Invocar funciones PHP desde Flex con AMFPHP

Adobe Flex es un framework de desarrollo que nos permite crear rápida y facilmente aplicaciones RIA (Aplicaciones de Internet Enriquecidas), basado en la plataforma Flash combinando el lenguaje de marcas MXML y ActionScript. También, gracias a su entorno de desarrollo se simplifica el desarrollo de aplicaciones AIR.

En esta oportunidad quiero explicar cómo hacer uso de Flex para invocar funciones hechas en PHP (no entraré en detalles, pues no conozco a fondo ActionScript). Una forma de hacerlo es mediante AMFPHP. Pero ¿qué es AMFPHP? Es un RPC (Llamada a Procedimientos Remotos) que nos permite comunicar datos de aplicaciones-funciones entre el cliente (JavaScript, Flash, Flex, etc) y servidor (PHP, ASP, JSP, etc). En este caso AMFPHP realiza la comunicación de procesos remotos entre Flash (y por extensión aplicaciones RIA en Flex y AIR) y PHP.

Vamos por paso para la implementación de un proyecto en Flex que llame a funciones en PHP.

  1. Descargar y extrae la carpeta amfphp que contiene la siguiente estructura (y para no perderse en el tutorial, colocala en la raíz de tu sitio web de tal forma que quede así: http://localhost/amfphp)
+ ampphp 
 +services
 +core
 +browser
 -gateway.php
 -globals.php
 -.htaccess
 -json.php
 -xmlrpc.php
 -phpinfo.php
  1. Verificar el funcionamiento del amfphp. Para ello abres tu navegador y escribes http://localhost/amfphp/browser. Aparecera una ventana de configuración donde se muestra la ubicación del archivo gateway que actuará como puerta de enlace. En esta ventana solo dale clic en Save.

Podrás apreciar un especie de explorador. En la vista árbol a tu izquierda se mostrarán todas las clases en PHP que podemos usar. Para que una clase aparezca allí debes guardarla en el directorio services.

  1. Vamos crear una clase en PHP. Vamos a lista una relación de clientes de una base de datos MySQL. La estructura de la tabla es la siguiente (ingresa un par de registros luego):
CREATE TABLE IF NOT EXISTS `cliente` (
 `id` tinyint(7) NOT NULL auto_increment,
 `nombres` varchar(50) NOT NULL,
 `ciudad` varchar(50) NOT NULL,
 `sexo` char(1) NOT NULL,
 `telefono` varchar(10) NOT NULL,
 `fecha_nacimiento` datetime NOT NULL,
 KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

En archivo PHP debe tener el mismo nombre que la clase, en este caso se llama sample.php:

<?php
class sample{
 function getUsers () {
 $mysql = mysql_connect(localhost, "root", "");
 
 mysql_select_db( "empresa" );
 
 $Query = "SELECT * from cliente";
 $Result = mysql_query( $Query );
 while ($row = mysql_fetch_object($Result)) {
 $return[] = $row;
 }
 return( $return );
 }
}
?>

Volvamos a http://localhost/amfphp/browser y podemos apreciar en la lista de servicios, a la mano izquierda, nuestra clase llamada sample. Si la seleccionamos se muestran sus métodos, en este caso getUsers, y pulsamos el botón call se mostrará el resultado en la parte inferior.

amfphp browser

  1. Abrimos Flex (en mi caso Flex Builder 3) y creamos un nuevo proyecto Flex de nombre sample.

new project

new project

Configuramos la ruta en nuestro servidor local:

new project

new project

El archivo autogenerado sample.mxml lo dejamos allí por un momento. Ahora vamos agregar un archivo de ActionScript a nuestro proyecto, para ello le damos clic derecho en la carpeta src y seleccionamos New > ActionScript File.

new project

new project

El archivo RemotingConnection.as contiene un clase que llama a una conexión remota especificando la url de ésta.

package {
 import flash.net.NetConnection;
 import flash.net.ObjectEncoding;
 
 public class RemotingConnection extends NetConnection
 {
 public function RemotingConnection( sURL:String )
 {
 objectEncoding = ObjectEncoding.AMF0;
 if (sURL) connect( sURL );
 }
 
 public function AppendToGatewayUrl( s : String ) : void
 {
 //
 }
 }
}

Ahora el archivo autogenerado sample.mxml, lo reemplazamos por el siguiente contenido:

<?xml version="1.0" encoding="utf-8"?>
 
 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns="*" creationComplete="initApplication()">
 
 <mx:DataGrid dataProvider="{dataProvider}">
 <mx:columns>
 <mx:DataGridColumn headerText="ID" dataField="id"/>
 <mx:DataGridColumn headerText="Nombres" dataField="nombres"/>
 <mx:DataGridColumn headerText="Ciudad" dataField="ciudad"/>
 <mx:DataGridColumn headerText="Telefono" dataField="telefono"/>
 <mx:DataGridColumn headerText="Sexo" dataField="sexo"/>
 <mx:DataGridColumn headerText="Fecha Nacim
iento" dataField="fecha_nacimiento"/>
 </mx:columns>
 </mx:DataGrid>
 
 <mx:Script>
 <![CDATA[
 [Bindable]
 public var dataProvider:Array;
 public var gateway : RemotingConnection;
 
 public function initApplication()
 {
 gateway = new RemotingConnection( "http://localhost/amfphp/gateway.php" );
 gateway.call( "sample.getUsers", new Responder(onResult, onFault));
 }
 
 public function onResult( result : Array ) : void
 {
 dataProvider = result;
 }
 
 
 public function onFault( fault : String ) : void
 {
 trace( fault );
 }
 ]]>
 </mx:Script>
 
</mx:Application>

Hemos creado un DataGrid para mostrar los datos de la consulta al servidor MySQL. Dentro de las etiquetas <mx:Script/> hacemos uso de ActionScript para llamar a la clase RemotingConnection que creamos anteriormente. La función initApplication() se encarga de conectar con la puerta de enlace: gateway.php, y llama al método getUsers() de la clase sample. La respuesta la recibe la función onResult() que pasa los datos a la variable dataProvider y ésta pasa al DataGrid.

  1. Ahora simplemente compilamos el proyecto (Ctrl + F11) y podemos apreciar el resultado en el navegador web.

new project

De esta forma podemos crear aplicaciones web complejas que incluyan inserción y actualización de datos. Pero eso no esto, incluso podemos crear aplicaciones de escritorio gracias a AIR con esta funcionalidad, es decir llamadas a procesos remotos. Les dejo los archivos de este tutorial para que lo prueben en su servidor local.

Fuente de inspiración: Flex and PHP Using AMFPHP

22 thoughts on “Invocar funciones PHP desde Flex con AMFPHP

  1. Chabon, no me caso de decirlo, UN GROXO!
    Siempre apareces con lo que toy buscando en el momento 😉
    Saludos

  2. Hola, excelente tutorial, mira ahora tengo el siguiente problema resulto casi todo a excepcion que la grilla no me devolvio los datos y en browser si se reflejaron ¿Falta algo?

  3. a mi tambien me ocurrio lo mismo, al parecer es un problema del gateway de amfphp, hice otros tutoriales y me pasa lo mismo, no me muestra los datos extraidos desde flex, pero en el browser si, alguna solucion.
    Saludos.

  4. @todos:
    Le muestra alguna advertencia el Flex?? Verifiquen eso.
    Ademas (disculpen si caigo pesado) pueden verificar a petición con Firebug. Me pasan la voz. 🙂

  5. Como esto me ayude a hacer lo que estoy intentando, mira….te hago un hijo si hace falta!!!
    ajajaj Muchas gracias!!!

  6. Alguien sabe como hacer para que el metodo onResult tome el parametro result como un array collection, para que en el servicio php solo haga return mysql_query(“querry”) y asi meterlo directo al datagrid?

  7. Hola, muy buen ejemplo, y corre todo a la perfección, me carga los datos muy bien, pero ahora quiero verlo desde otra pc en la misma lan, pongo la ip de mi máquina servidor y la ruta de donde esta la aplicación, y si la abre muy bien pero no muestra los datos…alguien podría ayudarme para resolver esto????

  8. En initApplication(), tengo dos invocaciones a funciones php. algo como;
    gateway.call(‘productos.leer’,new responder(onProductos,onerror));
    gateway.call(‘descripciones.leer’,new responder(onDescripciones,onerror));
    los dos traerian dos vectores de objetos de una base, pero cuando la aplicacion se carga, solo asigna a productos con los datos de productos y a descripciones con los datos de productos.
    ¿cómo se podria arreglar eso?
    una es para llenar un combobox y otra para llenar una grilla.
    gracias
    fernando

  9. Excelente tutorial, yo no sabia nada y estoy creando mi primera pagina en FLEX, muchas gracias

  10. “””””
    Ya lo encontré, el error es en la linea:
    gateway.call( “sample.getUsers”, new Responder(onResult, onFault));
    debe ser “amfphp.sample.getUser”
    “”””””””
    muy bien gracias

  11. Muy buen tutorial, he visto otros en los que se necesita el famoso services.xml este es de los pocos que no lo tienen, por el momento sabes como puedo llamar a una funcion con parametros
    gracias.

  12. Segui los pasos y cuando me aparecio la ventana de configuracion de amfphp le di en save tal cual como dice en el blog y me aparecio este error
    (mx.rpc::Fault)#0
    errorID = 0
    faultCode = “Client.Error.MessageSend”
    faultDetail = “Channel.Connect.Failed error NetConnection.Call.BadVersion: ”
    faultString = “Send failed”
    message = “faultCode:Client.Error.MessageSend faultString:’Send failed’ faultDetail:’Channel.Connect.Failed error NetConnection.Call.BadVersion: ‘”
    name = “Error”
    rootCause = (Object)#1
    code = “NetConnection.Call.BadVersion”
    description = “”
    details = “”
    level = “error”
    Como podre solucionarlo??
    Saludos

  13. Excelentisimo ejemplo: me estuve apoyando en el libro Flex 3 Bible durante una semana y nada, hasta que cai aqui. ¿Ejemplos de insercion y borrado?

  14. pues yo segui todo al pie de la letra de este ejemplo
    y simplemente me muestra el datawrid nose en que
    este fallando

  15. hola amigos, exelente ejemplo segui paso a paso el tuto y si me funcionó, solo tuve un error, pero solo le modifique al archivo sampl.mxml y funcionó perfectamente
    gateway = new RemotingConnection( “http://localhost/la versión de mi amfphp la cual fué amfphp 1.9/gateway.php” );
    o simplemente borrarle el 1.9 a la carpeta jejej
    saludos y muchas gracias!

  16. Hola buen tutorial, pero lo tendras para flex builder 4 o trabaja igual ??? o que cambios se deben realizar ??? de antemano gracias por tus atenciones…
    saludos

Leave a Reply

Your email address will not be published. Required fields are marked *

Proudly powered by WordPress | Theme: Wanderz Blog by Crimson Themes.