include 関数を利用している PHP ファイルがある。このファイルを別の環境に移したら動かなくなってしまった。 (+_+) 原因は何だろう?
include はどこからファイルを探すのか?
言語リファレンス > 制御構造 > include によると、
ファイルのインクルードは、指定されたパスから行います。パスを指定しない場合は、 include_path の設定を利用します。…
パス (絶対パスあるいは相対パスのいずれでも) を指定した場合は include_path は無視されます。たとえば ../ ではじまるファイル名を指定した場合は、 親ディレクトリからそのファイルを探します。
上記 include_path とは、
PHP は、インクルードするファイルを探す際に インクルードパスの各エントリを個別に調べます。 まず最初のパスを調べ、見つからなければ次のパスを調べ、…… というように、ファイルが見つかるか warning あるいは error が発生するまで続けます。
include_path を調べるには、phpinfo 、または get_include_path を利用する。 XAMPP を使っているなら、以下の URL にアクセス。
include を試してみる
右図のようにファイル構成で include の挙動を確認する。実行した環境は、XAMPP を利用しており、phpinfo() を見ると include_path は
D:\xampp\php\pear\
と表示される。 右図のルートとなる www フォルダは、PDT で testphp プロジェクト内に作成した。
各ファイルの内容は以下の通り。
- www/index.php
<?php include ("include/a.php"); ?>
- www/include/a.php
<?php print "include/a.php"."<br>"; include("b.php"); ?>
- www/include/b.php
<?php print "include/b.php"."<br>"; ?>
これで www/index.php を実行すると、
include/a.php
include/b.php
と表示された。
include でファイルを探しにいく場所を順に考える
上記の実行される流れを考える。最初に www/index.php にアクセスしたので current working directory は
www
include する側のファイルとされる側を矢印で示すと、
- www/index.php → include/a.php、
- include/a.php → include/b.php
という関係。
ところで、マニュアルには次のように書かれていた。
ファイルのインクルードは、指定されたパスから行います。パスを指定しない場合は、 include_path の設定を利用します。…
つまり、include/a.php において
“b.php”
を include するとき、パスが指定されていないので最初に include_path である
D:\xampp\php\pear\
に b.php がないか検索される。その後 www/include/ 内を検索。
上記の場合は include_path に b.php がなく、www/include/ に b.php があるので www/include/b.php が実行される。
相対パスによって指定するとそのディレクトリから検索される
ところで、先ほどのドキュメントには、以下のように書かれていた。
パス (絶対パスあるいは相対パスのいずれでも) を指定した場合は include_path は無視されます。たとえば ../ ではじまるファイル名を指定した場合は、 親ディレクトリからそのファイルを探します。
上記における www/include/a.php で include している部分を include("./b.php"); に変更して実行したら、以下のエラーが表示された。
include/a.php
Warning: include(./b.php) [function.include]: failed to open stream: No such file or directory in D:\xampp\htdocs\testphp\www\include\a.php on line 3
Warning: include() [function.include]: Failed opening './b.php' for inclusion (include_path='.;D:\xampp\php\pear\') in D:\xampp\htdocs\testphp\www\include\a.php on line 3
これは、
./
を付けたことによって current working directory から検索されるため。
www/b.php
は存在しないので上記のようなエラーが表示された。b.php を www に置いたら、エラーは表示されない。
意図しないファイルを include してしまう
さて、ここで www/include/ に
config.php
を作成する。ファイルの内容は "config.php" と文字列を表示するのみ。
これを include/a.php から include して動作を確かめる。 include/a.php の include を include("config.php") と変更した。
実行するとなぜか "config.php" と表示されなかった。
include("config.php") をブレークポイントにしてデバッグしたところ、config.php の include で以下のような表示がされている。
www/include/config.php を include しているつもりが、include_path (D:\xampp\php\pear\) 内の Config.php を include してしまっている。これは先ほどの説明にあったように、
include_path が最初に検索される
のが理由。 include_path 内にあるファイルと同名のファイルを include をするときは注意が必要。
意図しない include をしないための対策
config.php の内容が実行されるには、3 つの方法がある。
- config.php を myconfig.php のように名称を変え、pear\Config.php とバッティングしないようにする。
- config.php を current working directory に置き、相対パスで呼出すようにする。www/config.php に置き、include/a.php では、include("./config.php") とする。
- www/include/config.php の場所は変えず、include/a.php の include の呼出しを次にようにする。
include(dirname(__FILE__) . "/config.php");
include しているファイルから見て相対的な位置で include できるように記述すればよい。(参考: PHP の include, require で相対パスを指定して読み込む場合のメモ - hoge256ブログ)
環境を変えたら動作しなかった理由
最初の問題に戻る。環境を変えたら動かなくなった理由は、問題なく動いていた環境では PEAR がインストールされていなかったために、
include("config.php")
の記述により、自分が作成した config.php が include されたていた。
しかし、環境を XAMPP に変更したことにより include_path に PEAR が設定され、include("config.php") の記述により PEAR の Config.php が呼出されたために挙動がおかしくなった。
パタッ(o_ _)o~†
0コメント:
コメントを投稿