質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

311閲覧

「phpのif文」について、phpはどの順番で解釈し作業をしていくのか?

tajix_japan

総合スコア132

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/03/29 22:00

編集2019/03/29 23:04

下記の3ケ所の自社サーバーにcsvファイルを多数を保管しています。

http://100.example.com/aaa.csv
http://111.example.com/bbb.csv
http://122.example.com/bbb.csv

上記のファイルを、http://example.com/hyoji.php?csv=xxx  から読みに行き、表示させるphpを組んでいます。

3つのcsv保管サーバーにあるcsvファイルは無数にあり、100サーバーだけで保管できているもの、111サーバーだけで保管できているもの、122サーバーだけで保管できているもの、全てのサーバーに存在するもの(これが殆ど)が混ざっております。

やりたいこと
http://example.com/hyoji.php?csv=xxx としたときに、該当のcsvファイルを探しだして表示するphpを組みました。
まずは、100のサーバーを探し、100のサーバーになかった場合、自動的に111のサーバーにあるかを探し、なかったら122のものをさらに探し表示ます。

それが下記のphpです。

php

1<?php 2$csv= htmlspecialchars($_GET['csv'], ENT_QUOTES, "UTF-8"); 3 4$path100 = 'http://100.example.com/<?php echo $csv ?>.csv'; 5$array100 = get_headers($path100); 6 7$path111 = 'http://111.example.com/<?php echo $csv ?>.csv'; 8$array111 = get_headers($path111); 9 10$path122 = 'http://122.example.com/<?php echo $csv ?>.csv'; 11$array122 = get_headers($path122); 12 13$word100 = file_get_contents('http://100.example.com/csv_hyoji.php?csv=<?php echo $csv ?>'); 14$word111 = file_get_contents('http://111.example.com/csv_hyoji.php?csv=<?php echo $csv ?>'); 15$word122 = file_get_contents('http://122.example.com/csv_hyoji.php?csv=<?php echo $csv ?>'); 16 17 18// ファイルが存在するかチェックする 19if ((strpos($array100[0],'OK')) 20{ 21print($word100); 22} 23elseif ((strpos($array111[0],'OK')) 24{ 25print($word111); 26} 27elseif ((strpos($array122[0],'OK')) 28{ 29print($word122); 30} 31?> 32 33

懸念していること

上記のphpには、file_get_contentsが3つあります。
全てのcsvサーバーに該当のcsvファイルが存在した場合、通信量が3倍になることを懸念し、質問いたします。

phpの特性上、上から順番に読み込んでいくものなのか?

今回のphpでは

$word100 = file_get_contents('http://100.example.com/csv_hyoji.php?csv=<?php echo $csv ?>'); $word111 = file_get_contents('http://111.example.com/csv_hyoji.php?csv=<?php echo $csv ?>'); $word122 = file_get_contents('http://122.example.com/csv_hyoji.php?csv=<?php echo $csv ?>');

と事前に書いてあり、そのあとで下記のようなif文での表示をさせるようにしています。

if ((strpos($array100[0],'OK')) { print($word100); } elseif ((strpos($array111[0],'OK')) { print($word111); } elseif ((strpos($array122[0],'OK')) { print($word122); }

【最初の質問】
(1)
上記の場合、「file_get_contents」が事前にある関係上、「if文」が来る前にあらかじめ「file_get_contents」を読み込んでしまってから(通信してしまってから)、if文を解釈して適切に表示するものなのか?
(2)
それとも、php上で、「file_get_contents」があったとしても、それをprintなりechoなりで表示の指示が出るまでは「file_get_contents」は行わず、printなりechoなりで表示の指示が出た後に「file_get_contents」を行い、通信を開始するものなのか

が最初の質問です。

よろしくお願いいたします。

【次の質問】
もし上記の(1)と(2)の選択の中では(2)が正解だった場合、次の質問として下記があります。

if文でcsvファイルの存在を確認して($arrayで200 OKが返ってくるかの確認)、OKが返ってきたらそのサーバーのcsvファイルを表示することになっています。
今回のif文では、最初のifで100のサーバーを探し、elseifで111のサーバーを探し、次のelseifで122のサーバーを探すことになります。
当方としては、「最初のifで100のサーバーを探した末csvファイルが見つかったら、次のelseif以降の111&122への通信はして欲しくありません。

質問です。

phpのif文は、

if ((strpos($array100[0],'OK')) { print($word100); } elseif ((strpos($array111[0],'OK')) { print($word111); } elseif ((strpos($array122[0],'OK')) { print($word122); }

となっていた場合、最初にOKが出てきた時点で、次の作業に移らず(通信をせず)打ち切るということで問題ありませんでしょうか?

普通に考えると次の処理には移らず終了するものとは思いますが、
「実はPHPというものは、全てを読み取った後(上記では100、111、122のサーバーとの通信を全て終了した後)に、あらためてIF文を解釈してprintするものだ」ということがないかを確認する次第です。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

回答ではないです
仕様の詳細が分かりませんが一般論として、都度存在確認を「ファイル全体を取る」という形で実施するのはムダです。

普通は以下を検討します。
・サーバ管理者に、ファイルの存在箇所一覧をもらう → DB に保存箇所を投入
・一定時間毎にファイルの存在確認を実施 → DB に保存箇所を投入
・都度「ファイルの存在確認」をする場合は、header のみで存在を確認する

投稿2019/03/29 23:45

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tajix_japan

2019/03/30 00:54

DBの活用のご指摘、ありがとうございます。 DB活用についても検討してみます。 ありがとうございました。
guest

0

通信の有無の話をするのであればPHPはサーバーサイドの言語なので、
phpを実行させた時点で通信はしています。
となると前提崩れるような気がしますが、いかがでしょうか。

あとは消費メモリの問題ですが、

php

1$word100 = file_get_contents('http://100.example.com/csv_hyoji.php?csv=<?php echo $csv ?>'); 2$word111 = file_get_contents('http://111.example.com/csv_hyoji.php?csv=<?php echo $csv ?>'); 3$word122 = file_get_contents('http://122.example.com/csv_hyoji.php?csv=<?php echo $csv ?>');

(get_headers()もですが。)
file_get_contents()時点でファイルへのアクセスは発生しているので、
メモリは増え続けていると思います。
メモリ量を観測してください。

ちなみに例示のif文を分解するとこうですよね。

php

1if (条件A) { 2 3} elseif (条件B){ 4 5} elseif (条件C){ 6 7}

file_get_contents()時点でアクセスしたファイルの情報すべてを文字列取りこんでますから、
あとはその文字列と事前にget_headers()で取得した配列の処理になります。
上から順に1つずつ比較。条件が満たされたらif文は終了。
※elseなどでつながっていたら満たされるまで順に比較します


蛇足:
htmlspecialchars()はhtml出力時に使うものであってパラメータ取得の時に使うものではありません。
file_get_contents()のファイル取得先URLに利用していることからurlencode()の方が妥当。

投稿2019/03/29 23:10

m.ts10806

総合スコア80842

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tajix_japan

2019/03/29 23:18

ありがとうございます。 ご丁寧なご回答ありがとうございました。今まで作ったphpも含め見直すものが多いと痛感致しました。 また、「urlencode()の方が妥当」とのご指摘、大変勉強になりました。 本当にありがとうございました。 申し訳ございませんが、回答を頂く1分ほど前に、3分早くご回答いただいた方にベストアンサーを差し上げてしまいました。 大変申し訳ございませんがご了承願います。 ご丁寧な回答でお時間をお取りいただいたこと、深く感謝申し上げます。
m.ts10806

2019/03/29 23:26

少し検証したり蛇足部分書いてたら時間かかってしましました。 いずれにしてもphpマニュアルによる機能確認と検証は必要に思います。 解決されたようで何よりです。
tanat

2019/03/29 23:34

[通信の有無]は、PHPへのアクセスでは無く、file_get_contents()によって発生する通信の事かと思いますよ。 if文の有無によってfile_get_contents()の実行タイミングが最適化されるのでは?という質問だと解釈しました。
m.ts10806

2019/03/29 23:41

tanatさん 私も回答作ってる途中で、file_get_contents()のファイル取得先が別URLであることに気づいて 若干方向転換しました。(で「アクセス」と表現しました) いずれにしても今回のやり方だとifでは対応できませんね。 get_headers()の結果だけで判断する感じでしょう。
tanat

2019/03/30 00:07

> mts10806さん 補足ありがとうございます。理解しました。 > get_headers()の結果だけで判断する感じでしょう。 同意です。
tajix_japan

2019/03/30 00:44

tanat様、mts10806様 ベストアンサー後もいろいろお気遣いくださり、本当にありがとうございました。深く御礼申し上げます。
guest

0

ベストアンサー

【最初の質問】
(1)
上記の場合、「file_get_contents」が事前にある関係上、「if文」が来る前にあらかじめ「file_get_contents」を読み込んでしまってから(通信してしまってから)、if文を解釈して適切に表示するものなのか?

YES

これは実際に検証してみればわかることなので、
検証方法を考えて検証してみる事を習慣づけると良いです。

今回の件だと、ブレークポイントを仕掛けられるデバッガを使うと簡単に確認できますし、
デバッガを使わなくても、ifの前でファイル内容が格納されている変数をvar_dump()すればifで評価される前に読み込みが終わっていることを確認できます。

投稿2019/03/29 23:03

tanat

総合スコア18711

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tajix_japan

2019/03/29 23:07

ありがとうございます。助かりました。このままでは無駄な通信が発生するため別の方法を考えます。 また、ご指導ありがとうございました。今後のスキル向上に役立たせていただきます。 深く感謝申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問