人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

ActionScript3.0とPHPと連携したXMLデータの読み込みについて質問があります。ActionScriptからPOSTした文字列を参照してDBのデータをXMLファイルとして保存することは出来ましたが、ActionScript側の受け取りで「TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。」というエラーがはかれてしまい… XMLデータに変換できなくて困っています。解決の方法をご存知の方がいらっしゃいましたら、ご教授いただけると助かります。よろしくお願いします。
失敗スクリプト ⇒ http://www.kinsekitei.com/prototype/sample.html

●質問者: DrArabes
●カテゴリ:コンピュータ
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● romer
●200ポイント ベストアンサー

スクリプト読みました。現状だとphpからXMLとしてのレスポンスとしては出力されていません。

file_put_contents("color.xml",$dom->saveXML());
urlencode($dom);
echo ($dom);

この部分ですが、これはファイルに保存した後に

DOMDocumentオブジェクトをurlencodeし出力しようとしています。


これは私の環境ではfatal errorが出ましたので、エラーが出てないか確認してみてください。

この部分を書き換えるとすれば

$dom->save('color.xml');

header("Content-Type: text/xml; charset=utf-8");
echo $dom->saveXML();

でOKです。


あとは余談ですが

while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
foreach($array as $val){
$data_list[$ii][$val] = $row[$val];
}

$ii++;
};

ここの部分は

while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
 $data_list[] = $row;
}

このように簡略化する事が可能です。

理由はfetchmodeがassocなので、DBのキーがそのまま使える為です。


また最終行で

mysql_close($conn);

とされていますがこれは不要ではないですか?

仮に接続を切りたい場合は

fetchrowをしたループの後に

$db->disconnect()

とすれば良いと思います。


それと、以前の質問への回答に

もっと容易にXMLを出力する方法を記載してあります


DrArabesさんのコメント
返信ありがとうございます。とても丁寧な解説で分かりやすかったです。クラスにしていたPOSTしてXML受け取りをタイムラインにパッケージを使わない方向で解決はしましたが…クラスを使用した場合にTYPE ERROR#1009がロード終了前に戻り値にNULLを告げてきます。原因がまったく分かりません。解決の糸口をご存知でしたら、ご教授いただけると助かります。 以下エラーするクラスを記述しました。(ドキュメントクラスではないです。) package sample{ import flash.events.EventDispatcher; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.URLVariables; import flash.system.System; import flash.events.Event; import flash.events.IOErrorEvent; import flash.utils.escapeMultiByte; public class POST_XMLloader extends EventDispatcher { public static const LOAD_COMPLETE:String = "load_complete"; public static const LOAD_ERROR:String = "io_error"; var Xloader:URLLoader; public var error_message:String; var my_url:String; var xml:XML; //コンストラクタ function POST_XMLloader(url:String, array:Array, isUnicode:Boolean){ //URLLoader作成 my_url = url; var Xloader = new URLLoader(); Xloader.addEventListener(Event.COMPLETE, onXMLloaded); Xloader.addEventListener(IOErrorEvent.IO_ERROR, ioError); //URL var url_request:URLRequest = new URLRequest(url); url_request.method = URLRequestMethod.POST; //POST SET var url_variables:URLVariables = new URLVariables(); for ( var st:String in array ){ url_variables[ st ] = array[ st ]; } url_request.data = url_variables; //Unicode以外ならばtrue System.useCodePage = ! isUnicode; //PHPを実行(読み込み) Xloader.load(url_request); trace(Xloader.data); ← ここでNULLを告げられます。 } //PHPの実行が完了したとき function onXMLloaded(event:Event):void { try { //XMLオブジェクトに変換する var xml = new XML(Xloader.data); //カスタムイベントを配信する dispatchEvent(new Event(LOAD_COMPLETE)); trace("読み込み完了"); //XMLデータをセットする setTopics(xml); } catch (err:TypeError) { trace(Xloader); trace( "XML変換エラー"); trace(err.message); error_message = "XML変換エラー[ "+my_url + "]\n" ; error_message += Xloader.data; dispatchEvent(new Event(LOAD_ERROR)); } } function ioError( event:Event ):void { error_message = "ioError---\n -url:"+my_url + "\n" ; dispatchEvent(new Event(LOAD_ERROR)); } //XMLオブジェクトを返す(他のクラスからのアクセスに対応) public function getXML():XML{ return xml; } }

DrArabesさんのコメント
以下.flaタイムラインに記述したASです。 import sample.POST_XMLloader; this.addEventListener(Event.ENTER_FRAME,XMLloader); function XMLloader(event:Event):void{ var PostURL = "color.php"; var array = new Array(); array["function_name"] = "color"; array["trigger_name"] = "clear"; var Xloader: POST_XMLloader = new POST_XMLloader( PostURL, array , false ); Xloader.addEventListener( POST_XMLloader.LOAD_COMPLETE, onComplete ); Xloader.addEventListener( POST_XMLloader.LOAD_ERROR, ioErrorHandler ); this.removeEventListener(Event.ENTER_FRAME,XMLloader) //PHPの実行が完了したとき } function onComplete(event:Event):void { trace("└compleate:"); xml = new XML(); var xml:XML = event.currentTarget.getXML(); //読み込み終わったXMLの取得 trace(event.currentTarget.data); } function ioErrorHandler( event:Event ){ var err:String =event.currentTarget.error_message; trace("└ioErrorHandler:"+err); }

DrArabesさんのコメント
上記のコンビネーションではエラーのままでしたが…クラスを使わず、下記のように.flaタイムラインに直接書いたらエラーは出ませんでしたが…汎用性にかけるので、クラスを使用した方法でPOST&XMLリーディングを行いたいのですが…未知エラー#1009に悩まされています。エラー内容を調べてるうちに、リーディングが終わらないうちに、ロードしている可能性が高いと推測しています。NULLになるのは何故なのでしょうか?そんな事は無いと思いますが…クラススクリプトは値を保持できないのですか??まったく解決方法が見えなくいます。 var array = new Array(); var url_variables:URLVariables = new URLVariables(); var url_request:URLRequest = new URLRequest("color.php"); var loader:URLLoader = new URLLoader(); array["function_name"] = "color"; array["trigger_name"] = "red"; for ( var st:String in array ){ url_variables[ st ] = array[ st ]; } url_request.data = url_variables; url_request.method = URLRequestMethod.POST; url_request.data = url_variables; //PHPを実行(読み込み) loader.addEventListener(Event.COMPLETE, onXMLloaded); loader.load(url_request); //PHPの実行が完了したとき function onXMLloaded(event:Event):void { trace("└compleate:"); var xml = new XML(); xml = event.target.data;//読み込み終わったXMLの取得 } function ioErrorHandler( event:Event ){ var err:String =event.currentTarget.error_message; trace("└ioErrorHandler:"+err); }

DrArabesさんのコメント
追記)クラス内で変数arrayのObject定義が間違ってましたので…Nullが帰ってきたと判明しました。

DrArabesさんのコメント
class内の定義と.flaタイムラインを下記のように書き換えました。PHPファイル内でのPOST変数の受け取りと、XMLファイルの書き出しは成功しましたが…依然と#1009 NUllエラーがはかれています…なぜなのでしょう?? どなたかご教授ください。よろしくお願いします。 //クラス定義 var url_variables:URLVariables = new URLVariables(); for ( var key:String in postArray ){ url_variables[ key ] = postArray[ key ]; } url_request.data = url_variables; //.fla var array:Array = new Array(); array["function_name"] ="color"; array["trigger_name"] = "red";

DrArabesさんのコメント
trace(postArray["function_name"]);としたら「color」と出力されましたが、url_variablesとpostArrayをtrace()したら「undefined」でした。なぜPHP側でPOSTできてXMLファイルに保存できたのに…AS内でNULLが帰ってXMLが帰ってこないでしょう?ご存知の方がいましたら、ご教授ください。よろしくお願いします。

romerさんのコメント
trace(postArray["function_name"]);としたら「color」と出力されましたが、url_variablesとpostArrayをtrace()したら「undefined」でした。なぜPHP側でPOSTできてXMLファイルに保存できたのに…AS内でNULLが帰ってXMLが帰ってこないでしょう?ご存知の方がいましたら、ご教授ください。よろしくお願いします。 2011/10/26 07:56:09 Nullが告げられると書かれてる場所でNullが出てしまうのは、推測通りまだ読み込みが終わってないからですね。 ロードが完了したらEvent.COMPLETEが発生し、初めてテキストデータとして取得できます。 非同期処理を行う時にある、一般的なよくある間違いの1つだと思います。 >| Xloader.load(url_request); // 非同期のロードリクエスト依頼 // ←loadとtraceの間は非同期処理なのでロード完了するまで待機する事はありません trace(Xloader.data); // ロードが完了していないのに出力しようとしているのでNULL |< あと、テストはPHPではなく、既に出力してあるxmlファイルを直接指定して行うと 問題の切り分けがしやすいと思います。

DrArabesさんのコメント
クラスに記述したロード完了後のスクリプトで読み込みが失敗してNULLがはかれています。PHPからのXMLが読み込めてない…NULLという状態になってしまいます。何故なのでしょうか? //実行が完了したとき function onXMLloaded(event:Event):void { try { //XMLオブジェクトに変換する var xml = new XML(Xloader.data); //カスタムイベントを配信する dispatchEvent(new Event(LOAD_COMPLETE)); trace("読み込み完了"); //XMLデータをセットする setTopics(xml); } catch (err:TypeError) { trace( "XML変換エラー"); ← ここでエラーと#1009がはき出されます。 trace(err.message); error_message = "XML変換エラー[ "+my_url + "]\n" ; error_message += Xloader.data; dispatchEvent(new Event(LOAD_ERROR)); } }

DrArabesさんのコメント
XMLを直接呼んでも、同様のエラーが出ました。読み込みが完了していないのに、event.COMPLEATEを発生させたとは考えにくいので…POSTした戻りの値のXloader.dataがNULLと言うことが原因でしょうか?

romerさんのコメント
これで試してみてもらえます? >|actionscript| function onXMLloaded(event:Event):void { try { var xml = XML(Xloader.data); trace("読み込み完了",event); setTopics(xml); } catch (err:TypeError) { trace(err.message); } } ||<

romerさんのコメント
改めて見直しました。重要な部分がありました。 >|actionscript| public class POST_XMLloader extends EventDispatcher { var Xloader:URLLoader; //コンストラクタ function POST_XMLloader(url:String, array:Array, isUnicode:Boolean){ //URLLoader作成 my_url = url; var Xloader = new URLLoader(); } } ||< と記述されてますが、これだとPOST_XML_loaderのスコープはクラスのスコープではなく コンストラクタ内のローカル変数になり、ローカル変数扱いになった場合 classに存在するXloaderプロパティはnullのままになります。 onXMLloadedではclassのXloaderプロパティを参照しているため、 null値であるXloaderプロパティにアクセスした時に1009エラーが出ます。 ちなみにですが >|actionscript| var xml = XML(Xloader.data); ||< を >|actionscript| var xml = XML(event.currentTarget.data); ||< とすれば、Xloaderプロパティは共有しなくてすみます。

DrArabesさんのコメント
丁寧な解説、お手数かけて恐縮です。記述を試してみましたが…依然とエラーが出現しています。何故なのでしょう?

DrArabesさんのコメント
現在のサブクラスの定義 package kinsekitei_Pg{ import flash.events.EventDispatcher; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.URLVariables; import flash.system.System; import flash.events.Event; import flash.events.IOErrorEvent; import flash.utils.escapeMultiByte; public class POST_XMLloader extends EventDispatcher { public static const LOAD_COMPLETE:String = "load_complete"; public static const LOAD_ERROR:String = "io_error"; var Xloader:URLLoader; public var error_message:String; var url:String; var xml:XML; public class POST_XMLloader extends EventDispatcher { //コンストラクタ public function POST_XMLloader(url:String, postArray:Array, isUnicode:Boolean){ //URLLoader作成 my_url = url; var Xloader = new URLLoader(); Xloader.dataFormat = URLLoaderDataFormat.TEXT; Xloader.addEventListener(Event.COMPLETE, onXMLloaded); Xloader.addEventListener(IOErrorEvent.IO_ERROR, ioError); //URL var url_request:URLRequest = new URLRequest(url); url_request.method = URLRequestMethod.POST; //POST SET var postArray = new Array(); var url_variables:URLVariables = new URLVariables(); for ( var key:String in postArray ){ url_variables[ key ] = postArray[ key ]; } url_request.data = url_variables; //Unicode以外ならばtrue System.useCodePage = ! isUnicode; //PHPを実行(読み込み) Xloader.load(url_request); } //実行が完了したとき function onXMLloaded(event:Event):void { try { var xml = XML(event.currentTarget.data); trace("読み込み完了",event); setTopics(xml); } catch (err:TypeError) { trace(err.message); } } function ioError( event:Event ):void { error_message = "ioError---\n -url:"+my_url + "\n" ; dispatchEvent(new Event(LOAD_ERROR)); } function setTopics(xmldata:XML):void{ for each ( var dat:XML in xmldata.stone ){ trace("id :"+ dat.@id); trace("stock:"+ dat.stock); trace("name:"+ dat.name); trace("category:"+ dat.category); trace("prod_num:"+ dat.prod_num); trace("type:"+ dat.type); trace("type_linker:"+ dat.type_linker); trace("color:"+ dat.color); trace("shape:"+ dat.shape); trace("shape_size:"+ dat.shape_size); trace("size:"+ dat.size); trace("rank:"+ dat.rank); trace("priority:"+ dat.priority); trace("price:"+ dat.price); trace("discription:"+ dat.discription); trace("image01:"+ dat.image01); trace("image02:"+ dat.image02); trace("image03:"+ dat.image03); } } //XMLオブジェクトを返す(他のクラスからのアクセスに対応) public function getXML():XML{ return xml; } } }

DrArabesさんのコメント
同様に#1009が出ている状況です。

DrArabesさんのコメント
無事にクラス内部でのXMLの取得に成功しました。ありがとうございます。ちなみに.fla側では前回からのエラー#1009 Nullが出現し、targetができなくて困っています。公にXMLデータを参照でき格納された変数にすることはできないのでしょうか…
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ