Sistema de Gastos en Flex con AMFPHP y MySQL
En este tutorial veremos cómo acceder a los registros de una base de datos MySQL desde Flex utilizando AMFPHP. Realizaremos un pequeño Sistema de Gastos en el cual haremos inserciones a la base de datos, consultas, modificaciones y eliminación de registros. Si no sabes qué es y para qué sirve el AMFPHP, visita nuestro tutorial de Introducción a AMFPHP.
En esta ocasión no veremos a detalle todo el código que involucra el sistema; sin embargo, puedes encontrar al final de esta entrada los archivos fuentes.
El sistema funciona de la siguiente manera:
- El usuario primero da de alta tipo de monedas en la Sección de Divisas (Su nombre y símbolo).
- Posteriormente el usuario puede dar de alta servicios en la Sección de Servicios (valga la redundancia). Estos servicios son opcionales y pueden seleccionarse cuando un usuario introduce un gasto en el sistema. Ejemplo de servicios: teléfono, gas, luz, educación, restaurantes, entretenimiento, etc.
- Dentro del sistema, el usuario puede dar de alta gastos e ingresos. Estos gastos o ingresos requieren de la fecha, cantidad y divisa con la cual se realizó la operación. De manera opcional se puede introducir un concepto (descripción) y se puede seleccionar un servicio (si se trata de un gasto).
Comenzaremos con el script de nuestra base de datos:
-
# Host: localhost Database: codmetr_gastos
-
# ------------------------------------------------------
-
# Server version 4.1.22-community-nt
-
-
#
-
# Table structure for table tbldivisa
-
#
-
CREATE TABLE `tbldivisa` (
-
`INTNUMDIVISA` int(11) NOT NULL AUTO_INCREMENT,
-
`STRNOMBRE` varchar(30) NOT NULL DEFAULT '',
-
`STRSIMBOLO` varchar(5) character SET utf8 DEFAULT NULL,
-
PRIMARY KEY (`INTNUMDIVISA`)
-
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
-
-
#
-
# Table structure for table tbloperacion
-
#
-
CREATE TABLE `tbloperacion` (
-
`INTNUMOPERACION` int(11) NOT NULL AUTO_INCREMENT,
-
`DTMFECHA` date NOT NULL DEFAULT '0000-00-00',
-
`STRCONCEPTO` varchar(100) DEFAULT NULL,
-
`NUMCANTIDAD` decimal(10,2) DEFAULT NULL,
-
`INTNUMDIVISA` int(11) NOT NULL DEFAULT '0',
-
`INTNUMSERVICIO` int(11) DEFAULT NULL,
-
`INTOPERACION` int(11) NOT NULL DEFAULT '0',
-
PRIMARY KEY (`INTNUMOPERACION`)
-
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
-
-
#
-
# Table structure for table tblservicio
-
#
-
CREATE TABLE `tblservicio` (
-
`INTNUMSERVICIO` int(11) NOT NULL AUTO_INCREMENT,
-
`STRNOMBRE` varchar(50) DEFAULT NULL,
-
PRIMARY KEY (`INTNUMSERVICIO`)
-
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
Del código anterior podemos observar que tenemos una tabla tbldivisa, en la cual almacenamos los tipos de moneda que utilizamos. Una tabla tblservicio donde guardamos los servicios ingresados; y una tabla tbloperacion en donde almacenamos las operaciones (gastos e ingresos). Las relaciones entre divisas y servicios con respecto a las operaciones están dadas por el ID de estas tablas (INTNUMDIVISA e INTNUMSERVICIO).
Ahora veremos el código PHP de nuestra que funcionará como servicio:
-
<?php
-
class SistemaGastos
-
{
-
var $sqlstring = "";
-
var $server = "localhost";
-
var $user = "usuario_database";
-
var $pass = "contrasena_database";
-
var $database = "codigometr_gastos";
-
-
var $db = 0;
-
var $rs = 0;
-
var $row = 0;
-
var $recordcount = 0;
-
var $EOF = true;
-
-
function _conectarBaseDatos()
-
{
-
}
-
-
function _ejecutarQuery($strSql)
-
{
-
$this->sqlstring = $strSql;
-
$this->_exec_command();
-
return $this->lastid;
-
}
-
-
function _exec_command()
-
{
-
if ($this->db && $this->sqlstring!="")
-
{
-
if ($this->rs)
-
{
-
$this->EOF = true;
-
}
-
else
-
{
-
$this->recordcount = 0;
-
$this->EOF = true;
-
}
-
}
-
else
-
{
-
$this->recordcount = 0;
-
$this->EOF = true;
-
}
-
}
-
-
function _destruir()
-
{
-
if($this->db)
-
}
-
-
/* Métodos para la tabla tbldivisa */
-
function insertarDivisa($nombre, $simbolo)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Insert into `tbldivisa` (`STRNOMBRE`, `STRSIMBOLO`) VALUES ('" . $nombre . "', '" . $simbolo . "')";
-
$this->_ejecutarQuery($sql);
-
$this->_destruir();
-
}
-
-
function modificarDivisa($idDivisa, $nombre, $simbolo)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Update `tbldivisa` set `STRNOMBRE` = '" . $nombre . "', `STRSIMBOLO` = '" . $simbolo . "' where `INTNUMDIVISA` = " . $idDivisa;
-
$this->_ejecutarQuery($sql);
-
$this->_destruir();
-
}
-
-
function eliminarDivisa($idDivisa)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Delete from `tbldivisa` where `INTNUMDIVISA`= " . $idDivisa;
-
$sql = "Delete from `tbloperacion` where `INTNUMDIVISA`= " . $idDivisa;
-
$this->_destruir();
-
return $result;
-
}
-
-
function obtenerDivisas()
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Select INTNUMDIVISA, STRNOMBRE, STRSIMBOLO from tbldivisa ORDER BY STRNOMBRE asc";
-
-
{
-
$divisas[] = $row;
-
}
-
-
$this->_destruir();
-
-
return($divisas);
-
}
-
-
/* Métodos para la tabla tblservicio */
-
function insertarServicio($nombre)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Insert into `tblservicio` (`STRNOMBRE`) VALUES ('" . $nombre . "')";
-
$this->_ejecutarQuery($sql);
-
$this->_destruir();
-
}
-
-
function modificarServicio($idServicio, $nombre)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Update `tblservicio` set `STRNOMBRE` = '" . $nombre . "' where `INTNUMSERVICIO` = " . $idServicio;
-
$this->_ejecutarQuery($sql);
-
$this->_destruir();
-
}
-
-
function eliminarServicio($idServicio)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Delete from `tblservicio` where `INTNUMSERVICIO`= " . $idServicio;
-
$sql = "Delete from `tbloperacion` where `INTNUMSERVICIO`= " . $idServicio;
-
$this->_destruir();
-
return $result;
-
}
-
-
function obtenerServicios()
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Select INTNUMSERVICIO, STRNOMBRE from tblservicio ORDER BY STRNOMBRE asc";
-
-
{
-
$servicios[] = $row;
-
}
-
-
$this->_destruir();
-
-
return($servicios);
-
}
-
-
/* Métodos para la tabla tbloperacion */
-
function insertarOperacion($fecha, $concepto, $cantidad, $id_divisa, $servicio, $operacion)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "INSERT INTO `tbloperacion` (DTMFECHA, STRCONCEPTO, NUMCANTIDAD, INTNUMDIVISA, INTNUMSERVICIO, INTOPERACION) VALUES ('" . $fecha . "','" . $concepto . "'," . $cantidad . "," . $id_divisa . "," . $servicio . "," . $operacion . ")";
-
$result = $this->_ejecutarQuery($sql);
-
$this->_destruir();
-
-
return $result;
-
}
-
-
function actualizarOperacion($idOperacion, $fecha, $concepto, $cantidad, $id_divisa, $servicio, $operacion)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Update `tbloperacion` set `DTMFECHA` = '" . $fecha . "', `STRCONCEPTO` = '" . $concepto . "', `NUMCANTIDAD` = " . $cantidad . ", `INTNUMDIVISA` = " . $id_divisa . ", `INTNUMSERVICIO` = " . $servicio . ", `INTOPERACION` = " . $operacion . " where `INTNUMOPERACION` = " . $idOperacion;
-
$result = $this->_ejecutarQuery($sql);
-
$this->_destruir();
-
return $result;
-
}
-
-
function eliminarOperacion($idOperacion)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Delete from `tbloperacion` where `INTNUMOPERACION`= " . $idOperacion;
-
$this->_destruir();
-
return $result;
-
}
-
-
function obtenerOperaciones()
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Select * from `tbloperacion` ORDER BY DTMFECHA asc";
-
-
{
-
$operaciones[] = $row;
-
}
-
-
$this->_destruir();
-
-
return($operaciones);
-
}
-
-
function realizarConsulta($servicio, $divisa, $concepto, $fecha1, $fecha2, $cantidad1, $cantidad2, $operacion)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "Select top.DTMFECHA, top.STRCONCEPTO, top.NUMCANTIDAD, top.INTNUMDIVISA, top.INTNUMSERVICIO, top.INTOPERACION, td.STRNOMBRE, td.STRSIMBOLO FROM tbloperacion AS top, tbldivisa as td WHERE td.INTNUMDIVISA = top.INTNUMDIVISA";
-
-
/* Selección Concepto */
-
if($concepto != "")
-
$sql .= " AND top.STRCONCEPTO LIKE '%" . $concepto . "%'";
-
-
/* Selección Divisa */
-
if($divisa != 0) {
-
$sql .= " AND top.INTNUMDIVISA = " . $divisa . " AND td.INTNUMDIVISA = " . $divisa;
-
}
-
-
/* Selección Servicio */
-
if($servicio != 0) {
-
$sql .= " AND top.INTNUMSERVICIO = " . $servicio;
-
}
-
-
if($cantidad1 != "" && $cantidad2 != "")
-
{
-
if($cantidad1 <= $cantidad2)
-
$sql .= " AND top.NUMCANTIDAD BETWEEN " . $cantidad1 . " AND " . $cantidad2;
-
else
-
$sql .= " AND top.NUMCANTIDADBETWEEN " . $cantidad2 . " AND " . $cantidad1;
-
}
-
else if($cantidad1 != "")
-
$sql .= " AND top.NUMCANTIDAD = " . $cantidad1;
-
else if($cantidad2 != "")
-
$sql .= " AND top.NUMCANTIDAD = " . $cantidad2;
-
-
/* Selección Operación */
-
if($operacion == 3)
-
$sql .= " AND top.INTOPERACION>= 1 AND top.INTOPERACION <= 2";
-
else
-
$sql .= " AND top.INTOPERACION = " . $operacion;
-
-
if($fecha1 != NULL || $fecha2 != NULL)
-
{
-
if($fecha1 != "" && $fecha2 == "")
-
{
-
$sql .= " AND top.DTMFECHA = '" . $fecha1 . "'";
-
}
-
else
-
{
-
$sql .= " AND top.DTMFECHA>= '" . $fecha1 . "' AND top.DTMFECHA <= '" . $fecha2 . "'";
-
}
-
}
-
-
$sql .= " ORDER BY top.DTMFECHA asc, top.NUMCANTIDAD asc";
-
-
{
-
$registros[] = $row;
-
}
-
-
$this->_destruir();
-
-
return($registros);
-
}
-
}
-
?>
Los métodos que inician con guión bajo (_) son métodos privados y por lo tanto no podemos acceder a ellos desde Flex. Los otros métodos insertarDivisa, modificarDivisa, eliminarDivisa, obtenerDivisas, etc. son métodos públicos a los cuales accedemos desde Flex.
Observa cómo en los métodos obtenerXXX almacenamos los registros en un arreglo y lo regresamos a nuestra aplicación. Los queries en realidad son muy sencillos, por lo que no requieren explicación; solamente observa cómo en los métodos eliminarServicio y eliminarDivisa hacemos el borrado de los registros que involucran estos registros en la tabla tbloperacion. Esto es para evitar que haya inconsistencia en la base de datos.
Ahora veremos el código principal de nuestra aplicación en Flex.
Para poder hacer uso del AMFPHP necesitamos de las librerías NetConnection y Responder.
-
import flash.net.NetConnection;
-
import flash.net.Responder;
Para poder acceder a los servicios en AMFPHP debemos especificar la ruta en la cual se encuentra el archivo gateway.php de AMFPHP:
-
private var gateway:String = "http://www.codigometropoli.com/wp-content/uploads/2008/10/SistemaGastos/AMFPHP1.9/gateway.php";
-
private var connection:NetConnection;
-
private var responder:Responder;
Al iniciar la aplicación debemos llamar a la función connect pasándole como parámetro el gateway:
-
function iniciaAplicacion()
-
{
-
connection = new NetConnection;
-
connection.connect(gateway);
-
}
Dentro del constructor de la clase Responder debemos especificar las funciones que se ejecutarán en caso de que la llamada haya sido sido exitosa y en caso de que haya existido un error. Para hacer la llamada al servicio utilizamos la función call; a la cual pasamos como parámetro el nombre de la función que queremos llamar y que se encuentra en la clase SistemaGastos.php, nuestro objeto de la clase Responder y los parámetros que debemos pasarle a la función:
-
responder = new Responder(insertarOperacionResult, errorConsulta);
-
connection.call("SistemaGastos.insertarOperacion", responder, param1, param2, param3...);
Del código anterior podemos deducir que el nombre de nuestra clase en PHP es SistemaGastos y que tiene un método público llamado insertarOperacion.
En caso de que la llamada haya sido exitosa, se ejecutará el método insertarOperacionResult:
-
private function insertarOperacionResult(result:Object):void {
-
if(result.toString() != "0")
-
{
-
restablecerForma();
-
Alert.show("Registro almacenado", "Aviso");
-
}
-
else
-
Alert.show("No se pudo almacenar el registro", "Error");
-
}
En caso contrario, si existiera algún error en la llamada al servicio, la función errorConsulta se ejecutará:
-
private function errorConsulta(fault:Object):void {
-
Alert.show(fault.description, "Error");
-
CursorManager.removeBusyCursor();
-
}
Nuestra forma de alta de operación (Gasto o Ingreso) será la siguiente:

De la imagen anterior puedes saber qué tipo de información estamos solicitando, cuál es la obligatoria (Fecha, Cantidad y Divisa), así como la forma en qué estamos mostrando al usuario las divisas y servicios dados de alta (por medio de ComboBox).
Las partes de código mostradas forman parte de la llamada a una función que se encarga de insertar un registro. El código no tendrá variación cuando se trate de modificar un registro; y cuando se trate de eliminar un registro solamente le pasaremos el ID del registro a eliminar. ¿Pero qué pasa cuando se trata de una consulta? ¿Cómo obtenemos los registros registros regresados por la base de datos? ¿Cómo mostramos esos registros?
Si leíste el tutorial sobre Componente DataGrid y las cuatro entregas del tutorial Sistema de Clientes en AIR sabrás que podemos recorrer cada uno de los registros obtenidos de la base de datos y almacenarlos en un arreglo por medio del método push; posteriormente ese arreglo es pasado al DataGrid como su proveedor de datos (dataProvider).
Primero hacemos la llamada al método realizarConsulta del servicio SistemaGastos:
-
responder = new Responder(realizarConsultaResult, errorConsulta);
-
connection.call("SistemaGastos.realizarConsulta", responder, param1, param2, param3...);
Definimos el código de nuestra función realizarConsultaResult:
-
private function realizarConsultaResult(result:Array):void
-
{
-
if(result != null)
-
{
-
var totalRegistros:Number = result.length;
-
var totales_array:Array = new Array();
-
-
for (var i:int = 0; i <result.length; i++)
-
{
-
...
-
var divisa_txt:String = result[i].STRNOMBRE;
-
var simbolo_txt:String = result[i].STRSIMBOLO;
-
...
-
var cantidad:Number = result[i].NUMCANTIDAD;
-
-
if(totales_array.length == 0)
-
totales_array.push({cantidad:cantidad, divisaID:result[i].INTNUMDIVISA, divisa:divisa_txt, simbolo:result[i].STRSIMBOLO});
-
else
-
{
-
var posicion:Number = regresaPosicionMoneda(totales_array, result[i].INTNUMDIVISA);
-
if(posicion != -1)
-
{
-
var total:Number = totales_array[posicion].cantidad;
-
total += cantidad;
-
totales_array[posicion].cantidad = total;
-
}
-
else
-
totales_array.push({cantidad:cantidad, divisaID:result[i].INTNUMDIVISA, divisa:divisa_txt, simbolo:result[i].STRSIMBOLO});
-
}
-
data_provider.push({fecha_operacion:DateUtilities.returnReadableDate(result[i].DTMFECHA), concepto:result[i].STRCONCEPTO, cantidad:currencyFormatter.format(result[i].NUMCANTIDAD), cantidad_numero:result[i].NUMCANTIDAD, servicio:servicio_txt, divisa:divisa_txt, operacion:returnTipoOperacion(result[i].INTOPERACION)});
-
}
-
-
registros_dg.dataProvider = data_provider;
-
-
info_txt.text = "Total registros: " + totalRegistros + "\n";
-
for(var j:Number = 0; j <totales_array.length; j++)
-
{
-
var simbolo:String = totales_array[j].simbolo;
-
if(simbolo == "?")
-
simbolo = "€";
-
currencyFormatter.currencySymbol = simbolo;
-
info_txt.text += "\n --> " + totales_array[j].divisa + " = " + currencyFormatter.format(totales_array[j].cantidad);
-
}
-
}
-
else
-
info_txt.text = "";
-
-
CursorManager.removeBusyCursor();
-
}
Del código anterior podemos decir que... primero verificamos que el resultado obtenido por el servicio sea distinto de nulo (es decir, que no esté vacío) ya que si no nos mostraría error. En la variable totalRegistros almacenamos el número de registros obtenidos mediante la propiedad length del arreglo. Recorremos el arreglo result por medio de un ciclo for y dentro de este ciclo hacemos las operaciones que requerimos con los valores obtenidos. Observa que para acceder a cada una de las columnas de nuestros registros lo hacemos de la forma result[i].STRNOMBRE, result[i].STRSIMBOLO, result[i].INTNUMDIVISA, etc. donde STRNOMBRE, STRSIMBOLO, ... son los nombres de nuestras columnas en la tabla tbloperacion de nuestra base de datos. Dentro del código de nuestro ciclo for estamos sumando (ingreso) o restando (si se trata de gasto) las cantidades pertenecientes a un mismo tipo de moneda; y así mostrar la cantidad ganada o gastada por tipo de moneda.

Dentro del archivo SistemaGastos.php observarás que el código de la función realizarConsulta es largo y está lleno de condicionales. Esto es porque las consultas las podemos realizar de acuerdo a los siguientes criterios:
Hemos llegado al final de este tutorial, no olvidemos revisar el ejemplo y bajar los archivos fuentes.
Si te gustó esta entrada anímate a escribir un comentario o suscribirte al feed y obtener los artículos futuros en tu lector de feeds.
Comentarios
Hola José,
No es necesario pero sí es más que recomendable, sobre todo para evitar posibles errores en tiempo de ejecución.
Prometo en las próximas entregas no tener ningún Warning =0)
Saludos y gracias por tu comentario.
Tengo otra pregunta, he estado revisando los ejemplos, que repito, estan muy buenos. Y quiero saber como se puede mostrar el "id" del cliente (por ejemplo) o del gasto, ingresado en la misma pantalla, en un textInput. Me explico se ingresan los datos y al presionar el boton de hacer el ingreso pueda mostrar por lo menos la "id" ingresada para ese registro en un textInput aparte, pero de la misma pantalla.
Espero haber explicado bien y me puedas ayudar.
Gracias.
Hola JOse,
Espero haberte entendido bien.
Supongo que necesitas mostrar dentro de la misma pantalla el ID del registro que acabas de ingresar. Si es así, en la forma (AltaGasto.mxml) coloca un TextInput con ID de idGasto_txt. Después, en la función en donde mostramos el resultado de la ejecución del query (insertarOperacionResult) pon lo siguiente:
-
private function insertarOperacionResult(result:Object):void {
-
idGasto_txt.text = result.toString();
-
}
Por último, busca el método insertarOperacion en el archivo SistemaGastos.php y cambialo por:
-
function insertarOperacion($fecha, $concepto, $cantidad, $id_divisa, $servicio, $operacion)
-
{
-
$this->_conectarBaseDatos();
-
$sql = "INSERT INTO `tbloperacion` (DTMFECHA, STRCONCEPTO, NUMCANTIDAD, INTNUMDIVISA, INTNUMSERVICIO, INTOPERACION) VALUES ('" . $fecha . "','" . $concepto . "'," . $cantidad . "," . $id_divisa . "," . $servicio . "," . $operacion . ")";
-
$result = $this->_ejecutarQuery($sql);
-
$this->_destruir();
-
return $lastID;
-
}
Saludos.
Gracias por tu pronta respuesta, me has entendido bien, ahora vere como hacer esto mismo para para el ejemplo anterior de Sistema_Clientes que es distinto sin php, y el cual me interesa mas, agradeceria me pudieras ayudar tambien. Te agradezo mucho, gracias por tu tiempo.
Hola José,
Su implementación es similar.
Agrega un campo de texto con ID id_txt al archivo AltaCliente.mxml.
Dentro del archivo AltaCliente.as busca la función insertaCliente; después de la línea donde mostramos el alert de que los datos han sido almacenados, añade lo siguiente:
-
sql = "SELECT last_insert_rowid() as id";
-
queryStatement.clearParameters();
-
queryStatement.text = sql;
-
queryStatement.execute();
-
-
var result:SQLResult = queryStatement.getResult();
-
if(result.data != null) {
-
id_txt.text = result.data[0].id;
-
}
Saludos.
Hola Carla, primero que nada te felicito por este excelente ejemplo, Muchas Gracias...
Pero ya me confundí… me puedes ayudar a despejar estas dudas por favor ¿AMFPHP y BLAZE DS funcionan igual, me sirven para lo mismo? ¿FLASH REMOTING es lo mismo que HTTP SERVICES?
Hola Erasmo,
Gracias por tu comentario.
Son similares, la diferencia es que AMFPHP está desarrollado para "comunicarnos" con PHP, mientras que BlazeDS permite la integración con Java.
Los métodos que comienzan con guión bajo son privados y no se pueden acceder a ellos desde Flash o Flex y tampoco desde el browser de servicios que trae AMFPHP; pero estos métodos sí se pueden acceder dentro de la misma clase. Los métodos privados se utilizan principalmente cuando realizan operaciones importantes (por ejemplo: para conectarse a la base de datos, realizar borrado de registros, etc.)
No entiendo tu otra pregunta ¿con HTTP SERVICES te refieres a Web Services?
Saludos.
Muchas Gracias Carla, resolviste mi duda, si efectivamente me refiero a Web Services y Flash Remoting.
Hola Erasmo,
No creo que Flash Remoting sea lo mismo que Web Services; más bien es una solución que Macromedia (ahora Adobe) nos ofrece para facilitarnos la comunicación de aplicaciones desarrolladas en Java, ColdFusion, .NET, etc. por medio de documentos XML, permitiendo el parseo de éstos. Podríamos decir que facilita la comunicación de aplicaciones de Flash con los web services.
Saludos.
Hola Jaime,
Aquí va la explicación:
Generalmente el directorio del workspace de Flex se encuentra en la carpeta de "Mis Documentos" o "Documentos" y la carpeta se llama "Flex Builder 3".
Extrae los archivos del zip dentro de la carpeta Flex Builder 3. Corre el programa Flex Builder 3 y del lado izquierdo encontrarás el panel de "Flex Navigator". Haz click sobre alguna de las partes blancas de ese panel y selecciona la opción "Import...". Dentro de la opción General haz click en "Existing Projects into Workspace"; haz click en el botón de Next. Verifica que la opción "Select root directory" esté seleccionada y haz click en el botón Browse... Selecciona la carpeta raíz de nuestro proyecto (Sistema_Gastos) da click en el botón de Aceptar y posteriormente en el botón de Finish.
Después de lo anterior observarás que nuestro proyecto aparece dentro del panel izquierdo de "Flex Navigator", da click en el botón de + que está al lado del nombre del proyecto, busca el archivo Sistema_Gastos.mxml (dentro de la carpeta src) y haz doble click sobre él. Verás el código de ese archivo en el panel del lado derecho. Haz click en el botón verde que tiene una flecha blanca que está al lado del botón de imprimir y debajo del menú "Navigate" para ejecutar la aplicación.
No olvides bajar los archivos del AMFPHP y cambiarle la ruta en tu proyecto.
Saludos.
Hola Carla, nuevamente solicitando tu ayuda… Tengo un proyecto y me estoy decidiendo por desarrollarlo en estas fascinantes tecnologías Flex-PHPAMF-MySQL, por lo único que me estoy deteniendo es saber si es posible imprimir directamente en impresora de Tickets desde el cliente Flash o AIR; mas detallado... ¿hay manera de usar secuencias de escape por el puerto LPT1 que son las que utilizan las impresoras de Tickets para imprimir directamente? o me puedes ayudar con algunas alternativas para lograr este objetivo.
Saludos, muchas gracias.
Hola Erasmo,
Desconozco por completo este tema.
A lo mejor es posible utilizar PHP para la impresión, por medio de la ejecución del comando utilizando la función exec() o system().
Tampoco sé si puedas hacerlo utilizando un reporteador como Jasper4Flex o FlexReport.
Saludos y disculpa que no tenga más información.
Muchas Gracias Carla…
FlexReport es mi mejor opción, nada mas que no hay mucha documentación, ¿tendrás algún hilo para poder empezar o algunos ejemplos?
Muchas Gracias Carla por tus ejemplos, me han servido de mucho para aprender un poco más del mundo flex.
Tengo una duda, ¿este proyecto se puede pasar a Air?.
En el caso que se pudiera, ¿como se hace?.
desde ya muchas gracias!
Hola Hans,
Para usarlo con Air tendrías que hacerle pequeñas modificaciones, sobre todo al código de los queries (en este caso tendrías que usar SQLite). Revisa el tema de Sistema de Clientes en AIR.
Saludos.
Excelente Carla.
Una duda si se crea como air con sqlite.
Y mi server tiene el puerto de mysql cerrado al exterior.
Se puede sincronizar sqlite desde la apli air en el ordenador usuario, con mysql del server en internet de alguna forma a traves de la url publica de amfphp.
Gracias por existir y estar presente compartiendo tu tiempo.
Hola Juan,
Eso sí que no lo entedí.
¿Cómo es que tu server tiene el puerto cerrado al exterior? ¿Quieres utilizar AIR para después pasar los datos de sqlite a MySQL porque tienes cerrado el puerto o es por otra razón?
Disculpa pero en verdad no entendí la pregunta.
Saludos.
Hola Carla, excelente tutorial.
Tengo una pregunta para ti, he visto que se pueden enviar objetos atravez de remoteObject, sin embargo veo que tu solo utilizaste AS para comunicarte, es posible enviar objectos atravez del connection.call?
Saludos!!
Hola Luis,
Gracias por tu comentario.
Para enviar un objeto de Flash a PHP por medio de AMFPHP, puedes hacerlo de la siguiente forma:
-
var operacion:Object = new Object();
-
operacion.fecha = "2008-11-08";
-
operacion.concepto = "Pago de tenencia";
-
operacion.cantidad = 24500;
y recibirlo en tu clase de PHP como:
Saludos.
Hola recien estoy comenzando con esto y quiziera q me dieran una mano donde pongo el codigo del import lo estoy haciendo paso por paso no bajando el ya hecho donde pondrias el codigo netconnection y responder y en q parte del flex builder..
Gracias
Hola alfadoble10,
Al crear un nuevo proyecto en Flex te crea un archivo con extensión mxml, el cual tiene vista de Diseño y vista de Código (Source).
Al cambiarte a la vista Código, verás las etiquetas:
-
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
-
-
</mx:Application>
Dentro de ellas deberás escribir la etiqueta de Script, la cual te permite poner el código de ActionScript. Por lo tanto, el código quedaría de la siguiente forma:
-
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
-
<mx:Script>
-
<![CDATA[
-
import flash.net.NetConnection;
-
import flash.net.Responder;
-
-
private var gateway:String = "http://www.codigometropoli.com/wp-content/uploads/2008/10/SistemaGastos/AMFPHP1.9/gateway.php";
-
private var connection:NetConnection;
-
private var responder:Responder;
-
...
-
]]>
-
</mx:Script>
-
</mx:Application>
Saludos.
Muy buen ejemplo, soy estudiante y es excelente ejemplo para aprender, una consulta si esque quiero dejar una clase aparte para crear la coneccion con la BD e implementar los metodos de la clase anterior desde la clase SistemaGastos.php,para asi generar mas clases que usen los metodos de la clase db_con para conectarse a la bd, agradeceria si me ayudas que estoy un poco complicado
Muy Muy interesante todo....
Yo estoy comenzando a desarrollar una web para controlar transferencias de dinero online en php y mysql y bueno recien estoy viendo esto de FLEX, ya baje Eclipse+Flex..
Espero me ayude en mis dudas q creo que seran muchas desde el form Login q empesare...
Saludos desde Cusco Peru..
Hola Carla.
Muchas gracias por tu ejemplo, me sirvió mucho para aprender la sincronizacion de flex.
Retomando el comentario que te hizo Juan el 14 de Enero.
Conoces como sincronizar los datos en air, procedentes de una base de datos MySQL o SQLite, para que sean guardados en la base de datos que cree en Air? y puedan ser consultados de manera offline ?
Espero haberme explicado y te agradezco de antemano toda tu ayuda.
Gracias. ![]()
Hola Alonso,
Perdona la tardanza.
Desconozco cómo se pueda realizar lo que estás buescando; incluso no sé si sea factible ya que con Flex puedes acceder de forma remota a una base de datos mientras que con AIR lo haces de forma local. Lamento desconocer del tema y no poder ayudarte.
Saludos.
Escribe un comentario
Nota: Es posible que tu comentario requiera autorización, si es así tu comentario será publicado a la brevedad. Gracias.






Otra exelente entrega.
Una consulta... al importar el proyecto, aparecen varios warnings de variables y funciones que no tienen ninguna declaracion de tipo. No es necesario agregar un tipo "void" por ejemplo u otro, o no es necesario?
De todas maneras muy buen ejemplo.