Flash Remoting – Connecter une base de données
Envoi et réception de données (fr_03.fla)
Modifiez le code en vous inspirant des lignes de code suivantes, puis attribuez différentes valeurs à la variable paramètre. Essayez une chaîne de caractères, un nombre entier, un nombre décimal, un objet, un tableau, une instruction XML littérale… etc…
Aucun souci d’interprétation, Flash parle ActionScript et PHP renvoie bien de l’ActionScript.
Nous assistons donc à une sérialisation / dé-sérialisation à la volée… génial non… ?
var parametre = "coucou" var pc = service.appel(parametre); pc.onResult = function(arg) { trace(arg); };
Connection à une base de données
Bon, faire communiquer Flash et un serveur distant sans soucis de langage utilisé, ou de sérialisation des données était une première étape. Maintenant, voyons voir ce qu’il en est si nous souhaitons faire communiquer Flash avec une base de données, par l’intermédiaire de la passerelle AMFPHP. En fait, rien de plus simple…
La base de données
Dans un premier temps, assurons-nous de la mise en place de notre base de données et explorons sa construction. Lancez PHPMyAdmin et invoquez la base catalogue. Si la base n’est pas déjà installée, importez le fichier images.sql fourni depuis l’onglet importer, ou copiez son contenu depuis l’onglet SQL. Si vous le souhaitez, vous pouvez vous rapprocher du tutoriel sur les bases de MySQL. Cette base contient deux tables, catégorie et images. La première permet de définir et stocker des catégories de classifications, et la seconde contient les images et l’ensemble de leurs descriptions.
Le script PHP de connection
Il faut maintenant mettre en place une classe qui va gérer la connection et le renvoi du jeu d’enregistrement. Créons un fichier ConnectDataBase.php et enregistrons-le dans le dossier de nos services. Le but de ce tutoriel n’étant pas basé sur PHP, mais sur AMFPHP, allons au plus direct et ne cherchons pas spécialement à optimiser le code côté serveur. Prévoyons simplement un passage de paramètres pour la fonction qui a en charge le renvoi du jeu d’enregistrement.
<?php class ConnectDataBase { var $dbhost = 'localhost'; var $dbname = 'catalogue'; var $dbuser = 'root'; var $dbpass = ''; var $connection; function ConnectDataBase(){ $this->connection = mysql_connect($this->dbhost, $this->dbuser, $this->dbpass); } function renvoiLaTable($table){ mysql_select_db($this->dbname, $this->connection); $sql = "SELECT * FROM ". $table; $result = mysql_query($sql); return $result; } } ?>
Le script du point de vu d’AMFPHP
D’une part ce script en tant que tel, a besoin de définir dans sa fonction constructeur une propriété methodTable, afin qu’AMFPHP puisse correctement interpréter et utiliser ce service, et d’autre part, il nous faudrait pouvoir tester sa fonctionnalité dans un framework de développement. Ce genre de fonctionnalité existe dans l’environnement de Flash Remoting et nous apporte la réponse à ces deux questions… et même plus. Voyons voir de plus près ce module qui va grandement nous aider.
Le service browser
Lancez votre web local depuis un navigateur et parcourez l’arborescence jusqu’au dossier browser. Cet outil intégré à AMFPHP, permet de lister dans la colonne de gauche, l’ensemble des classes présentes dans le service. Vous devriez voir apparaître, PremiereClasse et ConnectDataBase.
En sélectionnant PremiereClasse, la partie droite de la fenêtre reflète chaque méthode, en donnant leur description complète et détaillée. Saisissez une valeur dans le champs de saisie arg, puis pressez le bouton Envoyer. Le résultat s’affiche instantanément dans la partie haute de la fenêtre.
Si vous sélectionnez ConnectDataBase, Service Browser vous répond qu’il n’existe pas de propriété methodTable. Comme dirait l’autre… Well… mais encore ?, nous le savions déjà ! Justement, regardez juste à côté du nom de la classe dans la colonne de gauche, il existe deux liens [mt] et [code]. Si vous pressez le premier, Service Browser vous renvoi directement le code PHP, qu’il ne vous reste plus qu’à, soit exporter, soit copier-coller au sein de la classe constructeur de votre classe. Intéressant non ? Nous verrons plus tard qu’il existe une autre alternative… mais déjà cela fait bien le job et à notre plus grande satisfaction…. fainéantise quand tu nous tiens !
$this->methodTable = array( "renvoiLaTable" => array( "description" => "Retourne une jeu d'enregistrement", "arguments" => array("table"), "access" => "remote" ) );
Donc, copions collons le code dans la classe, modifions au passage la description et rendons l’accès remote, enregistrons-la et ré-invoquons le service ConnectDataBase. Cette fois-ci, la partie droite énumère correctement les descriptions de la méthode renvoiLaTable. Saisissez categorie dans le champ table. Pressez le bouton Envoyer. Répétez l’opération, avec cette fois-ci images comme valeur pour le champs table. Que vouloir de plus…. le code Flash ?… hem pourquoi pas ?
Invocation du service depuis le player Flash
Commençons progressivement et voyons ce qui se passe pas à pas, lors de l’appel d’un service, et d’une communication Flash Remoting qui gère un jeu d’enregistrement.
Appel basique du service (fr_10.fla)
Passons sous Flash et invoquons le service depuis notre animation. Créez un nouveau fichier Flash, enregistrez-le dans le dossier sources_fla sous le nom de fr_10.fla. Nous pouvons directement copier coller le code utilisé lors de la précédente animation, en y apportant les modifications nécessaires. C’est-à-dire, le nom du service appelé, ConnectDataBase au lieu de PremiereClasse, la valeur du paramètre… optons pour categorie, et le nom de la méthode sollicitée renvoiLaTable() au lieu de appel(). Ces modifications faites, lancez l’animation. La fenêtre de sortie affiche [object Object]. Cela semble fonctionner correctement. Explorons cet objet.
Code auto généré
Une alternative à l’écriture du code Flash, se trouve dans l’utilisation du deuxième bouton présent sur le Service Browser, juste à côté du service. Le bouton [code]. Si vous le pressez, vous obtenez une classe Flash prête à l’emploi. Si vous ne travaillez pas en classe, vous avez d’autres possibilités de générations automatiques. Voici pour informations et une exploration en diagonale, la classe générée pour notre service ConnectDataBase.
import mx.remoting.*; import mx.rpc.*; import mx.utils.Delegate; import mx.remoting.debug.NetDebug; var gatewayUrl:String = "http://127.0.0.1/fr/amfphp_12/gateway.php" NetDebug.initialize(); service = new Service(gatewayUrl, null, "ConnectDataBase"); function renvoiLaTable(table){ var pc:PendingCall = service.renvoiLaTable(table); pc.responder = new RelayResponder(this, "handleRenvoiLaTable", null); } function handleRenvoiLaTable(re:ResultEvent){ //Implement custom callback code }
Ce code utilise une classe RelayResponder() qui permet de prendre en charge l’aiguillage de la réponse serveur. Dans le cas où la requête aboutie, et où il n’y a pas d’erreur, le retour généré par la méthode renvoiLaTable() est aiguillé vers la méthode handleRenvoiLaTable(). Alors que si une erreur, quelle quelle soit, serait détectée, l’aiguillage orienterait la suite du programme vers la seconde méthode, définie ici sur null. Le reste du code est grandement similaire à ce que nous utilisons jusqu’à présent.
Exploration de l’objet renvoyé
Première couche (fr_11.fla)
Une manière très rapide d’explorer un objet reste de parser cet objet dans une boucle for (… in object). En réalisant et traçant une première boucle, la fenêtre de sortie nous donne une série de propriétés assez parlantes par leur nommage.
Code de la fonction onResult()
for (var i in arg) { trace(i); }
Fenêtre de Sortie
- mRecordsAvailable
- mTitles
- uniqueID
- _items
- dispatchQueue
- dispatchEvent
- removeEventListener
- addEventListener
- serverInfo
Propriété _items (fr_12.fla)
Intéressons nous de plus près à _items. Cette propriété contient l’ensemble des enregistrements renvoyés par le service. Concentrons donc l’exploration sur cette propriété particulière.
Code de la fonction onResult()
for (var i in arg["_items"]) { trace(i) }
Fenêtre de Sortie
- 2
- 1
- 0
Parsage des objets du tableau _items (fr_13.fla)
Code de la fonction onResult()
for (var i in arg["_items"]) { for (var j in arg["_items"][i]) { trace(j+" = "+arg["_items"][i][j]); } } trace("----------===================----------");
Fenêtre de Sortie
- __ID__ = 2
ch_infos =
ch_categorie = Sports
ch_id = 3
———-===================———- - __ID__ = 1
ch_infos = Divers paysage du monde
ch_categorie = Paysage
ch_id = 2———-===================———- - __ID__ = 0
ch_infos = Promenade dans le grand nord
ch_categorie = Canada
ch_id = 1
———-===================———-
La même chose de manière plus élégante (fr_13.fla)
Du fait que nous importons le paquetage mx.remoting.* de manière intégrale, nous importons de ce fait, la classe mx.remoting.Recordset. Ajoutons-y la classe mx.utils.Iterator, et nous sommes paré. Au lieu d’explorer sur plusieurs niveaux l’objet renvoyé par la méthode renvoiLaTable, utilisons directement une structure native de Flash.
Le code suivant parle de lui-même …
// a ajouter en entête import mx.utils.Iterator; // puis dans le corps pc.onResult = function(arg) { var iter = arg.getIterator(); while (iter.hasNext()) { var currentData = iter.next(); for (var i in currentData) { trace(i + " = " + currentData[i]); } trace("----------==========----------"); } }
Encore plus simple (fr_20.fla)
Le plus simple reste d’utiliser les composants. Ce tutoriel ne portant pas sur les composants, nous en resterons à la manière de connecter Flash Remoting aux composants. Bon, c’est vrai, il s’agit d’une seule ligne de code… mais bon…c’est mieux qu’aucune … 🙂 Placez un composant DataGrid sur la scène et nommez son occurrence dg. Puis modifiez le contenu de la fonction onResult() à :
pc.onResult = function(arg) { dg.dataProvider = arg };
Et ensuite !
Disons qu’une fois les données récupérées, il ne nous reste plus qu’à les exploiter et les utiliser dans notre animation. Tout est ensuite du ressort de Flash et du scénario appliqué à notre application. L’exploitation des données récupérées dépassant un peu le scope de ce tutoriel, nous en resterons là et nous ne l’aborderons pas. L’idée majeure reste quand même, la manière de récupérer et d’échanger des données entre un player Flash et un serveur d’application, en utilisant Flash Remoting.