Material: Integrando PHP5 y AS3 a través de AMF

Dejo aquí todo el material de la charla que ofrecí en la PHPConfrence el viernes:

Slides

Integrando ActionScript3 y PHP5 a través de AMF

Ejemplo 1: Chat AMF

Flex + WebOrb Chat
AMF File Chat: Chat realizado con WebOrb para PHP + Flex.
Se puede ver en acción la implementación de mensajería de WebOrb para PHP y un sistema de transferencia de archivos a través del canal del Chat.

Ejemplo 2: Gestor Contactos

Gestor Contactos multi AMF implementation
Gestor de Contactos realizado con PHP + Flex. Se puede ver cómo con una misma base de código, solo cambiando las rutas de los gateways AMF se puede atacar a un mismo servicio a través de las diferentes implementaciones presentadas: Weborb, AMFPHP y Zend_AMF.
Nota 1: Zend framework debe estar instalado en el include_path de PHP para que funcione con Zend_AMF. Las demás implementaciones funcionan out of the box.
Nota 2: Se debe crear la base de datos MySQL gestor_contactos y ejecutar el script SQL contra ésta para crear la tabla contacto.

Enjoy!

PHP Conference 2009

php barcelona conference 2009Vuelve la PHP Barcelona Conference en su edición 2009 los días 30 y 31 de Octubre, este año con una apuesta mucho más fuerte e interesante. Para empezar el evento dura dos días durante los cuales habrá tres charlas/workshops paralelos continuamente.

Este año tengo el placer de participar como ponente dando la charla “Integrando PHP5 y ActionScript a través de AMF“, así que si vas a estar por ahí y te interesa ver cómo se integran PHP y Flash/Flex no puedes perderte esta charla!
La charla se centrará en el protocolo AMF, sus distintas implementaciones en PHP, casos de uso que cubran características interesantes, algunos benchmarks, etc…flex and PHP

Volviendo al evento, este año se volverá a celebrar en el Citilab de Cornellà de Llobregat, muy cerca de Barcelona ciudad.
El programa ya está cerrado y se puede ver en el apartado correspondiente de la web del evento.

Los ponentes: Derick Rethans, Pedro Cambra, Lorna Mitchel, Lorenzo Alberton, Joan Llenas (yo mismo), Rasmus Lerdorf, Kuassi Mensah, Chema Garrido, Erik Schultink, Lars Jankowfsky, Davide Ferrari, Stefan Koopmanschap, Lars Jankowfsky, Àlex Puig, Enrico Zimuel, Hans Zaunere, Damien Seguy, Davide Mendolia, Kuassi Mensah, Jordi Roura, Sebastian Bergmann, Kuassi Mensah, Victor Guardiola, Fabien Potencier, Fernando Palomo, Jordi Catà, David Zuelke… son un montón de ponentes!

Las charlas se darán en Inglés y Castellano dependiendo de la preferencia del ponente. En el apartado de charlas se puede diferenciar el idioma a través de un icono.

Si tienes que viajar y reservar estancia los organizadores proponen algunas opciones.
Y nada más solo queda que te registres!
Nos vemos

Barcelona PHP Conference

PHP Barcelona international conference
El Barcelona PHP user group ha organizado la PHP international conference un evento que trae ponentes de todo el mundo a la ciudad de Cornellà, muy cerca de Barcelona este 27 de Setiembre (27-09-2008) .
Pinta pero que muy bien! solo hace falta ver la programación y los ponentes.
Éstas son las charlas:

Si desarrollas con PHP no te puedes perder esta oportunidad… a ver si nos vemos por ahí :)

Enlaces:

Doctrine: ORM Open Source para PHP 5.2+

Doctrine es un potente y completo sistema ORM (object relational mapper) para PHP 5.2+ con un DBAL (database abstraction layer) incorporado.

Justo lo estoy utilizando para un proyecto y estoy empezando a ver su potencial, pero de la documentación se puede extraer que tiene todas las características necesarias para ser funcional en (casi?) cualquier proyecto.

Entre muchas otras cosas tienes la posibilidad de exportar una base de datos existente a sus clases correspondientes y también a la inversa, es decir convertir clases (convenientemente creadas siguiendo las pautas del ORM) a tablas de una base de datos.
Por otro lado, como la librería es bastante grande ésta tiene un método para ser ‘compilada’ al pasar a producción.
Dejo un índice de temas que estoy utilizando para buscar referencias durante el desarrollo:

amfphp de nuevo en marcha

El proyecto amfphp tiene un nuevo equipo de desarrollo.
Desde que Patrick Mineault anunció que se retiraba del desarrollo web en general el futuro del proyecto ha sido incierto. Ahora tenemos asegurada una nueva versión gracias a Wade Arnold y su equipo de desarrollo.
Se espera una versión 2.0 próximamente tal y como indica Patrick en su último post.
Si quieres agradecer el gran trabajo que Patrick ha hecho con amfphp no dudes en hacer una donación, hay un botón “Make a donation” de Paypal en la barra lateral de su blog.

php mkdir en safe mode

Si estás en un server con php en safe mode y quieres utilizar mkdir() aquí tienes una posible solución. Se trata de emular el funcionamiento de mkdir() mediante las funciones de ftp que tiene php.

PHP:
  1. // @param $dir: una ruta relativa desde el chroot del usuario ftp
  2. // (a veces puede ser que pida una ruta absoluta, depende del server)
  3. public function mkdirSafeMode( $dir )
  4. {
  5.     $conn_id = ftp_connect( "ftp.mi_dominio.com" );
  6.     if( @ftp_login( $conn_id, "mi_usuario_ftp", "mi_password_ftp" ) )
  7.     {
  8.         if ( @ftp_mkdir($conn_id, $dir) )
  9.         {
  10.             ftp_chmod( $conn_id, 0777, $dir );//permisos de lectura/escritura/ejecución
  11.             ftp_close( $conn_id );
  12.             return true;
  13.         }
  14.         else
  15.         {
  16.             ftp_close( $conn_id );
  17.             return false;
  18.         }
  19.     }
  20.     else
  21.     {
  22.         ftp_close( $conn_id );
  23.         return false;
  24.     }
  25. }
  26. //ejemplo
  27. $dir = "/httpdocs/nuevaCarpeta";
  28. if( mkdirSafeMode( $dir ) )
  29. {
  30.     echo "Carpeta creada correctamente";
  31. }
  32. else
  33. {
  34.     echo "Error al crear la carpeta.";
  35. }

Autentificación segura cliente/servidor

Leyendo la documentación acerca de como MySQL autentifica sus clientes he encontrado un sistema que me ha parecido extremadamente fácil de implementar y que aumenta la seguridad de manera importante con respecto a sistemas tradicional de login.

El flujo es el siguiente:

1. Lado Servidor
1.1 Se crea un string aleatorio de n caracteres que
     llamaremos RAND_STR y se guarda en la sesión.
1.2 Se envía RAND_STR al cliente

2. Lado Cliente
2.1 Se recibe RAND_STR
2.2 El usuario entra su usuario USERNAME_CLIENT
     y su password USER_PASS_CLIENT
2.3 Se calcula HASH_CLIENT = SHA1(USER_PASS_CLIENT)
2.4 Se calcula CLIENT_RES = SHA1(RAND_STR+HASH_CLIENT)
2.5 Se envía al servidor

3. Lado Servidor
3.1 Se recibe USERNAME_CLIENT y CLIENT_RES
3.2 se obtiene el password del usuario USERNAME_CLIENT
     (por ejemplo con un select en la db)
3.2 Se calcula HASH_SERVER = SHA1(USER_PASS_SERVER)
3.3 Se calcula SERVER_RES = SHA1(RAND_STR+HASH_SERVER)
3.5 Se comprueba que son iguales SERVER_RES == CLIENT_RES

Como se puede ver, a cada autentificación para un mismo usuario lo que se envíe será diferente ya que RAND_STR se genera en el servidor aleatoriamente.

PHP Debugging fácil con powerflasher.com SOS

La consola SOS de poweflasher.com por lo general se ha utilizado como ventana de salida para desarrollos Flash, pero en realidad cualquier lenguaje que disponga de funciones de conexión, lectura y escritura a sockets puede beneficiarse de la herramienta.
Éste es el caso de PHP, que dispone de la función fsockopen(), la cual abre una conexión con un puerto determinado y permite realizar operaciones de lectura y escritura.

Aprovechando todas las características que ofrece SOS se puede conseguir tener una ventana de salida para PHP con bastantes características interesantes.

Para conseguir algo así se necesita la consola SOS y esta clase (descarga con ejemplo al final)

PHP:
  1. <?php
  2. /*
  3. * @author Joan Garnet (http://www.joangarnet.com)
  4. * @version 1.0
  5. */
  6.  
  7. class Level
  8. {
  9.     private static $cont = 0;
  10.     const DEBUG = "DEBUG";
  11.     const WARN  = "WARN";
  12.     const ERROR = "ERROR";
  13.     private $level;
  14.     private $levels = array
  15.     (
  16.         self::DEBUG => array ( 65280, 60416 ),//green
  17.         self::WARN  => array ( 16744448, 15234048 ),//orange
  18.         self::ERROR => array ( 16711680, 15990784 )//red
  19.     );
  20.     public function __construct( $level=self::DEBUG )
  21.     {
  22.         $this->level = $level;
  23.     }
  24.     public function getLevelColor()
  25.     {
  26.         $colors = $this->levels[$this->level];
  27.         return $colors[ self::$cont++ % 2 ];
  28.     }
  29. }
  30.  
  31.  
  32.  
  33. class Debugger
  34. {
  35.     /*
  36.      * Singleton implementation
  37.      */
  38.     private static $instance = null;
  39.     public static function getInstance()
  40.     {
  41.         if( self::$instance == null )
  42.         {
  43.             self::$instance = new Debugger();
  44.         }
  45.         return self::$instance;
  46.     }
  47.  
  48.     private $socket;
  49.     private $level;
  50.     public static $foldEnabled;
  51.     private function __construct()
  52.     {
  53.         $this->foldEnabled = false;
  54.         $this->setLevel ( new Level(Level::DEBUG) );
  55.         $this->socket = fsockopen ( "localhost", 4444, $errno, $errstr, 30 );
  56.     }
  57.  
  58.     /*
  59.      * sends message(s) to the output screen
  60.      * the function accepts any number of arguments
  61.      * arguments can be of any type (string, array, object, date, etc..)
  62.      */
  63.     public function trace ()
  64.     {
  65.         $args = func_get_args();
  66.         foreach( $args as $data )
  67.         {
  68.             if( !is_string($data) )
  69.             {
  70.                 $data = var_export( $data, true );
  71.             }
  72.             else
  73.             {
  74.                 $data = utf8_encode($data);
  75.             }
  76.             fwrite ( $this->socket, "!SOS<setKey><name>currentLevel</name><color>". $this->level->getLevelColor() ."</color></setKey>".chr(0) );
  77.             if( $this->foldEnabled )
  78.             {
  79.                 fwrite
  80.                 (
  81.                     $this->socket,
  82.                     "!SOS<showFoldMessage key='currentLevel'>
  83.                         <title>[". microtime(true) ."]</title>
  84.                         <message><![CDATA[". $data ."]]></message>
  85.                     </showFoldMessage>".chr(0)
  86.                 );
  87.             }
  88.             else
  89.             {
  90.                 fwrite ( $this->socket, "!SOS<showMessage key='currentLevel'><![CDATA[[". microtime(true) ."] ". $data ."]]></showMessage>".chr(0) );
  91.             }
  92.         }
  93.     }
  94.  
  95.     /*
  96.      * clears output screen
  97.      */
  98.     public function cls()
  99.     {
  100.         fwrite ( $this->socket, "!SOS<clear/>".chr(0) );
  101.     }
  102.  
  103.     /*
  104.      * brings SOS to front and shows if hidden
  105.      */
  106.     public function show()
  107.     {
  108.         fwrite ( $this->socket, "!SOS<show/>".chr(0) );
  109.  
  110.     }
  111.  
  112.     /*
  113.      * hides SOS to system tray
  114.      */
  115.     public function hideToTray ()
  116.     {
  117.         fwrite ( $this->socket, "!SOS<hide/>".chr(0) );
  118.  
  119.     }
  120.  
  121.     /*
  122.      * sets level (background color) of messages
  123.      */
  124.     public function setLevel( Level $level )
  125.     {
  126.         $this->level = $level;
  127.     }
  128. }
  129. ?>

Enlaces relacionados:
* SOS
* Debugger.as con SOS

Respuesta del servidor al subir archivos: FileReference.uploadCompleteData

En la última versión de Flash Player ( 9.0.28.0 ) la API de FileReference incluye un nuevo evento: uploadCompleteData.
Se trata de un evento que se ejecuta cuando se ha subido por completo el archivo y (solo si) se devuelve un mensaje.
Digamos que el flujo sería el siguiente:

En el caso que no se devuelva un mensaje (opción nada aconsejable) simplemente se ejecutaría el evento COMPLETE y el upload podría o no haberse realizado con éxito.

Actionscript:
  1. import flash.events.DataEvent;
  2. import flash.net.FileReference;
  3. var fr:FileReference = new FileReference();
  4. fr.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, callbackFunction);
  5. ( ... )
  6. fr.upload(new URLRequest("upload.php"));// upload.php DEBE DEVOLVER ALGÚN MENSAJE
  7. function callbackFunction ( e:DataEvent ):void
  8. {
  9.     trace( e.data );
  10. }

[ via http://bcdef.org ]

Cheat sheets

Varios cheat sheets muy útiles:


* ActionScript 2.0
* MySQL
* PHP
* CSS
* JavaScript

[ vía franto.com, Mike Chambers ]

Next Page →