PHP の 相対パスinclude

投稿日:2009.03.16

PHP の inlude や require で他のファイルを相対パスを指定して読み込む場合があります。
そんな時に問題になりやすいのが、include しているファイルの中で、またさらに別のファイルを include するような場合です。
例えば、次のようなディレクトリ構成で、

www/
|-index.php
|
|-func/
|  |-function.php
|
|-class/
   |-class.php
次のような include を行っていたとします。
www/index.php ファイル
<?php
include("func/function.php");
?>

www/func/function.php ファイル

<?php
include("../class/class.php");
?>

www/class/class.php ファイル

<?php
print("test");
?>

この場合 index.php を実行すると、次のようなエラーが出てしまいます。
Warning: include(../class/class.php) [function.include]: failed to open
function.php の include で指定されている ../class/class.php ファイルが存在しないってことです。

一件すると、function.php からの相対パス ../class/class.php は問題なさそうですが、PHPでは、「実行したファイルのあるディレクトリが常に実行時のカレントディレクトリになる」っていう規則があるためエラーとなってしまうのです。
つまり、上記の場合 index.php 実行時のカレントディレクトリは www/ になるため、 www/../class/class.php というファイルを参照しに行って、エラーになってしまうのです。

この問題は、実行ファイルのディレクトリではなく、参照しているファイルのディレクトリを基にパスを取得することで回避することができます。具体的には dirname(__FILE__) を使って次のように書きます。

www/func/function.php ファイル
<?php
include(dirname(__FILE__) . "/../class/class.php");
?>
これで、問題無く実行されたかと思います。

__FILE__ は PHP の定数で、現在参照中のファイルのフルパスとファイル名を表します。dirname はパス中のディレクトリを取得する関数です。なお、dirname の結果は最後に / が付かないので、上記の例のように / を付け忘れないようにしましょう。

基本的に include, require は全て dirname(__FILE__) を使って記述しておくと、精神衛生上いいかなって思います。あと、include は include_once にしておくと、更にいいかなって思います。

PAGE TOP