2010-04-08

Introducción a AMFPHP AS3 + PHP5

AMFPHP 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. class Calculadora
  2. {
  3. /**
  4. * Suma dos números pasados por parámetro
  5. * @returns Regresa un valor numérico
  6. */
  7. function sumar($numeroA, $numeroB)
  8. {
  9. return ($numeroA + $numeroB);
  10. }

  11. /**
  12. * Resta dos números pasados por parámetro
  13. * @returns Regresa un valor numérico
  14. */
  15. function restar($numeroA, $numeroB)
  16. {
  17. return ($numeroA - $numeroB);
  18. }

  19. /**
  20. * Multiplica dos números pasados por parámetro
  21. * @returns Regresa un valor numérico
  22. */
  23. function multiplicar($numeroA, $numeroB)
  24. {
  25. return ($numeroA * $numeroB);
  26. }

  27. /**
  28. * Divide dos números pasados por parámetro
  29. * @returns Regresa un valor numérico
  30. */
  31. function dividir($numeroA, $numeroB)
  32. {
  33. return ($numeroA / $numeroB);
  34. }
  35. }

  36. ?>

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. class Calculadora
  2. {
  3. /**
  4. * Suma dos números pasados por parámetro
  5. * @returns Regresa un valor numérico
  6. */
  7. function sumar($numeroA, $numeroB)
  8. {
  9. return ($numeroA + $numeroB);
  10. }

  11. /**
  12. * Resta dos números pasados por parámetro
  13. * @returns Regresa un valor numérico
  14. */
  15. function restar($numeroA, $numeroB)
  16. {
  17. return ($numeroA - $numeroB);
  18. }

  19. /**
  20. * Multiplica dos números pasados por parámetro
  21. * @returns Regresa un valor numérico
  22. */
  23. function multiplicar($numeroA, $numeroB)
  24. {
  25. return ($numeroA * $numeroB);
  26. }

  27. /**
  28. * Divide dos números pasados por parámetro
  29. * @returns Regresa un valor numérico
  30. */
  31. function dividir($numeroA, $numeroB)
  32. {
  33. return ($numeroA / $numeroB);
  34. }

  35. /**
  36. * Este método es privado y no aparecerá en el browser de servicios
  37. * @returns Regresa la fecha y tiempo del servidor
  38. */
  39. function _esteMetodoEsPrivado() {
  40. $fecha_hoy = date("d/m/Y") . ' ' . date("H:i:s");
  41. return $fecha_hoy;
  42. }

  43. /**
  44. * Este método es público y está accediendo a nuestro método privado
  45. * @returns Regresa la fecha y tiempo del servidor
  46. */
  47. function obtenFechaServidor() {
  48. $fecha_hoy = $this->_esteMetodoEsPrivado();
  49. return $fecha_hoy;
  50. }
  51. }

  52. ?>

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):

  • numeroA_txt
  • numeroB_txt
  • resultado_txt

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

  • mas_btn
  • menos_btn
  • por_btn
  • entre_btn

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. /* 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 */
  5. var gateway:String = "http://localhost/AMFPHP1.9/gateway.php";
  6. /* Creamos una variable de tipo NetConnection para poder establecer la conexión. Este objeto funcionará como enlace entre el cliente y el servidor */
  7. var conexion:NetConnection = new NetConnection;
  8. /* Establecemos una conexión bidireccional entre el Flash Player y el servidor */
  9. conexion.connect(gateway);
  10. /* 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 */
  11. var responder:Responder;
  12. /* Deshabilitamos el campo de texto donde se mostrará el resultado para que sea sólo de lectura */
  13. 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. /* 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) */
  6. responder = new Responder(respuesta, error);

  7. /* 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. */
  8. conexion.call("Calculadora.sumar", responder, numeroA, numeroB);
  9. }

  10. function resta(evento:MouseEvent) :void {
  11. var numeroA:Number = Number(numeroA_txt.text);
  12. var numeroB:Number = Number(numeroB_txt.text);

  13. operacion_mc.gotoAndStop("menos");
  14. responder = new Responder(respuesta, error);

  15. conexion.call("Calculadora.restar", responder, numeroA, numeroB);
  16. }

  17. function multiplicacion(evento:MouseEvent) :void {
  18. var numeroA:Number = Number(numeroA_txt.text);
  19. var numeroB:Number = Number(numeroB_txt.text);

  20. operacion_mc.gotoAndStop("por");
  21. responder = new Responder(respuesta, error);

  22. conexion.call("Calculadora.multiplicar", responder, numeroA, numeroB);
  23. }

  24. function division(evento:MouseEvent) :void {
  25. var numeroA:Number = Number(numeroA_txt.text);
  26. var numeroB:Number = Number(numeroB_txt.text);

  27. operacion_mc.gotoAndStop("entre");
  28. responder = new Responder(respuesta, error);

  29. conexion.call("Calculadora.dividir", responder, numeroA, numeroB);
  30. }

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. /* 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. */
  6. function error(error:Object):void {
  7. trace("Error: " + error.description);
  8. }

  9. /* Establecemos las acciones de nuestros botones */
  10. mas_btn.addEventListener(MouseEvent.CLICK, suma);
  11. menos_btn.addEventListener(MouseEvent.CLICK, resta);
  12. por_btn.addEventListener(MouseEvent.CLICK, multiplicacion);
  13. 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.



Descargar Archivo


Fuente:
LINK

No hay comentarios: