FLEX->AMF->PHPの初歩

ほかのブログさんにも色々ソースはあったのですが、
結局自分で書かないと全然意味がわからなかったので
自分流のまとめってことで。

AMFの詳細はここら辺を参考にさせて頂きました。
http://framework.zend.com/manual/ja/zend.amf.server.html
http://www.atmarkit.co.jp/fwcr/rensai2/flex4_05/01.html
http://blog.asial.co.jp/323
http://andante0727.blog81.fc2.com/blog-entry-299.html

簡単にいえばFLASHからバイナリ通信でPHPのクラスを叩けますよってことですかね。
ただ割と規約というか制約も多いので、そこら辺を。

AMFとPHPの連携自体も何個かライブラリがあるのですが、
とりあえずZEND_AMFを使うことに
(特に理由はありません。)

FLASH側はFLEX BUILDER3です。

とりあえずZEND_AMFを落としてきてサーバ側ではパスを通しておいてください。
php_iniとかに書いておけばいいかと。

シンプルなソースはこんなかんじ。

php側

//http://hogehoge.com/amf.php
include('/Zend/Amf/Server.php');

$Server = new Zend_Amf_Server();
$Server->setClass('Foo');
$return = $Server->handle();
//phpからFLEXにデータを返す
echo $return;


Class Foo {
   private $aho;
   public function bar($aho,$baka,$manuke) {
        $this->aho = $aho;
        return array($this->aho,$baka,$manuke);
    }

   public function buzz($baka,$manuke) {
        return array($baka,$manuke);
    }

}

ほぼソースそのままです。っていうかほぼおまじないみたいなもので、
これだけ書いておけばあとはFLEX側から書いたクラスをぶったたけます。

FLEXではこのクラス名とメソッド名が必要になってきます。

FLEX側MXML

//test.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script source="../libs/amf.as" />

//AMFのアクセス部分
<mx:RemoteObject id="amfAccess" source="Foo" endpoint="http://hogehoge.com/amf.php" destination="zend" fault="onFault1(event)">
    <mx:method name="bar" result="onResult(event)" fault="onFault2(event)" />
    <mx:method name="buzz" result="onResult(event)" fault="onFault3(event)" />
</mx:RemoteObject>

//結果出力
<mx:VBox width="100%">
    <mx:VBox width="100%">
        <mx:Text id="php_result1"/>
        <mx:Text id="php_result2"/>
        <mx:Text id="php_result3"/>
    </mx:VBox>
    <mx:VBox width="100%">
        <mx:Button label="てすと1" click="amfTest1()" />
        <mx:Button label="てすと2" click="amfTest2()" />
    </mx:VBox>
</mx:VBox>


FLEX側asファイル

//amf.as

import mx.controls.Alert;
import mx.rpc.events.ResultEvent;

public function amfTest1() :void{
  //FLEXのid.phpのメソッド名(引数) にする
    amfAccess.bar("amf1","amf2","amf3");
}

public function amfTest2() :void{
  //FLEXのid.phpのメソッド名(引数) にする
    amfAccess.buzz("amf1","amf2","amf3");
}

public function onResult(event:ResultEvent):void {
 //phpからのリターンを表示
    var spl:Array = event.result.toString().split(",");
    php_result1.text = spl[0];
    php_result2.text = spl[1];
    php_result3.text = spl[2];
}

MXMLから説明すると、 mx:RemoteObject の source をPHPで作ったクラス名に、 endpoint はファイルのURIにします。
んで、mx:method の name をメソッド名にします。
(この mx:method の中に <arguments> としてタグでやる場合はその中のタグは
 PHPのメソッドのほうで書いた引数と名前合わせないといけないのでなんかかっこ悪いです。)

でAS側で単純に FLEXのid.メソッド名(引数,引数,引数)ってかけるわけです。

ちなみにリターンはarrayで送るとカンマくぎりだったので splitして表示させているだけです。

ただエラー関連はphpのエラーを返してくれるわけではないので、
PHP側でエラーがないか先にテスト通してからじゃないと
FLEXのほうをゴリゴリってわけにはいかないのがめんどくさいですね。
(FLEXとPHPを同時並行で書くのは結構きつい)

*追記
癖で tostring() してたので勘違いしてましたが、phpからくるデータは
flexのarrayで受け取ってそのまま扱うことができました。