ejemplo PHPObject :: contador vistas

PHPObject es una alternativa OpenSource a Flash Remoting.
La clave de PHPObject es que permite tratar clases PHP com si estuvieran definidas en nuestras aplicaciones ActionScript. Una vez instalado y configurado, el sistema simplifica enormemente el proceso de comunicación cliente-servidor.
La instanciación y llamada a métodos de las clases PHP se hace virtualmente en la película Flash.
Para ver el funcionamiento básico vamos a crear un simple contador de visitas que lee y escribe en un archivo de texto las visitas que se hacen en una página determinada.

Instalación:
Librerías ActionScript para PHPObject:
- Bajamos los archivos que conforman PHPObject.
( Para poder utilizar PHPObject necesitamos instalar la extensión que nos dará acceso al sistema )
- Instalamos la extensión que vayamos a utilizar (cerramos Flash primero). Yo instalo las dos: PHPObject_AS1.mxp y PHPObject_AS2.mxp para poder escoger según el player que quiera utilizar el cliente. (Se requiere Macromedia Extension Manager)
Con esto ya tenemos todo lo necesario en el lado cliente para desarrollar nuestro contador de visitas con PHPObject.

Antes de seguir bajamos los archivos que he preparado para el ejemplo (ver al final del post)

Preparando el terreno:
La parte servidor:
- Creamos una carpeta llamada contadorVisitas en la raíz de nuestro servidor web.
- Copiamos la carpeta server del package de PHPObject dentro de contadorVisitas.
- Creamos una carpeta llamada classes dentro de contadorVisitas
- Copiamos la clase ContadorVisitas.php de mi package en la carpeta classes.
Ya tenemos la estructura del lado del servidor montada

Configurando el gateway:
Lo primero que se debe hacer en una aplicación basada en PHPObject es definir unos pocos parámetros de configuración que van a permitir a Flash conversar con PHP.
Para hacerlo editamos el archivo /contadorVisitas/server/config.php y asignamos algunos valores:

PHP:
  1. // La ruta a las carpetas donde están las clases PHP
  2. // Pueden haber varias carpetas ($cfg['classdir'][1], etc..)
  3. $cfg['classdir'][0]= "/www/contadorVisitas/classes/";
  4. // Una clave secreta que todas las conexiones desde Flash deberán enviar.
  5. $cfg['useKey'] = "xx_clave_secreta_xx";
  6. // Aquí decimos si se puede conectar la aplicación desde el
  7. // player (false) o debe residir en un archivo .html (true)
  8. $cfg['disableStandalone'] = false;
  9. // Importante. Especifica si se utiliza codificación UTF-8 o no
  10. $cfg['multiByte'] = true;

Con esto ya tenemos el servidor listo, solo nos falta crear la página en Flash que activará el mecanismo de recuento/visualización de visitas.

Película Flash:
En el lado Flash, lo primero será incluir la librería (AS1.0) o importar las clases (AS2.0) de PHPObject (Este ejemplo es AS1.0).
A continuación configuraremos algunos parámetros necesarios como la ruta a la puerta de entrada defaultGatewayUrl, la clave de conexión defaultGatewayKey (que debe ser la misma que entramos en el archivo /contadorVisitas/server/config.php) o también convenientemente activar el soporte UTF-8 para caracteres latinos (entre otros...) con enableMultiByte.
Una vez hecho esto ya podemos instanciar PHPObject enlazando la clase PHP deseada, la cual debe estar en una de las rutas especificadas anteriormente en config.php.

Llamada / callback:
Una vez instanciada la clase, para cada llamda a un método de la clase remota debe haber (si es necesario) una función de retorno "callBack" definida desde la que podremos recibir parámetros convertidos "serializados" a ActionScript directamente desde PHP.
Esta es la magia real de este sistema. El hecho de despreocuparte totalmente de hacer conversiones mediante bucles y demás. Tansolo ejecutas un método ActionScript, y recibes datos de un tipo ActionScript. PHPObject se preocupa de todo lo demás por nosotros de una manera totalmente transparente e indolora :)

Código película Flash:

Actionscript:
  1. // incluímos la librería de PHPObject
  2. // AS1.0
  3. #include "PHPObject.as"
  4. // AS2.0
  5. //import com.ghostwire.phpobject.*
  6.  
  7. // creamos el campo de texto donde se verá todo el proceso
  8. this.createTextField ( "log", 1, 10, 10, 400, 300 );
  9. this.log.border = true;
  10.  
  11. // clave de conexión (la misma que hay en /contadorVisitas/server/config.php)
  12. _global.defaultGatewayKey = "xx_clave_secreta_xx";
  13. // definimos la ruta a la puerta de entrada
  14. _global.defaultGatewayUrl = "http://localhost/contadorVisitas/server/Gateway.php";
  15. // activamos el soporte utf8 para caracteres latinos ( ñ, ç, á, etc... )
  16. Serializer.enableMultiByte = true;
  17.  
  18. // Instanciamos PHPObject y lo enlazamos a la clase PHP
  19. var mi_contador = new PHPObject( "ContadorVisitas" );
  20. // Callback al instanciar y ejecutar el constructor de la clase.
  21. // La clase ya está inicializada y disponemos de las propiedades por defecto.
  22. mi_contador.onInit = function()
  23. {
  24.     log.text += "Clase inicializada!\n";
  25.     log.text += "* archivo: "     + this.archivo + "\n";
  26.     log.text += "* numVisitas: "    + this.numVisitas + "\n";
  27.     log.text += "\n";
  28. }
  29. // Callback. Este es el callback del método "vistasTotales".
  30. // [n_vistas] es el valor que devuelve el método.
  31. mi_contador.getVisitasTotales_onResult = function( n_visitas )
  32. {
  33.     log.text += "\n";
  34.     log.text += "Visitas totales: " + n_visitas + "\n";
  35.     log.text += "\n";
  36. }
  37. // Callback. Este es el callback del método "leeArchivo".
  38. mi_contador.leeArchivo_onResult = function()
  39. {
  40.     this.getVisitasTotales();
  41. }
  42. mi_contador.leeArchivo();

Enlace a la página de descarga de PHPObject:
* PHPObject

Enlaces relacionados:
* Flash Remoting

Comments

14 Responses to “ejemplo PHPObject :: contador vistas”

  1. Daniel on March 29th, 2005 08:34

    Buen artículo, Joan!

    una pregunta: ¿Qué difrencias hay entre phpobject y amfphp? ¿Cuáles son los pros y los contras?

    un saludo ;)

  2. admin on March 29th, 2005 09:47

    Hola Dani ;)
    Pues la filosofía en ambos casos es la misma: crear un puente de comunicación directa entre ambos lenguajes sin necesidad de conversiones intermedias, es decir, virtualmente trabajar PHP como si fuera ActionScript.
    Las diferencias exactamente no se, pero algo te puedo decir.

    AMF (Active Message Format) es un sistema creado por Macromedia que permite una comunicación directa entre un lenguaje del lado del servidor y ActionScript. Este formato es el que utiliza Flash Remoting para comunicarse con Cold Fussion por ejemplo.
    AMFphp es exactamente eso pero portado a PHP. Es decir, es Flash Remoting con PHP envez de con ColdFussion.
    Para desarrollar en AMFphp necesitarás los componentes de Flash Remoting.

    PHPObject es una implementación totalmente independiente pero basada en la misma idea. No utiliza FlashRemoting sino unas librerías propias.

    Te podré decir algo más en unos dias porque estoy ahora mismo probando las dos y viendo eso mismo, los pros y los contras :)
    De momento con PHPObject estoy muy contento de lo fácil que es de utilizar y lo bien que va.
    No he hecho pruebas en grandes proyectos, pero de momento a escala media va muy bien.

    Saludos!

  3. Michael on March 30th, 2005 05:26

    AMF es un protocolo binario creado por Macromedia que permite una comunicacion "transparente" de los datos entre el flash player y el servidor de aplicacion elegido(PHP en ese caso), tambien llamado Flash Remoting gateway.

    Macromedia aun no ha documentado el protocolo publicamente, pero se parece bastante al formato usado por los remote shared objects (cf FlashCom).
    El Flash Player comunica con el Flash Remoting gateway (amfphp) usando el protocolo AMF sobre una peticion HTTP estandar. El paquete AMF se envia como un POST binario.

    En eso es la diferencia fundamental con PHPObject.
    El nucleo de PHPObject es una modificacion de la clase Serializer de Sephiroth. En concreto usa las funciones nativas de PHP serialize() y unserialize()
    http://ghostwire.com/archives/phpobject/000032.html
    http://www.sephiroth.it/test/unserializer/

    Amfphp usa el protocolo AMF (AMFDeserializer.php )
    Pero los datos no son completamente comprimidos
    Hay cadenas lisibles dentro del flujo AMF (ver la herramienta Fiddler para comprobarlo, enlace mas abajo)
    Por lo que vi se puede extraer datos como el nombre de los metodos remotos (ejemplo: getForums()) y los resultados de la peticion. Pero por supuesto no se difunde el mecanismo PHP interno.

    Lo importante de AMFPHP es que usa AMF para la serialización de los "datatypes" (o objetos) ActionScript
    AMF tiene esa ventaja principal sobre las tecnicas de serialization de datos tradicionales (como XML, peticiones de tipo URL y PHPObject)

    Concretamente y para hacer un resumen:
    AMF(PHP) utiliza un protocolo binario y nativo para la manipulación y transporte de los objetos Actionscript, asi el flujo total de datos es más pequeño que si se usa un formato basado en cadenas normales (strings).

    Eso se traduce en un aceso muchisimo mas rapido a los datos
    Ver este ejemplo (paginación instantanea de los resultados mysql)
    http://www.amfphp.org/wiki/doku.php?id=using_pageable_resultsets
    http://cvs.sourceforge.net/viewcvs.py/amfphp/sources/examples/pageableRecordSet/

    Pero no es lo unico, hay que destacar el soporte de:
    - las sesiones PHP
    - los servicios Web (mas rapido que SOAP por ejemplo)
    - mecanismos de seguridad (metodo "Roles") para restringir el aceso a ciertas funciones
    - netDebugger (el sistema/panel de debug incluido en el Flash IDE), MUY util.
    Despues mejor ver el wiki de amfphp:
    http://amfphp.org/wiki/

    Despues, CUAL ES EL MAS SIMPLE DE USAR , PHPObject o AMFPHP ?

    Pues hay muchas maneras de implementar los callbacks o eventHandlers de remoting y eso, siempre es bueno :)
    Yo uso una version "no oficial", mejorada, creada por Jed Wood.
    - SHAREDOBJECTS : Ofrece soporte para cachear los datos en sharedObjects ( el tiempo de cache se puede configurar)
    - CODIGO SIMPLIFICADO (Configuracion del gateway en 1 LINEA)
    - NO REQUIERE LA INSTALACION DE LOS COMPONENTES REMOTING

    /////////////////////////////////////////////////////////////
    USO DE AMFPHP con UFRemotingCache
    /////////////////////////////////////////////////////////////
    import com.usableflash.remoting.RemoteHandler;
    var remote:RemoteHandler = new RemoteHandler("HelloWorld", "gateway.php", true);
    var myListener:Object = new Object();
    remote.addEventListener("ALL", myListener);
    myListener.onMakeEcho = function(obj) {
    for (var z in obj) trace(z+": "+obj[z]);
    }
    myListener.onMakeEchoError = function(obj) {
    trace ("\r\r ERROR was returned");
    }
    remote.serve("makeEcho", 0, myName.text);
    /////////////////////////////////////////////////////////////

    Personalmente encuentro la implementacion de PHPObject un poco tediosa:

    /////////////////////////////////////////////////////////////
    USO DE PHPOBJECT
    /////////////////////////////////////////////////////////////
    #include "PHPObject.as"
    _global.defaultGatewayUrl = "http://mydomain.com/services/Gateway.php";
    _global.defaultGatewayKey = "secret";
    myFoo = new PHPObject("Foo");

    myFoo.onInit = function() {
    trace(this.story);
    }
    myFoo.onResult = function(result) {
    if (typeof(result) == "object") {
    for (var i in result) trace(i + ":" + result[i]);
    }
    else {
    trace(result);
    }
    }
    myFoo.doRemoteMethod_onResult = function(result) {
    }
    myFoo.doRemoteMethod(param1,param2,...)
    /////////////////////////////////////////////////////////////

    Ya esta. Esto es parte de un articulo que tenia previsto para mi blog, pero como aun no esta en linea pues espero que sirve.

    Un saludo :)

    LECTURAS Y ENLACES:

    // AMF
    Sobre el protocolo binario AMF(Actionscript Message Format)
    http://amfphp.org/?g=amf_format
    Look at amfphp - the amf format is NOT open, yet it has been recreated (DarronShall)
    http://www.asvguy.com/2004/01/the_swf_flash_d.html

    // AMFPHP vs PHPObject
    http://www.sephiroth.it/phpBB/viewtopic.php?t=2166
    PHPObject does not use AMF
    [ASNativos] Extensión PHPObject
    comparing_amfphp_to_alternatives

    // UFRemotingCache (Implementacion mejorada de las librerias remoting)
    http://www.actionscript.com/index.php/fw/1/simplified-flash-remoting/
    http://www.usableflash.com/downloads/UFRemotingCache.zip

    // Libreria Remoting (ahorra la instalación de flashremoting_comp_as20-win-en.exe 16.39 MB)
    flashremoting_comp_sourcecode.zip (61K) New!

    // Analisis de los paquetes AMF
    HTTP proxy (o espia TCP) Fiddler
    (Configura 127.0.0.1/ 8888 en tus parametros de proxy de Mozilla Firefox)

  4. admin on March 30th, 2005 11:56

    Hola Michael,
    este comentario se merece un premio :)
    Yo lo elevaría a la categoría de artículo, la verdad.
    Me parece muy interesante la comparativa y precisamente me va a ir muy bien porque un dia de estos quiero probar AMFphp.
    Toda esa lista de enlaces es oro para mi.
    Gracias por tomarte la molestia ;)

    Volviendo al tema, algo de PHPObject que le da ventaja en algún aspecto a AMFphp es que es OpenSource (GNU LGPL License) y FlashRemoting y AMF son propietarios.
    En el tema rapidez de transferencia/parseo parece que no hay mucha diferencia por lo que he leído en uno de tus enlaces. Dicen que se empieza a notar a favor de AMFphp en proyectos con un volumenes apreciables.
    Y PHPObject también consume webservices por lo que he visto, y de una manera bastante simple.

    Creo que no hay un empate (AMF es superior porque implementa más cosas y utiliza el protocolo binario) pero las dos tecnologías son bastante parecidas en funcionalidad y rendimiento.
    Hablo sin mucho conocimiento porque AMF no lo he probado todavía y PHPObject más bien poco, pero esto es lo que pienso por lo que he ido leyendo.

    Pues despues de esto todavía tengo más ganas de probar AMFphp :)
    A ver si saco algo de tiempo...

    Saludos!

  5. Michaelm on March 31st, 2005 05:56

    Dios!
    a veces no deberia postear pasado los 5 de la mañana.
    Acabo de leerme, como me he liado sobre el tema.
    No te cortes en quitar mi ultimo comentario, perdona las molestias :(

  6. admin on March 31st, 2005 09:24

    He borrado el comentario como has pedido.
    Yo tbién soy de los que se lían a partir de las 3:00h de la mañana.
    No hace mucho confundí MTASC con NaturalDocs en el blog de Dani :)

    Saludos!

  7. Marcos on March 31st, 2005 17:25

    Muy buena información!! A ver de donde saco tiempo para mirar esto de PHPObject, me has metido el gusanillo Joan, y si logro mirarlo bien antes de 2 meses puede que lo emplee en un proyecto de tienda online que tengo en flash...

    Saludos :)

  8. admin on April 1st, 2005 02:58

    Hola marcos ;)
    Pues ya ves que es muy simple...
    Y verás que una vez has usado el sistema ya no puedes volver atrás.
    Nuesta clase "peticiones MySQL comunes" está obsoleta XD

    Saludos!

  9. Marcos on April 2nd, 2005 10:42

    Bueno, no te creas.

    En un libro: Flash MX for Server Geeks, creo que refleja muy bien la esencia de usar una técnica u otra, y en el se contempla el problema abarcando muchas posibilidades: Flash mx + lado del servidor (Cold fusion, .NET y JSP) y muchos metodos, desde strings formateados, a pares variable valor, a xml, a remoting e incluso webservices. Y en el libro siempre se insiste en que en unas ocasiones es mejor una tecnica y en otras no. Que el caso marca la elección, ninguna es siempre mejor.

    Yo creo que el envio tipo url es un gran metodo, facil de recibir y simple de implementar, y con la clase que hiciste es aun más sencillo. Solo se necesita una consulta, y saber ActionScript. Pero claro para movimientos poderosos de datos en ambos sentidos, pues... supongo que sera mejor poder pasar objetos completos.

    Cuando pruebe ya sabrás de mi... XD

    Saludos ;)

  10. admin on April 2nd, 2005 12:59

    Totalmente de acuerdo marcos,
    está claro que cada cosa tiene su momento y su aplicación.
    Me he precipitado al decir "obsoleto" :)
    Supongo que es la emoción de aprender una nueva tecnología.

    Por cierto, ¿qué tal el libro este que comentas "Flash MX for Server Geeks"?
    No escribiste un artículo por ahí? pásame el link que me lo leeré.

    Saludos!

  11. Michael on April 5th, 2005 05:18

    Hola!

    No sé como esta información te ha podido escapar ;)
    (Bueno la verdad es que yo mismo solo empece ha repasar por completo el mailing-list de MTASC ayer :p)
    Mira lo que encontré:
    [mtasc] flashremoting support files
    http://lists.motion-twin.com/archives/mtasc/2005-March/001312.html

    mich heimann de visualfire.ch ha portado las librerias remoting para MTASC
    http://eco.visualfire.ch/AMFService.zip.
    Ha reescrito por completo las librerias ( su paquete 'AMFService' contiene incluso un EventListener casero )

    Lo probe en mi Eclipse-IDE (como mola el termino de IDE :p) y funciona perfecto
    Ej:
    INFO: Status (h: 11 m: 39 s: 4) : call: Mike.AMFBOARD.servlet.ViewForum()
    on: http://localhost/flashservices/gateway.php
    INFO: onViewForum result: AMFDBResult: .../...

    Eso si hay que tener cuidado con la version de MTASC que se usa!
    De momento la version 1.03 tien un pequeño fallo que no permite parsear correctamente el codigo actionscript:
    [mtasc] Error in Fault class with 1.03
    http://lists.motion-twin.com/archives/mtasc/2005-March/001484.html
    [mtasc] mtasc 1.03 Invalid Expression error
    http://lists.motion-twin.com/archives/mtasc/2005-March/001439.html

    Asi,hay que descargar la versión precedente (1.02) para tener el package AMFService funcionando.

    Información relacionada con MTASC: Bokel LoaderClass actionscript 2 para MTASC
    http://www.v-i-a.net/blog/archives/000015.html
    (Es un blog frances..,para una tradución automatica frances-castellano: http://babelfish.altavista.com/tr )

    Saludos :)

  12. admin on April 5th, 2005 09:22

    Muy bueno ;)
    Me debió pasar porque no tenía en cuenta estas tecnologías.
    Ahora que estoy utilizándolas me va muy bien saber que se pueden utilizar en MTASC.
    Cuando MTASC sea más estable puede ser una alternativa a tomar en cuenta en el sitio donde trabajo. Yo les voy comentando y la verdad estan muy receptivos.
    Esto es un punto más.

    Saludos!

  13. Luis on May 4th, 2005 14:08

    Saludos

    Excelente explicación, me aclara muchas dudas. He bajado AMFphp, pero me gustaría tener ejemplos simples como Insertar, Modificar, Eliminar registros de una tabla. Esto yo lo he estado realizando con "sendAndLoad" seria de gran utilidad probar AMFphp.
    Si tienes algunos documentos te agradeceré si me los pudieses enviar ha ldiaz@hualo.ucm.cl

  14. Narref Blog on August 10th, 2005 21:44

    WebServices

    Ara fa uns dos anys que apostava per el XML com a que facilitaria la estandarditzaci? i la interconnexi? entre la gran diversitat de plataformes, sistemes operatius, llenguatges i aplicacions existents, crec que el seg?ent pas s?n el WebServices.
    Que ...