- ベストアンサー
include を使用していてちょっと疑問に
外部ページを読み込んでそれを編集しようと、includeを試しに使ってみたのですが、予期せぬ結果になり、少し疑問に思いましたので投稿させていただきました。 <? $data = include ('test/01.html'); ?> この状態でecho $data; としていないのに01.htmlが表示されてしまうのはどうしてなのでしょうか? この時点ではまだ 変数に代入しているだけですよね。こういったケースは他の関数でも良くあるのでしょうか? そんなもんなんだろう、と覚えてしまうことはできるのですが、ちょっと気になりました。 ご存知のかたおられましたらご教授していただけるとうれしく思います。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
読み返して気がつきましたが、質問者さんは関数の戻り値を変数に代入する行為を、関数を変数に代入する行為だと考えておられないでしょうか。 例えば、 $var = foo(); function foo() { echo "aaa"; } という処理があったとします。 これはfoo関数の処理を変数$varに代入するのではなく、foo関数の「実行結果」を$varに代入するという意味になります。 ですので、$var=foo();を行った時点で、foo関数の中が実行されます。
その他の回答 (5)
- matchasoft
- ベストアンサー率54% (20/37)
PHP言語はPHPの開始タグから終了タグまでをプログラムとして実行し、それ以外は直接出力するという動きをします。 例えば、PHPファイルに echo "aaa"; とのみ記述すると、画面に「echo "aaa";」と表示され、PHPファイルに <?php echo "aaa"; ?> と記述すると画面に「aaa」と表示されるはずです。 前者はHTMLモードであるため直接文字が画面に出力され、後者はタグで囲まれているため、文字列をプログラムとして認識しているためです。 さて本題ですが、マニュアルにはincludeの説明として以下のような説明が書かれています。 『ファイルが読み込まれるときには、読み込まれるファイルの先頭で PHPモードを抜けてHTMLモードになり、最後に再びPHPモードに戻ります。このため、読み込むファイル中のPHPコードとして実行する必要がある コードは、有効なPHPの開始タグおよび終了タグで括る必要があります。』 これがNo.2さんの仰っていることです。 このため、PHPタグで囲っていない文字列があるファイルをincludeした場合、includeした時点でタグで囲まれていない部分が出力されることになります。 ここで勘違いしないでいただきたいのですが、この「出力」は画面に直接出力されるということです。これは変数に代入するという行為とは関係ありません。 次にNo.4の回答にありますechoの件です。 echoは、呼び出した際に後に続く文字列を画面に表示するという動きを行います。このためechoが呼ばれた時点で画面に文字列が表示されます。これは戻り値とは関係ありません。 文字列を関数の戻り値としたい場合は、echoではなくreturnを使います。
- yambejp
- ベストアンサー率51% (3827/7415)
すでに#1で回答したのが正しいやり方なので、なぜincludeで 変数に代入するなんてわけのわからないことに固執して、 それができると思い込んでいるのか不思議でなりません。 仮に以下をなんとかするとしても $data = '<!-- '. include(test/01.html) .' -->'; という書式でまずincludeするなら引数(?)は文字列になります。 最低限 include('test/01.html')ですね。 前回ちょっと書きましたがincludeは関数ではなく構文です。 なので別に括弧を必要せず括弧は無視されます。仮に $data = '<!-- '. include('test/01.html') .' -->'; というスクリプトはどう評価されるかと言えば、 まず$dataに「<!-- 1」が代入されます。文字列+includeの戻り値1。 で、includeは「test/01.html -->」というファイルを開こうとします。 (単純に「test/01.html」と「 -->」という文字列をつなぐだけですから) 換言すればinclude構文に文字列はつなげない・・・と考えればよいかと。 結局この構文ですと「test/01.html -->」というファイルがないため ファイルのオープンエラーになるわけです。 もしこれを実行したいのであれば、ob関数をつかってバッファリングして、 変数に流し込んでください。 <?PHP ob_start(); include("test/01.html"); $data=ob_get_clean(); print '<!-- '. $data .' -->'; ?> $dataに代入しなくていいなら簡単にこんな感じ。 <?PHP print "<!--"; include("test/01.html"); print "-->"; ?> しつこいようですが「思い込み」を捨ててPHPの構文に あわせた書き方をしてください。 マニュアルを読んだとかいていますが、includeで変数になんて 代入していませんよね? 質問者さんがやっていることは $data=print "test"; のようなことです。そろそろご自身の間違いに気がついてください。 PHPは非常にロジカルで理路整然と処理がされているので 理解さえすればそれほど疑問がでるはずがありません。 >制御構造について述べられていますが、何か質問に関係あります >でしょうか?よくわかりませんでした。 せっかくリンクまで貼ってあるのに理解いただけないのはまことに 残念です。制御構造のなかにincludeがありませんでしたか?
補足
>すでに#1で回答したのが正しいやり方なので、なぜincludeで >変数に代入するなんてわけのわからないことに固執して、 >それができると思い込んでいるのか不思議でなりません。 ??? おっしゃっている意味が良くわからないのですが、なぜ回答者さんは私が「わけのわからないことに固執して、それができると思い込んでいる」と思い込んでいるのでしょうか?質問の意図は#1のお礼で述べたとおりです。質問の意図は外部ファイルを編集する方法を知るのが目的ではありません。phpという言語、もしくはもっと大まかなプログラミングの考え方になれるために理解を深めようとしているだけですよ。不快に感じたらすみません。 >前回ちょっと書きましたがincludeは関数ではなく構文です。なので別に括弧を必要せず括弧は無視されます。 ありがとうございます。これで何となくわかったような気がするのですが、for, while, foreach などはカッコ内に値がないと動かないのではないでしょうか? でもphpって思った以上に結構ややこしいですね。includeが関数だと思っていた理由に結構メジャーなページでそう説明されています。購入した初心者用の本にもなんとinclude () and recuire () functionsと載っています(笑)。(一応、function:関数) http://www.w3schools.com/php/php_includes.asp >制御構造のなかにincludeがありませんでしたか? あ。。 「これはだからいったいどうしたのだろうか」、と思っていました^^。つまり関数じゃないよ、と暗に提示してくれていたのですね。それならそうと教えていただければ助かりました。 で、本題に移りたいのですが、前回の補足にも書きましたが、 $data = htmlecho(); function htmlecho () { echo "<html><head></head><body>Hello World!</body></html>"; } これはincludeが行う処理とよく似ていると思うのですが、いったいなぜ、$dataに代入した時点で 関数内のコードが処理されてしまうのでしょうか?
- yambejp
- ベストアンサー率51% (3827/7415)
制御構造など基本構文については学習してからのほうがよろしいかと。 includeで代入ができるなど「思い込み」に他なりません。 プログラミング言語の場合、前はこうだったからこれでもこうだ という思い込みをいかに払拭するかが肝になってくるので、 いろいろ試しながら理解を深めていくひつようがありますね。 とりあえずオンラインマニュアルは必読だと思ってください。 http://www.php.net/manual/ja/language.control-structures.php http://www.php.net/manual/ja/function.include.php
お礼
う~ん。 マニュアルは一通り目を通しましたが納得いく説明が書いていません。 プログラミングってもっとロジカルなものだと思っていましたので、案外例外があるのはおもしろいなあ、と思います。 制御構造について述べられていますが、何か質問に関係ありますでしょうか?よくわかりませんでした。 あと、#2さんの回答が自分としては解釈としてしっくり来るのですが、 $data = '<!-- '. include(test/01.html) .' -->'; を試しにやってみましたがエラーが出ました。 もしincludeが <? を切り離してしまう作用をするのであれば、htmlのコメントで括れば内容は表示されないはずだと思うのですが、考え方として的はずれでしょうか?
補足
試しに $data = htmlecho(); function htmlecho () { echo "<html><head></head><body>Hello World!</body></html>"; } としてみたところ include()関数と同様 値を代入した時点でその関数が実行されて表示されてしまいました。 ということは、echo が入っている関数は 変数という箱に収めてしまうような事はできない、ということでしょうか?
- php504
- ベストアンサー率42% (926/2160)
<? $data = include ('test/01.html'); ?> は <? $data = 1?>test/01.htmlの内容<? ?> と同じ意味になります includeの前でいったんPHPタグが閉じられその後にファイルの内容がコピーされた状態と理解すればいいでしょう。 includeされるファイルにPHP構文のreturn文がなければ1が返るので$data = 1が代入されます。 ファイルの内容を変数に入れたい場合、PHP4.3以上でしたらfile_get_contents()が使えます。
お礼
おぉ~~、 なるほど! こういう解釈はやはり慣れでできてくるものなのでしょうか? 初心者には思いつこうにもつけないんじゃないかと思いました。本家のマニュアルもそうですが、phpを解説している本はほとんどこういったメカニズムの説明を省略してしまっているので、なれるのに大変です。 ありがとうございます。感謝します。
補足
ところで試しに、 $data = '<!-- '. include(test/01.html) .' -->'; とやって真っ白なページがでないかなーと思ったのですが、がエラーが出てしまいました。
- yambejp
- ベストアンサー率51% (3827/7415)
includeの使い方を曲解していますね。 命題の内容をやるなら <?PHP $data = file('test/01.html'); ?> もしくはfopen系のファイルI/Oで実現します。
お礼
コメントありがとうございます。 質問の意図としまして、「なぜ変数に値を代入しただけなのに、勝手に変数の中身が表示されてしまうのか。」ということが知りたいのですが、もしご説明いただけるようでしたらありがたく思います。 プログラミングをはじめたばかりで、素朴に感じた疑問なのです。
お礼
うわぁああ。 やーっとわかりました!!!!ありがとうございます。 >これはfoo関数の処理を変数$varに代入するのではなく、foo関数の「実行結果」を$varに代入するという意味になります。< これでした。この説明がいままでどこにもなかったためわからなかったのだと思います。 うーでもこういった時間軸を整合させて認識するにはやっぱり慣れないと難しいですね^^。勘がぜんぜん違う方向に働いていました。