Lab : Test du AMF server de Zend Framework 1.7 (Partie PHP)

Plus simple y'a pas smiley myconcept:actionscript & php développement et management pour applications RIA (internet, intranet et extranet)

Mise en place

En gros ça fonctionne comme pour instancier un service SOAP c'est à dire on instancie un objet 'serveur' auquel on va rattacher des classes ou des fonctions. Comme vous allez le voir rien de bien compliqué mais le service étant établi dans sa plus simple expression, il va falloir tester le comportement des appels. Donc mes premiers tests seront :

  • établir la communication AMF over http entre flash et php ;
  • définir les comportements de bases (que se passe-t-il lors du connect de flash, que se passe-t-il lors du call de flash,...);
  • vérifier le typage et la structure des variables après désérialisation AMF de chaque coté (Actionscript > PHP et PHP > Actionscript).

La partie Flash est elle expliquée ds le lab Flash dans "Test du AMF server de Zend Framework 1.7 (Partie Actionscript)" smiley myconcept:actionscript & php développement et management pour applications RIA (internet, intranet et extranet)

<?php
import
('com.zend.library.Zend.Amf.Server');
class 
Test {
    private static 
$cpt=0;
    function 
__construct(){
         
self::debug('__construction__');
    }
    function 
say($msg){
       
self::debug('Says : '.$msg);
        return 
'Message received';
    }
    public static function 
debug($txt){
        
self::$cpt++;
        
file_put_contents('log.txt',self::$cpt.' > '.$txt.PHP_EOL,FILE_APPEND);
    }
}
$svr=new Zend_Amf_Server();
file_put_contents('log.txt','Starting Server'.PHP_EOL);
$svr->setClass('Test');
echo 
$svr->handle();
? >

Premières remarques

Si le framework est correctement installé aucun souci ça tourne tout seul et les fonctionnalités sont très proches de SOAP si pas identiques.

Quelques commandes utiles:

  • setClass : permet d'ajouter une class au service
  • addFunction : si vous ne voulez pas attacher d'objet ou si vous souhaitez rajouter une fonction sans redéfinir l'objet vous pouvez vous passer du setClass et simplement ajouter la fonction au service.
  • setClassMap : permet de mapper le nom des classes existantes afin de l'adapter au nom des classes appelées par flash. Vous pouvez aussi comme pour SOAP

Sur le site Chinois de zfphp il est notifié que 'All attached methods and functions need docblocks' mais perso je n'ai pas eu de problème avec ma classe Test. Il va de soit que tout doit être documenté style phpdoc si on veut travailler correctement mais je n'ai pas vu la nécessité techique dans ce cas.


NB : vous pouvez attacher plusieurs fonctions et classes au service. Afin d'éviter les problèmes de noms, utiliser le namespacing en passant un string en second paramètre aux méthodes addFunction & setClass

Comportement du ZEND AMF SERVER avec une application Actionscript 3

Lors des appels

Voici donc le résultat de mes tests :

  • Lors de l'appel de la méthode connect() de flash : rien -> l'url n'est même pas appelée;
  • Lors de l'appel de la méthode call() de flash : le résultat est intéressant et les comportements étonnamment logiques quand on connait un peu le passé de flash et de php coté développements...
    • La connexion est instanciée une seule fois lors du premier call (appel de l'url);
    • Tous les appels se font bien sur la même 'session' car mon compteur n'a pas cessé de s'incrémenter;
    • Si la méthode distante est publique mais pas statique : à chaque call un nouvel objet est instancié -> on repasse dans le constructeur à chaque fois;
    • Si la méthode distante est publique et statique : seule la méthode est appelée et pas le constructeur;

    Il faut donc prévoir un objet Singleton ou bien stocker un objet dans une statique de la classe attachée au service si on veut garder une seule instance d'objet.

  • C'est une opération http et donc une application client pour une instance serveur. Donc pour faire un application multi-users, il faudra donc soit utiliser une mémoire partagée en gardant l'HTTP, soit développer une application socket standalone en PHP (un peu comme un serveur xml ou telnet mais avec les réponses en AMF).

Sérialisation / désérialisation d'objets simples

Bon ici c'est comme pour des conversions JSON ou SOAP > quand on utilise plusieurs langages, les objets d'échanges doivent rester simples aussi je n'ai testé que des structures simples. En voici un extrait (PHP > AS3)

<?PHP
    
...
    
//méthodes appelées par flash
    
function getObject(){
        
$test=new StdClass();
        
$test->id=123;
        
$test->name='toto';
        
$test->nickname='foo';
        
$test->place2be='bar';
        return 
$test;
    }
    function 
getArray(){
        
$tab=array('test','fes',0,1.877,2,3,"tetst 1"=>'tool1','test 2'=>'tool2');
        return 
$tab;
    }
    function 
getComplexArray(){
        
$tab=array('test','fes',0,1,2,3,'child'=>array('ctest','cfes','c0','c1',2,3,"ctetst 1"=>'ctool1','ctest 2'=>'ctool2'),"tetst 1"=>'tool1','test 2'=>'tool2');
        return 
$tab;
    }
    function 
getBoolean(){
        return 
true;
    }
    
//Va recevoir les objets envoyé par flash
    
function printUnserializeObject($object){
         
ob_start()
         
var_dump($object);
         
self::debug('Objet reçu de flash : '.ob_get_clean());      
         return 
true;          
    }

Donc entiers, décimaux, chaines, tableau simple, tableaux complexes (plusieurs dimensions, tableaux associatifs (indices textuels à la place des offset entier), objets,... tout est passé et le typage des informations et leur structure sont restés intacts ! 8000x mieux que JSON smiley myconcept:actionscript & php développement et management pour applications RIA (internet, intranet et extranet). Ce test était bi-directionnel (as renvoyait à PHP les données que PHP lui avait envoyées et tout est resté intact : les données de départs sont restées identiques aux données d'arrivées. Nice job de la part de Zend & d'Adobe : c'est rare quand tout passe du premier coup...

Niveau tests de sérialisation je me suis arrêté là car il y a déjà tout ça dans le wiki de zend.


Voici juste les tables de conversions PHP2AS et AS2PHP :

- MY Concept FlashPlayer Loader for actionscript demo's and movie/animation player-