Introducción a AMFPHP

FlashAMFPHP es una implementación en PHP, gratuita y de código abierto del AMF (Action Message Format), el cual es un formato binario basado en SOAP. AMF permite la serialización binaria de objetos y tipos nativos de ActionScript 2 y ActionScript 3 para ser enviados a servicios del lado del servidor. AMFPHP permite que aplicaciones realizadas en Flash, Flex y AIR puedan comunicarse directamente con objetos de clases de PHP.

Prácticamente, la forma en la que funciona se resume en que podemos crear clases en PHP, acceder a los métodos de esas clases por medio de Flash, Flex o AIR y obtener los datos retornados por esos métodos. Por ejemplo, podemos crear una clase para conectarnos a una base de datos en MySQL. Esta clase podría contener un método para insertar datos a la base, otro método para generar consultas y obtener en nuestra aplicación de Flash, Flex o AIR los registros regresados por la consulta.

En esta entrada veremos cómo está formado el AMFPHP y cómo acceder a él desde Flash CS3. Para una mejor explicación de cómo acceder a AMFPHP haremos una sencilla clase en PHP la cual no accederá a ninguna base de datos (eso lo dejaremos para nuestro próximo tutorial).

Tutorial

1. Baja el archivo amfphp-1.9.beta.20080120.zip de aquí. El amfphp-1.9 lo podemos usar con ActionScript 3 (Flash CS3, Flex y AIR), mientras que la versión anterior puede ser usada con ActionScript 2.

2. Descomprímelo y ponlo en algún directorio de tu servidor Web, en tu directorio htdocs o www en tu localhost. Si lo deseas, puedes renombrar la carpeta y ponerle AMFPHP1.9.

La estructura del directorio quedaría de la siguiente manera (en mi caso, la carpeta AMFPHP1.9 la puse en la carpeta raíz de mi servidor):

--> root ó carpeta raíz
-->AMFPHP1.9 (D)
--> browser (D)
--> core (D)
--> services (D)
--> gateway.php
--> globals.php
--> json.php
--> phpinfo
--> xmlrpc

Donde (D) indica que se trata de un directorio. Observa la carpeta browser, si accediéramos a él desde el navegador observaremos una aplicación creada en Flex donde nos muestra la lista de servicios que tenemos en AMFPHP, como se muestra en la siguiente liga. Si es la primera vez que accedes al browser, aparecerá la siguiente ventana de configuración:

Imagen 1: Ventana de Configuración de AMFPHP

En esta ventana de configuración deberás asegurarte que la dirección del Gateway es correcta. Después de hacer click en el botón Save te aparecerá la lista de servicios. Por default y cuando todavía no hemos creado ningún servicio nuevo, solamente aparecerá el servicio DiscoveryService. Importante: Cuando tenemos servicios que deben acceder a una base de datos o tratan información importante o crítica, lo mejor será no poner el directorio browser en el servidor. Continuando con nuestra estructura de directorios, como podrás imaginar, todos nuestros servicios (clases en PHP) deberán ir en el directorio services.

3. Vamos a crear una sencilla clase de PHP, la cual simulará las operaciones básicas de una calculadora. Sus métodos serán sumar, restar, multiplicar y dividir. Cada método recibirá como parámetro los dos números sobre los cuales hay que hacer la operación. Nota: Este tutorial es solamente para explicar cómo funciona AMFPHP y cómo podemos acceder a él desde Flash. Es por eso que nuestra clase de ejemplo es muy sencilla y muchos de ustedes dirán que no se requiere de PHP para sumar, restar, multiplicar y dividir dos números =0).
En PHP, al igual que en Flash, el nombre del archivo de una clase deberá tener el mismo nombre de la clase; por lo tanto, crea un nuevo archivo PHP, nómbralo Calculadora.php y guárdalo dentro del directorio services de nuestra carpeta AMFPHP19. Coloca el siguiente código dentro de Calculadora.php:

PHP:
  1. <?php
  2.  
  3. class Calculadora
  4. {
  5.     /**
  6.      * Suma dos números pasados por parámetro
  7.      * @returns Regresa un valor numérico
  8.      */ 
  9.     function sumar($numeroA, $numeroB)
  10.     {
  11.         return ($numeroA + $numeroB);   
  12.     }   
  13.    
  14.     /**
  15.      * Resta dos números pasados por parámetro
  16.      * @returns Regresa un valor numérico
  17.      */
  18.     function restar($numeroA, $numeroB)
  19.     {
  20.         return ($numeroA - $numeroB);
  21.     }
  22.    
  23.     /**
  24.      * Multiplica dos números pasados por parámetro
  25.      * @returns Regresa un valor numérico
  26.      */
  27.     function multiplicar($numeroA, $numeroB)
  28.     {
  29.         return ($numeroA * $numeroB);
  30.     }
  31.    
  32.     /**
  33.      * Divide dos números pasados por parámetro
  34.      * @returns Regresa un valor numérico
  35.      */
  36.     function dividir($numeroA, $numeroB)
  37.     {
  38.         return ($numeroA / $numeroB);
  39.     }
  40. }
  41.  
  42. ?>

Observa los comentarios antes de cada función; estos comentarios nos dan una descripción de qué es lo que hace cada método y además le estamos indicando qué es lo que nos regresa cada método (@returns). Si bien estos comentarios no son obligatorios, nos ayudarán a recordar en el momento en que queramos modificar el archivo. Además, dentro de la lista de servicios en el browser, cuando seleccionamos alguno de estos métodos se nos mostrará esta descripción (Como prueba, ingresa al navegador, de la lista de la izquierda selecciona la clase Calculadora y posteriormente selecciona de la ventana de la derecha el método dividir. Observarás que antes de los campos de texto para ingresar los números aparece la descripción del método). Ahora ingresa un número dentro del campo de texto $numeroA e ingresa otro número dentro del campo $numeroB, haz click en el botón Call y observa cómo en el área de resultados (Results) se muestra el resultado regresado por el método dividir de nuestra clase Calculadora en PHP.

4. Dentro de nuestra clase podemos utilizar métodos privados, los cuales no podrán ser utilizados desde el navegador de servicios (browser) ni desde nuestras aplicaciones en Flash, Flex o AIR. Esto es útil cuando dichos métodos realizan operaciones importantes o críticas y que requieran de mayor seguridad. Para establecer que un método es privado, bastará con agregarle un guión bajo (_) antes del nombre. Para hacer la prueba, agrega el siguiente código a la clase Calculadora.php (Insértalo antes de la última llave (}) y del tag de cierre de PHP (?>):

PHP:
  1. /**
  2.      * Este método es privado y no aparecerá en el browser de servicios
  3.      * @returns Regresa la fecha y tiempo del servidor
  4.      */
  5.     function _esteMetodoEsPrivado() {
  6.         $fecha_hoy = date("d/m/Y") . ' ' . date("H:i:s");
  7.         return $fecha_hoy;
  8.     }

Observa cómo en el código anterior el nombre de la función empieza con guión bajo _, eso quiere decir que se trata de un método privado. El código de este método privado lo que hace es regresarnos la fecha y el tiempo del servidor (por medio del método date).

Desde nuestra clase de PHP podemos acceder a ese método privado por medio de otro método. Para acceder a este método es necesario utilizar la palabra clave $this. A continuación te muestro cómo:

PHP:
  1. /**
  2.      * Este método es público y está accediendo a nuestro método privado
  3.      * @returns Regresa la fecha y tiempo del servidor
  4.      */
  5.     function obtenFechaServidor() {
  6.         $fecha_hoy = $this->_esteMetodoEsPrivado();
  7.         return $fecha_hoy;
  8.     }

El método obtenFechaServidor hace un llamado a la función esteMetodoEsPrivado y almacena en la variable $fecha_hoy el valor regresado por el método privado. Este valor es regresado por el método obtenFechaServidor.

Ingresa a nuestro navegador de servicios, selecciona la clase Calculadora y observa cómo el método esteMetodoEsPrivado no aparece dentro de los métodos de esta clase. Ahora haz click en el botón obtenFechaServidor y posteriormente en el botón Call. En el área de resultados (Results) se mostrará la fecha y hora del servidor.

Antes de pasar a la interfaz y al código ActionScript, te dejo el código completo del archivo Calculadora.php

PHP:
  1. <?php
  2.  
  3. class Calculadora
  4. {
  5.     /**
  6.      * Suma dos números pasados por parámetro
  7.      * @returns Regresa un valor numérico
  8.      */ 
  9.     function sumar($numeroA, $numeroB)
  10.     {
  11.         return ($numeroA + $numeroB);   
  12.     }   
  13.    
  14.     /**
  15.      * Resta dos números pasados por parámetro
  16.      * @returns Regresa un valor numérico
  17.      */
  18.     function restar($numeroA, $numeroB)
  19.     {
  20.         return ($numeroA - $numeroB);
  21.     }
  22.    
  23.     /**
  24.      * Multiplica dos números pasados por parámetro
  25.      * @returns Regresa un valor numérico
  26.      */
  27.     function multiplicar($numeroA, $numeroB)
  28.     {
  29.         return ($numeroA * $numeroB);
  30.     }
  31.    
  32.     /**
  33.      * Divide dos números pasados por parámetro
  34.      * @returns Regresa un valor numérico
  35.      */
  36.     function dividir($numeroA, $numeroB)
  37.     {
  38.         return ($numeroA / $numeroB);
  39.     }
  40.    
  41.     /**
  42.      * Este método es privado y no aparecerá en el browser de servicios
  43.      * @returns Regresa la fecha y tiempo del servidor
  44.      */
  45.     function _esteMetodoEsPrivado() {
  46.         $fecha_hoy = date("d/m/Y") . ' ' . date("H:i:s");
  47.         return $fecha_hoy;
  48.     }
  49.    
  50.     /**
  51.      * Este método es público y está accediendo a nuestro método privado
  52.      * @returns Regresa la fecha y tiempo del servidor
  53.      */
  54.     function obtenFechaServidor() {
  55.         $fecha_hoy = $this->_esteMetodoEsPrivado();
  56.         return $fecha_hoy;
  57.     }
  58. }
  59.  
  60. ?>

5. Crea un nuevo documento de Flash en Flash CS3 ActionScript 3.0. Cambia las dimensiones del área de trabajo por 300px de ancho y 190px de alto. Renombra la única capa que existe y ponle de nombre Forma. Agrega 3 textos, 3 TextInput(s) y 4 botones de tal forma que tu forma quede similar a la de la imagen:

Imagen 2: Forma de nuestra aplicación

El nombre de instancia de cada uno de los TextInput(s) es (de arriba a abajo):

El nombre de instancia de cada uno de los botones es (de arriba a abajo):

6. Agrega otra capa y ponle de nombre Acciones. Agrega el siguiente código a dicha capa:

Actionscript:
  1. /* Las siguientes librerías son necesarias para hacer las llamadas y conexión a AMFPHP */
  2. import flash.net.NetConnection;
  3. import flash.net.Responder;
  4.  
  5. /* Dentro de la variable gateway especificamos la URL completa de donde se encuentra nuestro archivo gateway.php. Si estás trabajando en local, es posible que tu URL sea similar a  http://localhost/AMFPHP1.9/gateway.php */
  6. var gateway:String = "http://localhost/AMFPHP1.9/gateway.php";
  7. /* Creamos una variable de tipo NetConnection para poder establecer la conexión. Este objeto funcionará como enlace entre el cliente y el servidor */
  8. var conexion:NetConnection = new NetConnection;
  9. /* Establecemos una conexión bidireccional entre el Flash Player y el servidor */
  10. conexion.connect(gateway);
  11. /* Este objeto de clase Responder se encargará de administrar los valores que son regresados por el servidor, ya sea si la operación fue todo un éxito o si hubo un error */
  12. var responder:Responder;
  13. /* Deshabilitamos el campo de texto donde se mostrará el resultado para que sea sólo de lectura */
  14. resultado_txt.enabled = false;

Revisa con atención el código anterior y los comentarios que están insertados en él. Hasta ahora solamente hemos importado las librerías que necesitamos, hemos declarado e instanciado las variables que usaremos a lo largo del programa.

Coloca el siguiente código debajo del anterior. Aquí estamos declarando cuatro métodos que serán llamados dependiendo de si el usuario hizo click en el botón de mas, menos, por o entre. Observa bien que el código de cada uno de estos métodos sólo cambia en la llamada de los métodos de la clase (la última línea de cada método, antes de }), es por eso que sólo comentaré la primera función (suma).

Actionscript:
  1. function suma(evento:MouseEvent) :void {
  2.     /* Obtenemos el valor ingresado en cada uno de los campos de texto  */
  3.     var numeroA:Number = Number(numeroA_txt.text);
  4.     var numeroB:Number = Number(numeroB_txt.text);
  5.    
  6.     /* Le especificamos a la variable responder qué métodos debe llamar en caso de éxito (método respuesta) o en caso de error (método error)  */
  7.     responder = new Responder(respuesta, error);           
  8.    
  9.     /* Invocamos, por medio del método call, al método sumar que se encuentra en la clase Calculadora (Calculadora.sumar). El segundo parámetro del método call es nuestro objeto de la clase Responder (el que se encargará de gestionar los valores obtenidos de dicha llamada. Por último, le pasamos como cuarto y quinto parámetro los dos números que deberá recibir la función sumar. */
  10.     conexion.call("Calculadora.sumar", responder, numeroA, numeroB);
  11. }
  12.  
  13. function resta(evento:MouseEvent) :void {
  14.     var numeroA:Number = Number(numeroA_txt.text);
  15.     var numeroB:Number = Number(numeroB_txt.text);
  16.    
  17.     operacion_mc.gotoAndStop("menos");
  18.     responder = new Responder(respuesta, error);           
  19.    
  20.     conexion.call("Calculadora.restar", responder, numeroA, numeroB);
  21. }
  22.  
  23. function multiplicacion(evento:MouseEvent) :void {
  24.     var numeroA:Number = Number(numeroA_txt.text);
  25.     var numeroB:Number = Number(numeroB_txt.text);
  26.    
  27.     operacion_mc.gotoAndStop("por");
  28.     responder = new Responder(respuesta, error);           
  29.    
  30.     conexion.call("Calculadora.multiplicar", responder, numeroA, numeroB);
  31. }
  32.  
  33. function division(evento:MouseEvent) :void {
  34.     var numeroA:Number = Number(numeroA_txt.text);
  35.     var numeroB:Number = Number(numeroB_txt.text);
  36.    
  37.     operacion_mc.gotoAndStop("entre");
  38.     responder = new Responder(respuesta, error);           
  39.    
  40.     conexion.call("Calculadora.dividir", responder, numeroA, numeroB);
  41. }

Después del código anterior solamente nos faltan los métodos respuesta y error, además de las acciones de cada uno de nuestros botones:

Actionscript:
  1. /* En caso de éxito tras ejecutar el método call, esta función es llamada pasándole como parámetro un objeto con el resultado regresado. Este resultado lo mostraremos dentro del TextInput resultado_txt. */
  2. function respuesta(resultado:Object):void {
  3.     resultado_txt.text = String(resultado);
  4. }
  5.  
  6. /* En caso de error tras ejecutar el método call, esta función es llamada pasándole como parámetro un objeto con el error generado. Este error lo desplegaremos dentro de un trace. */
  7. function error(error:Object):void {
  8.     trace("Error: " + error.description);
  9. }
  10.  
  11. /* Establecemos las acciones de nuestros botones */
  12. mas_btn.addEventListener(MouseEvent.CLICK, suma);
  13. menos_btn.addEventListener(MouseEvent.CLICK, resta);
  14. por_btn.addEventListener(MouseEvent.CLICK, multiplicacion);
  15. entre_btn.addEventListener(MouseEvent.CLICK, division);

A continuación puedes ver el SWF funcionando. A este archivo le añadí un campo de texto dinámico en el lado inferior derecho en el cual muestro el resultado de hacer una llamada al método obtenFechaServidor de nuestra clase Calculadora. No olvides bajar los archivos de este tutorial que se encuentran al final de esta entrada.


Este archivo requiere Flash Player 8
Descargar Archivo

Enlaces recomendados:

» Sitio del AMFPHP
» ActionScript 3.0 Language and Components Reference (Clase NetConnection)

Tags: , ,

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

Carla.

Me ha encantado tu pequeño tutorial. Para gente que se inicia en el AMFPHP (como yo) este ejemplo que has creado resulta por demás intuitivo. En mi caso, yo monté un servidor en mi PC (el AppServ, que incluye el Apache, PHP 5 y MySql) y funcionó a la perfección. Te agradezco el tiempo que invertiste para preparar este manual.

Saludos afectuosos desde Monterrey, México!

Hola Salvador,

Muchas gracias por tu comentario.
El próximo tutorial va a ser más completo ya que vamos a utilizar Flex, AMFPHP y MySQL para almacenar registros en la base de datos. Espero publicarlo en un par de días si el trabajo me lo permite =0(

Saludos desde el Distrito Federal =0)

[...] 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. [...]

Te felicito por este tutorial, muestra realmente el panorama AMF con PHP, me esta sirviendo mucho como novato en este trayecto como programador. Continúa con este entusiasmo.

Saludos desde Morelos.

Hola Erasmo,

Muchas gracias por tu comentario y qué gusto que te sea de utilidad.
Saludos congelados desde el Distrito Federal.

Excelente tutorial y en español. Felicitaciones y por favor, quiero estar al tanto de nuevos aportes.

Gracias desde Colombia

Buenos Días, Ingeniera. Hasta cuando la siguiente clase?
una sugerencia, podría escribir sobre modulos y titlewindows.
Un servidor le agradece todos estos cursos de
Air-Flex-PHP-MySQL,me han servido de guia, no hay otra en la web, muchas gracias.

PD.
NetConnection Ufff, OK!

Estimado Francisco,

Lamentablemende, debido a la cantidad de trabajo que tengo, me ha sido imposible actualizar el blog. Sin embargo, éste no está abandonado y no es por flojera su poca ctualización, eso se nota en la respuesta a sus dudas y comentarios =0).
Espero que por lo menos en este mes pueda poner dos tutoriales más. Tendré en cuenta su sugerencia sobre módulos y titlewindows; sin embargo, ya tengo varios ejemplos/ejercicios realizados (siempre hago primero los ejemplos y después desarrollo el tutorial) de los cuales me falta la explicación en el tutorial; pero no descarte la posibilidad de un tutorial sobre su tema propuesto.

Espero que esté bien y le agradezco su comentario.

Saludos.

Estan buenisimos estos tutoriales. ¿Qué tan nuevas son las interfases para conectarse con el servidor? Muchas gracias por la ayuda.

Hola Fernando,

Te agradezco mucho tu mensaje.
No entendí tu pregunta de las interfases para conectarse con el servidor ¿Me podrías explicar más sobre tu duda?

Saludos.

Felicitaciones para nosotros los programadores novatos en as y amfphp los cuales tenemos ahora un panorama ma amplio de lo que se puede, y como se debe hacer, muchas gracias ingeniera carla, ojala pueda publicar mas sobre amfphp, tengo una duda, para hacer las inserciones a la base datos tiene que ser ocn flex o puede ser de flash con as, y no se si pueda colgar un tutorial asi como el de flex pero para flash pues me interesa hacer mis consultas a la bd de mysql pero en flash.

O que libro me sugiere que pueda leer al respecto

Atte.

Jerry Otero

Muchas Gracias

Como sale la imagen que tengo en mi escritorio en el display??????? usa algun codigo para coger la imagen de mi equipó????? si es asi me gustaria saber como.... Seria algo genial jejej.... as lo puede todo

Hola Jerry, gracias por tu comentario.

"Tengo una duda, para hacer las inserciones a la base datos tiene que ser ocn flex o puede ser de flash con as..."
Puede ser con Flash, de hecho este ejemplo está hecho en Flash. Para hacer las inserciones es lo mismo, lo único que tendrías que cambiar es el código de la clase de PHP para guardar los datos pasados como parámetros en tu base de datos (Para darte una idea de cómo debe ser el código en PHP visita este tutorial http://www.codigometropoli.com/sistema-de-gastos-en-flex-con-amfphp-y-mysql/)

"Como sale la imagen que tengo en mi escritorio en el display??????? usa algun codigo para coger la imagen de mi equipó?????"
¿Te refieres a la imagen de la chava que aparece al lado de tu comentario? Esta imagen es la que seguramente subiste al registrarte en gravatar.

Saludos.

Hola me sale el siguiente error !! ayuda

Error #2044: NetStatusEvent no controlado: level=error, code=NetConnection.Call.Failed
at ehemplo_fla::MainTimeline/ehemplo_fla::frame1()

error mio... ya solucionado !

Holas
Soy nuevo en el mundo de Flex y estoy muy interesado en aprender acerca de esta tema.
Muy bueno el material introductorio y todo tu sitio.
Siguiendo este tutorial me sale un error cuando quiero abrir la clase calculadora en el navegador:

Error retrieving service info:

Function eregi_replace() is deprecated
C:\wamp\www\AMFPHP1.9\core\shared\util\MethodTable.php on line 505

Esa funcion es antigua y no se usa???

Estoy Usando WampServer 2.0
1. Apache 2.2.11
2. PHP 5.3.0
4. Mysql 5.1.36

Esperando tu respuesta gracias

Hola Jorge,

Efectivamente, si el error señala "deprecated" es porque la función ya no se utiliza en PHP.
Investigando... esta función ha sido eliminada desde la versión 5.3.0 de PHP (http://www.php.net/eregi_replace). Además, no existe una nueva versión de AMFPHP que sea compatible con PHP 5.3.0.
Lo más fácil es que bajes una versión de WampServer anterior a la del 30 de junio de 2009 como se indica en esta página http://sourceforge.net/forum/message.php?msg_id=7527111.

Saludos.

[...] Importante: Dentro de nuestra clase podemos utilizar métodos privados, los cuales no podrán ser utilizados desde el navegador de servicios (browser) ni desde nuestras aplicaciones en Flash, Flex o AIR. Esto permite crear funciones que realicen operaciones importantes o que requieran mayor seguridad como lo muestra Carla en su Post Original. [...]

[...] Importante: Dentro de nuestra clase podemos utilizar métodos privados, los cuales no podrán ser utilizados desde el navegador de servicios (browser) ni desde nuestras aplicaciones en Flash, Flex o AIR. Esto permite crear funciones que realicen operaciones importantes o que requieran mayor seguridad como lo muestra Carla en su Post Original. [...]

Muy buen Tutorial, por de más claro.

Saludos
Martín

Escribe un comentario

Nota: Es posible que tu comentario requiera autorización, si es así tu comentario será publicado a la brevedad. Gracias.

(requerido)

(requerido)