AMFPHPを試してみました
AMFPHPを使ってPHPとFlashでAMF形式での通信を試してみました。
AMF とは、ActionScript Message Formatと呼ばれる仕様非公開のバイナリフォーマットです。
テキストベースの形式と比べ軽量で、高速に扱うことができるそうです。
AMFPHPでは、AMF形式でのやり取りをサポートし、簡 単にFlashからPHPのメソッドを呼び出すことができ、
また、PHPとFlashでやり取りするデータの変換も自動で行ってくれるので、非常に簡単にやり取りができます。
Q.クリスマス何してました?
※初めて使ったので、おかしな点や、もっとスマートな書き方があると思いますので注意願います。
まず、AMFPHPライブラリを http://amfphp.org/ からダウンロードし、/path/to/amfphpに配置します。
今回使用したバージョンは、amfphp-1.9.beta.20070513 です。
次にflashから、送信先のファイルとなるamftest_gateway.phpを作成します。
■/var/www/public_html/amftest_gateway.php
<?php
$AMFPHP_DIR = "/path/to/amfphp"; //AMFPHPディレクトリへのpath
include $AMFPHP_DIR . "/core/amf/app/Gateway.php";
$gateway = new Gateway();
$gateway->disableDebug();
$gateway->setClassPath($AMFPHP_DIR . "/services/"); //使用するクラスの場所
//$gateway->setCharsetHandler("utf8_decode", "ISO-8859-1", "ISO-8859-1");
$gateway->enableGzipCompression(25*1024);
$gateway->service();
?>
そして、/path/to/amfphp/servicesフォルダを作成し、使用するクラスを設置します。
今回は、TestService.phpファイルをひとつ設置しました。
■/path/to/amfphp/services/TestService.php
<?php
define("LOG_FILE", "/path/to/log.csv");//書込み権限を設定
class TestService{
var $methodTable;
function TestService(){
/* //なくても動いてる。。。
$this->methodTable = array(
"loadData" => array("description" => "amfphp test data load",
"access" => "remote",
"arguments" => null
),
"writeData" => array("description" => "amfphp test data load",
"access" => "remote",
"arguments" => array("name_str", "body_str")
),
);
*/
}
/**
* ログファイル読み込み配列で返却
**/
function loadData() {
$fp = fopen(LOG_FILE, "r");
$res_list = array();
while(!feof($fp)) {
$buf = fgets($fp, 4096);
$d = explode(",", $buf);
$r_data = array(
"name" => $d[0],
"body" => $d[1]
);
$res_list[] = $r_data;
}
array_pop($res_list);//空データ削除
return array_reverse($res_list); //新しい順に返却
}
/**
* ログファイルに書込み(※CSV形式、カンマ除去)
**/
function writeData($name_str = "", $body_str = ""){
if ($name_str & & $body_str) {
$log = str_replace(",", "", $name_str) . "," . str_replace(",", "", $body_str) . "\n"; //カンマ削除
$fp = fopen(LOG_FILE, "a");
fputs($fp, $log);
fclose($fp);
}
$res_list = $this->loadData();
return $res_list;
}
}
?>
あとは、flash側から、amftest_gateway.phpへ使用するサービスのクラス名と、メソッドを指定することで、
flashからPHPのメソッドを実行できます。
■main.mxml(main.swf)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="top" backgroundColor="white" creationComplete="init();">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
[Bindable]
public var dataList:Array = []; // [{"name":"hoge", "body": "foo"}] 形式
private const GATEWAY_URL:String = "/sample/323/amftest_gateway.php";
/**
* 初期データ読み込み
*/
private function init():void {
var responder:Responder = new Responder(onResult, onFault);
var con:NetConnection = getCon();
con.call("TestService.loadData", responder);
}
/**
* データ送信
* */
private function sendMessage():void {
var nametxt:String = nameText.text;
var bodytxt:String = bodyText.text;
nameText.text = "";
bodyText.text = "";
var responder:Responder = new Responder(onResult, onFault);
var con:NetConnection = getCon();
con.call("TestService.writeData", responder, nametxt, bodytxt);
}
/**
* コネクション初期化
**/
private function getCon():NetConnection {
var time:Number = (new Date()).getTime();
var con:NetConnection = new NetConnection();
con.connect(GATEWAY_URL + "?time=" + time);
con.objectEncoding = ObjectEncoding.AMF3;
return con;
}
/**
* 成功
**/
private function onResult(etc:*):void {
if (typeof etc == "object") {
dataList = etc;
} else {
Alert.show("Error-2");
}
}
/**
* 失敗
**/
private function onFault(etc:*):void {
Alert.show("Error-1");
}
]]>
</mx:Script>
<mx:ApplicationControlBar dock="true">
<mx:Label data="名前:" />
<mx:TextInput id="nameText" width="10%" />
<mx:Label data="内容:" />
<mx:TextInput id="bodyText" width="80%" />
<mx:Button id="sendButton" label="送信" click="sendMessage();" />
</mx:ApplicationControlBar>
<mx:DataGrid id="dataGrid" dataProvider="{dataList}" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="name" headerText="名前" width="100" />
<mx:DataGridColumn dataField="body" headerText="内容" />
</mx:columns>
</mx:DataGrid>
</mx:Application>
データの変換等をすべてAMFPHPで処理してくれるので、簡単にPHPとFLASHでやり取りができます。