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 件のコメント:
コメントを投稿