JeuWeb - Crée ton jeu par navigateur
Communication Flash-Php - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Communication Flash-Php (/showthread.php?tid=3531)

Pages : 1 2


Communication Flash-Php - Blarg - 11-01-2009

Bonjour!

Je n’ai pas trouvé de tuto dans le wiki pour faire de la communication flash/php. (Vous allez rire, mais je n’ai pas trouvé le moyen d’ajouter ce tuto dans le wiki non plus, alors si quelqu’un sait comment faire…)

La communication client flash et serveur est une fonctionnalité de base dans flash qui est inscrite dans le fichier d’aide, mais si on ne sait pas où chercher, ça peut être long avant de trouver l’information pertinente. Je vous donne donc ma façon de faire, en espérant qu’elle simplifiera la vie aux intéressés.

Flash mx 2004
Actionscript 2


Je ne donne qu’un squelette de script ici : d’abord le script dans flash qui envoie une requete php au serveur, ensuite le script php qui reçoit la demande et renvoie des informations au client, puis retour au client flash qui reçoit l’info de php.

Je commence par vous envoyer le script du client flash bêtement, je l'explique ensuite :

Code :
_root.createEmptyMovieClip("clipCible", _root.getNextHighestDepth());
//
_root.clipCible.onData = function() {
    //
    trace(_root.clipCible.reponse);
    //
    _root.clipCible.removeMovieClip();
}
//
loadVariables("http://www.siteweb.com/addition.php?chiffreA="+10+"&chiffreB="+4, _root.clipCible);

Explication :
La commande «createEmptyMovieClip» permet de créer un clip vide nommé «clipCible» qui servira pour stocker les variables reçues du serveur lors de leur réception.
Ensuite, on greffe la fonction «onData» sur notre «clipCible». Cette fonction sera appellé dès que le client aura REÇU toutes les variables de php. (Dans mon exemple, la variable sera écrite dans la fenêtre Output puis le clip de réception sera effacé)
Finalement, la commande «loadVariables» se charge d'envoyer des informations au script php. Il faut utiliser un format html strict pour envoyer les variables : «cheminVersLaPagePhp» suivit d'un «?». Ensuite on ajoute les variables «nomDeVariable=Valeur». Si on doit envoyer plus d'une variable, on les accole grace au symbole «&», soit : «nomDeVariable=Valeur&nomDeVariable2=Valeur2».

Ce qu'il est important de comprendre ici, c'est que ce script est exécuté de façon asynchrome; il y a un laps de temps indéterminé entre l'envoie des variables à php et l'exécution du script de réception «onData». Ce laps dépend de la vitesse de connexion internet et de la complexité du script exécuté du côté php. Donc le script de flash continuera de s'exécuter en attendant que php renvoie ses variables, ce qui peut pauser des problèmes. J'ai tendance à bloquer tous les menus après l'envoie d'un «loadVariables» de la façon suivante :

Code :
_root.menuInscription.onPress = function() {
    if(_root.clipCible == undefined){
        /* script */
    }
};

Ainsi, à chaques fois que je fais un script de réception, je le nomme «clipCible». De cette façon, le client flash attendra la réception des variables php avant de continuer. Lors de l'exécution «onData», le clip est effacé, et on peut renvoyer une nouvelle commande.



Voici finalement le script php (le document s'appelle «addition.php» et est placé à la racine du site «www.siteweb.com»):

Code :
<?php
//
$variableA = $_GET['chiffreA'];
$variableB = $_GET['chiffreB'];
//
$reponse= $variableA+ $variableB;
//
echo"reponse=$reponse&";
?>

Encore une fois, si on avait plus d'une variable à renvoyer au client flash, il faut respecter le format html script décrit plus haut.
J'ai ajouter le symbole «&» à la fin des variables, car j'ai remarqué que parfois flash ne reçoit pas la dernière variable sans lui...


Voilà, j'espère que ce script vous sera utile. Si vous avez des questions, n'hésitez pas à mes les communiquer.


RE: Communication Flash-Php - mdcarter - 11-01-2009

Pour faire des choses encore plus propre et complexe (php object, transfert de tableaux, d'objets, etc...) je te conseille de regarder du coté d'amfPHP
http://www.amfphp.org/
Ça te simplifiera la vie une fois installé Smile


RE: Communication Flash-Php - Shao - 11-01-2009

Je voulais apporter mon grain de sel sur ce système de communication en Flash/PHP.

Pas mal de procédés existent afin de faire communiquer Flash avec un langage serveur. J'en utilise principalement deux :
- La communication XML
- Le Remoting (cela peut être AMFPHP par exemple)

Pour le Remoting je préfère en parler une autre fois car bien qu'il soit pour moi un des procédés les plus propres, il est également plus difficile à mettre en place.

Communication XML :

Le principe :
Le principe de la communication XML est simple. Flash va charger un fichier XML se situant sur votre serveur web. Une fois ce chargement effectué, vous n'avez plus qu'à traiter les données dans vos clips.

Coté Client (en AS2) :
Prenons un exemple simple, je veux charger des news dans un champ texte.
Pour cela je dispose sur mon serveur du fichier "news.xml".


<?xml version="1.0" encoding="UTF-8" ?>
<ListeNews>
<News id="0" nom="Shao" date="01/10/08" contenu="ceci est un exemple de news"/>
<News id="1" nom="Bidule" date="31/12/08" contenu="ceci est 2e exemple de news"/>
<News id="2" nom="Truc" date="01/10/08" contenu="ceci est un 3e exemple de news"/>
</ListeNews>

Je vais demander à Flash de me charger ce fichier. Quand il aura terminé, il devra me copier le contenu dans mon champs texte.

Je considère que dans votre scène vous avez une occurrence d'un champ texte qui s'appelle mesNews.

On commence par définir notre variable de notre fichier XML :

var fichierXML:XML = new XML() ;
fichierXML.ignoreWhite = true ;

Comme Blarg l'a si bien expliqué, Flash fonctionne de manière asynchrone. Cela veut dire que pour certaines fonctions en ActionScript, le résultat ne sera pas directement disponible après le lancement d'une fonction. Il faut attendre ce qu'on appelle un évènement. Il est préférable que les évènements soient définis avant de lancer ce genre de fonction.
Ici nous attendons que le chargement soit terminé avant de pouvoir traiter notre fichier XML, et nous devons définir ce qu'il se passe lorsque l'évènement 'Chargement' est terminé :

fichierXML.onLoad = function(success:Boolean)
{
//On vérifie que le chargement s'est bien passé
if(success)
{
//On récupère le nombre de news que l'on chargé
var nbNews:Number = this.firstChild.childNodes.length ;

//On effectue une boucle dans laquelle on va parcourir l'ensemble de nos news au sein de notre fichier XML
for(var i:Number =0 ; i<nbNews ; i++)
{
mesNews.text += "News "+i+"\n" ;
mesNews.text += " Auteur : "+this.firstChild.childNodes[i].attributes.nom+"\n" ;
mesNews.text += " Date : "+this.firstChild.childNodes[i].attributes.date+"\n" ;
mesNews.text += " Contenu : "+this.firstChild.childNodes[i].attributes.contenu+"\n" ;
mesNews.text += "\n" ;
}
}
else
{
mesNews.text = "Erreur lors du chargemment du fichier XML" ;
}
}

Il faut maintenant lancer la fonction qui permet de charger le fichier XML.

fichierXML.load("news.xml") ;

Voilà, vous compilez et vous placez votre swf au même endroit que votre fichier XML, et normalement vous verrez apparaitre les news dans votre champ texte en Flash.
Bien sûr cet exemple est un bout de script simple, mais il est possible de manœuvrer votre chargement XML (ainsi que vos clips) avec de l'orientée objet Wink

Et le PHP dans tout ça ?
Et bien maintenant que vous savez charger un fichier xml, vous pouvez très bien via php demander par exemple la liste des news au sein d'une Base de Données et la retranscrire au format XML (pensez à mettre votre fichier .xml au format .php Wink ).

Donc voici un exemple de mon fichier news.php
Code PHP :
<?php
//connexion a la base de données :
$db = mysql_connect('maBase', 'monLogin', 'monPass') or die('Connexion impossible') ;
mysql_select_db('maBase',$db) ;

//requête qui liste toutes les news :
$req = "SELECT m.pseudonyme, n.date_news , n.article FROM news n,membre m WHERE n.membre=m.id_membre" ;
$res = mysql_query($req) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());

//affichage du resultat sous format XML :

echo"<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \n" ;
echo
"<ListeNews>\n" ;
for(
$i = 0; $i < mysql_num_rows($res); $i++)
{
echo
'<News ' ;
$row = mysql_fetch_row($res) ;
echo
'nom="'.$row[0].'" ' ;
echo
'date="'.$row[1].'" ' ;
echo
'contenu="'.$row[2].'"/>' ;
}
echo
'</ListeNews>' ;
?>

Voilà je complèterai avec aussi une version AS3 du chargement XML (qui je pense serait plus d'actualité ^^).


RE: Communication Flash-Php - Harparine - 11-01-2009

Salut !
Personnellement, je trouve que amfphp est une usine à gaz et qu'il n'est pas forcément utile pour de petits projets. Tant que l'on a pas des tableaux ou des objets à échanger entre Flash et PHP, autant rester avec une méthode plus classique (l'architecture d'amfphp est plus contraignante côté serveur).

Par contre, Blarg, je trouve que le code est plus propre et les résultats plus faciles à utiliser lorsque l'on utilise la classe LoadVars avec flash (il est d'ailleurs précisé dans la doc que la fonction loadVariables lit des données dans un fichier externe tandis que pour la classe LoadVars, on parle bien d'envoi et de réception de données).

Un exemple du fonctionnement de ce code :


// on déclare un objet d'envoi, instancié depuis la classe LoadVars
var envoi_lv:LoadVars = new LoadVars();
// on ajoute des variables à cet objet
envoi_lv.chiffre1 = 24;
envoi_lv.chiffre2 = 42;

// on déclare un objet de réception
var reception_lv:LoadVars = new LoadVars();

// la fonction qui s'exécute lorsque l'objet reception_lv reçoit l'information que les données ont été chargées.
//"success" est ici un booléen qui est automatiquement renvoyé par onLoad.
reception_lv.onLoad = function(success:Boolean)
{
// les données ont été correctement chargées
if (success)
{
// on peut directement utiliser le résultat sans pour autant devoir le
// charger dans un clip (ce qui permet des traitements dans Flash si nécessaire)
trace("résultat de l'addition : " + reception_lv.resultat);
}
// en cas d'échec de la connexion
else
{
trace("la connexion a échoué");
}
};

// on envoit les données à PHP avec la méthode sendAndLoad
// paramètre 1 : le script php cible
// paramètre 2 : un objet LoadVars récepteur
// la méthode d'envoi (POST ou GET)
envoi_lv.sendAndLoad("http://www.monsite.fr/addition.php", reception_lv, "POST");

Le fichier php est légèrement différent :
Code PHP :
<?php
// une fonction pour formater le retour
function retour($var, $val)
{
echo
"&" , $var , "=" , utf8_encode($val);
}

// on récupère les information transmises par LoadVars
$a = $_POST['chiffre1'];
$b = $_POST['chiffre2'];

// traitement
$resultat = $a + $b;

// on renvoie vers Flash
retour("resultat", $resultat); // echo &resultat=66
?>

Il existe également une méthode send (qui permet d'ouvrir le fichier PHP dans une nouvelle fenêtre pour afficher un résultat) et une méthode load.

Voilà, j'espère que c'est clair !

@+

/!\ EDIT : je vois que la coloration syntaxique de l'actionscript m'a rajouté un <strong></strong> inutile : ce n'est pas dans le code !


RE: Communication Flash-Php - Blarg - 11-01-2009

Cool, en voulant aider les autres, c'est peut-être moi qui va apprendre quelque chose xD

Je n'ai pas poster mon script en tant qu'expert en flash, tout ce que j'ai appris c'est de façon autodidacte. Tout ce que je peux dire, c'est que mon script fonctionne, mais peut-être que vos propositions sont meilleures.


RE: Communication Flash-Php - Harparine - 11-01-2009

Si ça t'intéresse, je me suis amusé à faire un petit fichier d'exemple (alors que je suis à la bourre dans mes préparations de cours de demain^^) :
http://gwenole.stephant.free.fr/tests/flash-PHP/
les sources sont ici : http://gwenole.stephant.free.fr/tests/flash-PHP/source.zip
Le mieux est peut-être de regarder.


RE: Communication Flash-Php - Anthor - 12-01-2009

Il y a aussi Zend_AMF, qui a été développé directement par Adobe avec les dernières spécifications.


RE: Communication Flash-Php - Hakushi - 12-01-2009

Je plussoie Anthor, a l'heure actuelle, la meilleure solution pour deploayer du AMF, c'est ZendAMF. C'est tres simple d'utilisation et est basé sur les dernieres spec de chez Adobe:
http://framework.zend.com/manual/fr/zend.amf.html

Et ici une petite application AIR qui va te generer les fichiers de bases necessaire a ton application AMF :
http://flexandair.com/?cat=32

Je lis ton script et j'editerais pour mettre mes commentaires

[edit]
Le script est tres basique et fonctionnel, son seul defaut c'est l'utilisation du mot clef "_root".

_root ne doit etre jamais utilisé, pour troisraisons : premièrement parce que c'est un inconnu, on ne sait jamais la valeur de _root, si tu charges ton SWF ton _root pointe alors vers le SWF qui a chargé. Deuxiemenent, ça brise l'encapsulation et rend les choses horrible a debugger (sur un petit script comme ça c'est raisonnable, mais sur une appli complète, c'est vite l'horreur), et par la meme rend les MovieClip/Objet non reutilisable facilement. Et enfin, parce que bien que l'usage a fait que _root est usé comme un objet de type MovieClip, ça n'en est pas un, et il est préférabe en toute circonstance de travailler dans un MovieClip chargé sur le _root plutot que sur le _root lui même.

Après plus personnellement, je conseillerais a quiconque voulant mettre le nez dans Flash, de regarder directement l'AS3. L'as2 est obsolète, lent, mal pensé, mauvais, nul, bref un des pires langages que la terre aie jamais portée! (rien que ça ouais).

Voila l'equivalent avec AS3

Code PHP :
<?php 
package
{

import flash.events.*
import flash.net.*;

public class
SendAndLoadExample {

public function
SendAndLoadExample() {}
public function
sendData(url:String, _vars:URLVariables):void {
var
request:URLRequest = new URLRequest(url);

var
loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
request.data = _vars;
request.method = URLRequestMethod.POST;

loader.addEventListener(Event.COMPLETE, handleComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);

loader.load(request);
}
private function
handleComplete(event:Event):void {
var
loader:URLLoader = URLLoader(event.target);
trace("Code: " + loader.data.code);
trace("Message: " + loader.data.msg);
}
private function
onIOError(event:IOErrorEvent):void {
trace("Error loading URL.");
}
}
}

Voila une petite classe qui fait office de sendAndLoad. On traite les données retournés par PHP dans la fonction handleComplete avec un objet URLLoader.
Les variables retournées par PHP se trouvent dans URLLoader.data.nomDeLaVariable1, etc, ...

Code PHP :
<?php 
var sendAndLoad:SendAndLoadExample = new SendAndLoadExample ();
var
myVariables:URLVariables= new URLVariables();
myVariables.message_id = 12;
sendAndLoad.sendData('http://monserveur.com/script.php', myVariable);

On instancie notre classe SendAndLoad, on creer un objet URLVariables pour passer des variables a PHP et on envoie le tout en utilisant notre methode sendData().

Coté PHP:
Code PHP :
<?php
function printOutput($code, $msg){
print
"code=$code&msg=$msg";
}
$message_id = $_REQUEST['message_id'];

if(
is_numeric($message_id))
{
$message_content = new MessageContent($message_id);

printOutput('0', $message_content->getContentEncoded();
}

?>

C'est un simple exemple, mais globalement c'est comme ca que ca marche.


RE: Communication Flash-Php - Harparine - 12-01-2009

Hakushi, est-ce que des applis développées avec AS2 sont compatibles AS3 ? J'avoue que j'arrive au bout de mon jeu et que j'ai la flemme de tout mettre à jour... L'AS3 sera pour mon prochain projet (et la licence Flash aussi, maintenant que j'ai fait mes armes !)


RE: Communication Flash-Php - Hakushi - 12-01-2009

Oui et non, ça dépends de ce que tu entends par compatibles.
Tu peux charger des SWF compilés en AVM1 (as1 et 2) dans un SWF compilé en AVM2 ( Flex/AS3), et communiquer via LocalConnection, mais ça se limite a ça.
Et la façon de faire a tellement changer que si tu souhaites migrer une appli de As2 a AS3, ca veut dire la repenser depuis le début. Si ton app marche bien en AS2 et qu'AS3 ne t'offre pas de valeur ajoutée significative (traitement graphique, 3D, son, ..), ça ne vaut pas la peine de refaire tout.