- 2007-10-15
- php
require("foo.php")とrequire("./foo.php")って意味違うって知ってました? cliから実行する場合以外はあまり関係無いかもしれませんが。
読み込むファイルはまずカレントのワーキングディレクトリからの相対パスとしてinclude_path で探され、それから、カレントのスクリプトのディレクトリからの相対パスとしてinclude_path で探されます。 (中略)ファイル名が ./ あるいは ../ で始まっている場合は、 カレントのワーキングディレクトリからの相対パスとして探されるのみとなります。 (PHP: include - Manual)
以下実験。include_pathは.:/php/includes:/usr/share/pearとなっています。
で、例えばこんなディレクトリ構成になっているとします。
+- foo/
| +- bar/
| +- a.php
| +- b.inc
+- b.inc
+- c.inc
それぞれのファイルの内容はこんな感じ。
foo/bar/a.php
<?php
include "b.inc";
include "./b.inc";
include "../../c.inc";
?>
foo/bar/b.inc
This is foo/bar/b.inc
b.inc
This is b.inc
c.inc
This is c.inc
で、fooディレクトリの上のディレクトリから実行してみます。
$ php foo/bar/a.php
This is b.inc
This is b.inc
PHP Warning: include(../../c.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 4
...
実行結果は、すべてのファイルをスクリプトのあるディレクトリではなく現在の実行ディレクトリから探そうとしていることを意味していますね。
include "b.inc"の場合は、ワーキングディレクトリ⇒スクリプトディレクトリの順で探すので、ここでb.incを削除してみると、
$ php foo/bar/a.php
This is foo/bar/b.inc
PHP Warning: include(./b.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 3
...
PHP Warning: include(../../c.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 4
と、include "b.inc"は成功しますが、include "./b.inc"はエラーとなります。
straceを見ると、いくつかのパスをトライしている様子が見えます。
open("foo/bar/a.php", O_RDONLY) = 3
# include("b.php") の場合、
# 最初にワーキングディレクトリ
open("/path/to/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)
# 次にinclude_path
open("/php/includes/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/pear/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)
# 次スクリプトディレクトリで発見
open("/path/to/foo/bar/b.inc", O_RDONLY) = 3
This is foo/bar/b.inc
# include("./b.php") の場合、ワーキングディレクトリに
# 無ければすぐ諦める
open("/path/to/b.inc", O_RDONLY) = -1 ENOENT (No such file or directory)
PHP Warning: include(./b.inc): failed to open stream: No such file or directory in /path/to/foo/bar/a.php on line 3
でも何でこんな仕様になってるんだろう。