Flash/AIRとPHP間でXMLのやりとりをするのに使った.
試行錯誤した結果,結局こんな感じでうまくいくことがわかった.
基本的に,URLRequestで送信データ,およびその設定を行い,
URLLoaderでリクエスト(送信),Completeイベントでphpからのレスポンスが帰ってくる仕組み.
package {
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.IOErrorEvent;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.utils.ByteArray;
/**
* ConnectPHP
* @auther kusamochi
*/
public class ConnectPHP extends EventDispatcher {
public static const COMPLETE:String = "complete";
public static const IO_ERROR:String = "io_error";
public static const PROGRESS:String = "progress";
public static const FAILED:String = "failed";
private var _urlRequest:URLRequest;
private var _result:XML;
private var urlLoader:URLLoader;
// コンストラクタ
public function ConnectPHP() {
}
// XMLの送信
public function sendAndLoad_XML(url:String, xml:XML):void {
// 送信するデータを設定
_urlRequest = new URLRequest(url);
_urlRequest.contentType = "text/xml";
_urlRequest.data = xml.toXMLString();
// データはPOSTで送信
_urlRequest.method = URLRequestMethod.POST;
// URL
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
// イベントリスナー登録
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlLoader.load(_urlRequest);
}
// データロード完了のイベントリスナー
private function completeHandler(event:Event):void {
urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
urlLoader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
// reusltに格納
try {
_result = new XML(event.target.data);
}
catch(error:TypeError) {
// イベントをブロードキャスト
dispatchEvent(new Event(FAILED));
return;
}
// イベントをブロードキャスト
dispatchEvent(new Event(COMPLETE));
}
// 送信中に一定間隔で発生するイベントリスナー
private function progressHandler(event:ProgressEvent):void {
// イベントをブロードキャスト
dispatchEvent(new ProgressEvent(PROGRESS));
}
// 送信エラーのイベントリスナー
private function ioErrorHandler(event:IOErrorEvent):void {
urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
urlLoader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
// イベントをブロードキャスト
dispatchEvent(new IOErrorEvent(IO_ERROR));
}
// 参照削除
public function deleteReference():void {
if(urlLoader) {
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlLoader.close();
}
_urlRequest = null;
_result = null;
}
// getter //////////////////////////////////////////////////////
// result
public function get result():XML {
if(_result) return _result;
else return null;
}
}
}
ポイントは,Content-typeを"text/xml"にして,xmlのStringを送信すること.
当初,Content-typeを"application/octet-stream"(バイナリデータの意)として,
XMLをBinaryArrayで送っていたけど,
それだと送信先でヘッダーに文字化けが起きる.
ちなみに,PHP側では,
$inputStr = file_get_contents("php://input");
$xml = simplexml_load_string($inputStr);
print "<result>";
// Flash側に送りたいデータをほげほげ
print "</result>";
というように,file_get_contents("php://input")で,
生データを丸ごと読みこんでPHPのXMLクラスに変換.
Flash側に送りたいXMLは,PHP自身にタグをprintすればいい.
0 件のコメント:
コメントを投稿