複数のファイルが読み終わったら実行する。 - PHPプロ!Q&A掲示板

2494

  • 100P

複数のファイルが読み終わったら実行する。

質問日時 / 2010年2月1日 12:00    回答数 / 16件

Questioner:  Tayax  このエントリーをはてなブックマークに追加 

キーワード / キーワードが設定されていません

複数の外部ファイルの読み込みが終わったら処理を実行しようとしています。

  1. <?php
  2. //読み込みファイル1
  3. $txt = "test.txt";
  4. $rsp = file_get_contents($txt);
  5.  
  6. //読み込みファイル2(json_decodeが終わったらOK)
  7. $dcs_json = file_get_contents("http://test/test.json");
  8. $dcs_obj  = json_decode($dcs_json,true);
  9.  
  10. //読み込みファイル3($rss->parse()が終わったらOK)
  11. require_once "XML/RSS.php";
  12. $rss =& new XML_RSS("http://test/test.rss");
  13. $rss->parse();
  14.  
  15. //3つの処理が終わったらOKと表示させたい。
  16. echo "OK";
  17. ?>

これら3つの処理が終わったら次の処理を実行させたい場合、
一番良い方法はどのようになるのでしょうか?

あともうひとつ、読み込みが一つであれば、以下のようにすれば良いのでしょうか?
(あまり良く分かっていないので。)
  1. $dcs_json = file_get_contents("http://test/test.json");
  2. $dcs_obj  = json_decode($dcs_json,true);
  3.  
  4. if($dcs_obj)
  5. echo "OK";

PHPを勉強し始めたばかりで基本的なところかもしれませんが、
教えていただけるとうれしいです。

よろしくお願いします。

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01shimix「読み込みが終わらないうちに、次の処理が実行される
┃┗A01-1Tayaxありがとうございます。 >「読み込みが終わらない
┗A02magicflute2関数の戻り値は、TRUE/FALSEになるとは限らないので、
 ┗A02-1Tayaxありがとうございます。 上記だと、 とりあえず、
  ┗A02-1-1magicflute2> とりあえず、jsonの判定だけで終わってますよね。
   ┗A02-1-1-1Tayaxありがとうございます。 今回は、上記でご指摘いただ
    ┣A02-1-1-1-1shimixうーん。。。 >$dcs_json = file_get_contents("ht
    ┃┗A02-1-1-1-1-1Tayax>$dcs_jsonが(取得に失敗して)falseなのにjson_deco
    ┃ ┗A02-1-1-1-1-1-1shimix詳細な説明をmagicflute2さんが書かれたので、重複す
    ┃  ┗A02-1-1-1-1-1-1-1Tayax>「関数の返り値に注目」 これが重要なのは分かりま
    ┃   ┣A02-1-1-1-1-1-1-1-1magicflute2以下が『どうチェックすればいいのか』という部分・・
    ┃   ┃┗A02-1-1-1-1-1-1-1-1-1Tayaxいろいろ細かいところまで、ありがとうございます。
    ┃   ┃ ┗A02-1-1-1-1-1-1-1-1-1-1Tayaxえっと、いろいろ拝見しました。 いろいろ参考にはな
    ┃   ┗A02-1-1-1-1-1-1-1-2shimixgetStreamDataは(本人じゃないので推測モードですが
    ┃    ┗A02-1-1-1-1-1-1-1-2-1Tayaxありがとうございます。
    ┗A02-1-1-1-2magicflute2関数の返り値に全く注目していないでしょ・・・。

回答一覧

並び替え:

A01 参考になった
answerershimix [2月1日 12:28]

「読み込みが終わらないうちに、次の処理が実行される」と考えられたのは何故でしょうか?非同期処理でない限りは「実行(読み込み)が終わるまで」は次の処理は実行されませんけど・・。

ちなみに読み込みが正しく行われたかのチェックは必ず行うべきです。file_get_contents()のあとで結果がfalseでないかをチェックしてください。

この意見に回答する

ツリーへ TOPへ

A01-1
replyerTayax [2月1日 12:54]

ありがとうございます。

>「読み込みが終わらないうちに、次の処理が実行される」と考えられたのは何故でしょうか?
これは、その処理が終わらなくても次々に処理を実行していくイメージを持っていました。
そんなことは無いのですね。

>file_get_contents()のあとで結果がfalseでないかをチェックしてください。
具体的なソースのイメージが分からないです。
実際に今回の例だとどのようになるのでしょうか?

この意見に回答する

ツリーへ TOPへ

A02 参考になった
answerermagicflute2 [2月1日 12:55] (最終編集:2月1日 13:13)

関数の戻り値は、TRUE/FALSEになるとは限らないので、
いつもif($x) の記述では済みません。

また、勉強中という事であればなおさら、判定部分を明確に記述しましょう。
  1. <?php
  2. $x !== ''
  3. $x === TRUE  // Booleanが返る時に
  4. $x === FALSE
  5. $x !== FALSE // mixedとFALSEが返る時に
  6. isset($x)
  7. count($x) > 0
  8. is_array($x)
  9. is_object($x)
  10. is_numeric($x)
  11. // etc.

以上を踏まえて、3つの処理の返り値の条件式を && で繋ぎ、判定します。

一工夫するなら、先頭で変数を初期化しておきましょう。
変数のスコープの関係で、変数が未定義とか言われますし、
色々と値を加工するし、
後々、ソースを追っかけるのが大変になります。
  1. <?php
  2. $rsp     = NULL// 別にNULLでなくてもいいです。
  3. $dcs_obj = NULL//
  4. $rss     = NULL//
  5. if ( ($tmp = json_decode('')) !== FALSE ) {
  6.   $dcs_obj = $tmp;
  7.   unset($tmp);
  8. }

追記:
そして上記を一つにまとめる。
  1. <?php
  2. /**
  3.  * getStreamData
  4.  * 
  5.  * @param  String        ファイル名
  6.  * @param  String        ファイルタイプ [plain | json | xml] 
  7.  * @param  Array         リクエストを送りたい時など
  8.  * @param  Boolean       [TRUE:HTTPから | FALSE:ファイルシステムから]
  9.  * @return mixed / FALSE
  10.  */
  11. //
  12. $rsp = $dcs_obj = $rss = NULL;
  13. if ( ($dcs_obj = getStreamData( 'hoge.json''json'$arrTRUE )) !== FALSE ):

この意見に回答する

ツリーへ TOPへ

A02-1
replyerTayax [2月1日 14:20] (最終編集:2月1日 14:25)

ありがとうございます。

上記だと、
とりあえず、jsonの判定だけで終わってますよね。。
同じようにして&&で繋ぎましょうということだと思うのですがちょっと分かりにくかったです。

それとgetStreamDataについて少し調べたのですが、有用な情報が見つけられませんでしたので、
上のコメントアウトを参照しているだけなのですが、(ありがとうございます。)
これはどのようなときに使えるものなのでしょうか?

もろもろ踏まえて、以下のようなものではダメなのでしょうか?
(これだと何か問題が起こりそうでしょうか?)
  1. <?php
  2. $rsp = $dcs_obj = $rss = NULL;
  3.  
  4. //読み込みファイル1
  5. $txt = "test.txt";
  6. $rsp = file_get_contents($txt);
  7.  
  8. //読み込みファイル2(json_decodeが終わったらOK)
  9. $dcs_json = file_get_contents("http://test/test.json");
  10. $dcs_obj  = json_decode($dcs_json,true);
  11.  
  12. //読み込みファイル3($rss->parse()が終わったらOK)
  13. require_once "XML/RSS.php";
  14. $rss =& new XML_RSS("http://test/test.rss");
  15. $rss->parse();
  16.  
  17. //3つの処理が終わったらOKと表示させたい。
  18. if($rsp!==FALSE && $dcs_obj!==FALSE && $rss!==FALSE) echo "OK";
  19. ?>

この意見に回答する

ツリーへ TOPへ

A02-1-1 参考になった
replyermagicflute2 [2月1日 14:46]

> とりあえず、jsonの判定だけで終わってますよね。
  1. <?php
  2. 1$dcs_json = file_get_contents("http://test/test.json");
  3. 2$dcs_obj  = json_decode($dcs_json,true);
  4. 3.  
  5. 4if($dcs_obj)
  6. 5echo "OK";
とあったので、“とりあえず”、jsonの判定だけ。
以下同じようにしてから、3つの判定をすればよいと言う事・・・。

  1. <?php
  2. if($rsp!==FALSE && $dcs_obj!==FALSE && $rss!==FALSE) echo "OK";
とするなら、
  1. <?php
  2. $rsp = $dcs_obj = $rss = NULL;
でなく、
  1. <?php
  2. $rsp = $dcs_obj = $rss = FALSE;
でしょ。
(スコープ関係ない状態じゃ、意味無いけど・・・)

この意見に回答する

ツリーへ TOPへ

A02-1-1-1
replyerTayax [2月1日 14:59] (最終編集:2月1日 14:59)

ありがとうございます。
今回は、上記でご指摘いただいた部分を修正して使ってみます。

  1. <?php
  2. $rsp = $dcs_obj = $rss = FALSE;
  3.  
  4. //読み込みファイル1
  5. $txt = "test.txt";
  6. $rsp = file_get_contents($txt);
  7.  
  8. //読み込みファイル2(json_decodeが終わったらOK)
  9. $dcs_json = file_get_contents("http://test/test.json");
  10. $dcs_obj  = json_decode($dcs_json,true);
  11.  
  12. //読み込みファイル3($rss->parse()が終わったらOK)
  13. require_once "XML/RSS.php";
  14. $rss =& new XML_RSS("http://test/test.rss");
  15. $rss->parse();
  16.  
  17. //3つの処理が終わったらOKと表示させたい。
  18. if($rsp!==FALSE && $dcs_obj!==FALSE && $rss!==FALSE) echo "OK";
  19. ?>

また分からないことがあればよろしくお願いします。
ありがとうございました。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1
replyershimix [2月1日 15:07] (最終編集:2月1日 15:09)

うーん。。。

>$dcs_json = file_get_contents("http://test/test.json");
>$dcs_obj  = json_decode($dcs_json,true);

$dcs_jsonが(取得に失敗して)falseなのにjson_decodeに引き渡すのはマズイんじゃないか(∴取得直後にチェックせよ)と書いたんですが・・

#json_decodeは失敗したら(falseじゃなくて)NULLが返るわけだし。

$rss->parse()も同様かと。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1
replyerTayax [2月1日 16:13]

>$dcs_jsonが(取得に失敗して)falseなのにjson_decodeに引き渡すのはマズイんじゃないか(∴取得直後にチェックせよ)と書いたんですが・・
このチェックのやり方はどのようになるのか最初に聞いています。

$dcs_json = file_get_contents("http://test/test.json");
if($dcs_json!==FALSE){
    $dcs_obj  = json_decode($dcs_json,true);
}
で良いのでしょうか?

>$rss->parse()も同様かと。
これについて同様というと?以下で良いのでしょうか?
require_once "XML/RSS.php";
$rss =& new XML_RSS("http://test/test.rss");
if($rss!==FALSE){
    $rss->parse();
}

よろしくお願いします。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1
replyershimix [2月1日 16:32]

詳細な説明をmagicflute2さんが書かれたので、重複するので書きませんでした。

magicflute2さんも↓で書かれているように「関数の返り値に注目」してください。どの時点で失敗したら、どういう値が返るのか(それをどうチェックすればいいのか)を意識してください。今回のスクリプトで一番エラーになりやすいのはhttp経由でデータを取得する部分です(相手サーバのあることなので)。この部分は必ずチェックしてください。

#どうすればいいかは、すでにmagicflute2さんが詳しく書かれているとおりです。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1
replyerTayax [2月1日 17:26]

>「関数の返り値に注目」
これが重要なのは分かりました。
>(それをどうチェックすればいいのか)
このあたりが分からないのです。

>#どうすればいいかは、すでにmagicflute2さんが詳しく書かれているとおりです。
これなんですが、上に書いているように、
>それとgetStreamDataについて少し調べたのですが、有用な情報が見つけられませんでしたので、
>上のコメントアウトを参照しているだけなのですが、(ありがとうございます。)
>これはどのようなときに使えるものなのでしょうか?
と、getStreamDataがどのような役割をしているのか、分からずじまいなので、
どのように使えば良いのか分からないのです。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1-1
replyermagicflute2 [2月1日 18:35] (最終編集:2月1日 18:42)

以下が『どうチェックすればいいのか』という部分・・・の一例。

様々な値を返す処理群を、どうやって扱いやすくすればいいのか?
一つの案として、
正常な値(文字列・配列等)かFALSEを返す様なルールにすればよさそうです。

でも、値を取得して終わりじゃなく、きっと、色々加工するでしょ?
だから、だらだらと長いソースにならない様に、関数化する事にします。
  1. <?php
  2. function func_a() { return 'X'}
  3. function func_b( $fpath )
  4. {
  5.   $retval = array();
  6.   // json_decodeの返り値がNULLだった時、そのままreturnは扱いづらい
  7.   // NULLならFALSEを返す様に変更・・・という事にする
  8.   if ( is_null( $tmp = json_decode( $fpath ) ) ) {
  9.     return FALSE;
  10.   } else {
  11.     // 何らかの処理をする部分
  12.     if ( isset($tmp->id$tmp->name) ) {
  13.       $retval['id']   = $tmp->id;
  14.       // JSONでは、マルチバイトはURLエンコードするのがお約束
  15.       // だからURLデコード
  16.       $retval['name'] = urldecode( $tmp->name );
  17.       return $retval;
  18.     }
  19.   }
  20.   return FALSE;
  21. }
  22. function output($str){return htmlspecialchars($strENT_QUOTES);}
  23.  
  24. // 最後の『}』が無いので、JSON形式ではありません。
  25. $json = '{"id":"A001", "name":"%E9%88%B4%E6%9C%A8%E4%B8%80%E9%83%8E"';
  26. // こっちはJSON形式(コメントアウトを外してみよう)
  27. //$json = '{"id":"A001", "name":"%E9%88%B4%E6%9C%A8%E4%B8%80%E9%83%8E"}';
  28.  
  29. $a_retval = func_a();
  30. $b_retval = func_b( $json );
  31. // 返り値をチェックしてみる
  32. echo '[func_aの返り値]';
  33. var_dump($a_retval);
  34. echo '[func_bの返り値]';
  35. var_dump($b_retval);
  36. // 返り値は、文字列か配列、もしくはFALSEとなる様に統一
  37. if ( $a_retval !== FALSE && $b_retval !== FALSE ) {
  38.   echo "結果はOK<br />";
  39.   echo output($a_retval).'<br />';
  40.   echo output($b_retval['id'].' : '.$b_retval['name']).'<br />';
  41. } else {
  42.   echo '結果はNO';
  43. }


getStreamData()は、自分が銘々したものですので、検索してもでてこないでしょう。

これは、上記ソースの発展形で、
複数の関数群を一つの関数にまとめて処理しようという案です。
また、関数の実行順序を指定するといった発展も可能でしょう。

※別に無視していいです。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1-1-1
replyerTayax [2月1日 19:30]

いろいろ細かいところまで、ありがとうございます。

ただ自分の知識が追いついてないようです。
もう少しいろいろみてからまた返信させていただきます。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1-1-1-1
replyerTayax [2月2日 00:39]

えっと、いろいろ拝見しました。
いろいろ参考にはなりました。
ありがとうございました。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1-2
replyershimix [2月1日 18:38] (最終編集:2月1日 18:39)

getStreamDataは(本人じゃないので推測モードですが)、同じような処理なのでそういう名前の関数を作って

  1. * @param  String        ファイル名
  2. * @param  String        ファイルタイプ [plain | json | xml] 
  3. * @param  Array         リクエストを送りたい時など
  4. * @param  Boolean       [TRUE:HTTPから | FALSE:ファイルシステムから]
  5. * @return mixed / FALSE

を渡して結果を受け取るようにしてはどうですか?・・という提案だと思います。渡すパラメータ(引数)が4つですね。

(追記)
あ、ご本人から説明がありましたね↑。余計なことを書いてしまったかな(汗

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1-2-1
replyerTayax [2月1日 19:37]

ありがとうございます。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-2
replyermagicflute2 [2月1日 15:24] (最終編集:2月1日 15:28)

関数の返り値に全く注目していないでしょ・・・。

・この3つの処理のエラー処理をする、
・または、それを一つの関数でまとめ、返り値を推測できるものにする。
これらをする前提で、「変数を初期化したら」と言ったんですよ?

エラー処理等の記述を追加した時に、
変数が未定義 となったら困るだろうから・・・。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
PHPのHTML埋め込み記述について
 このエントリーをはてなブックマークに追加 
A
$_POST["data"] == "男" ? $val = "checked" : $val = "" ; の意味は以下と同じです。 if($_POST["data"] == "男"){ $val = "checked; } e...

>>続きを読む

kende様のご指摘通り、三項演算子を使用する際には、コードの複雑度などを考慮する必要がありますね。書きやすさと共に可読性も追求したいところですね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)