【2019年07月21日】

PHPでファイルやディレクトリを操作するとき、当然操作対象のファイルやディレクトリのパスが必要になる。

例えばファイルを開く関数、fopen。第一引数にファイルのパスを指定する。
このパスには絶対パスと相対パスが指定できるが、絶対パスはいいとして、相対パスの基準がどこになるのか迷った事ってないだろうか?

たとえば、

http://www.hoge.com/bbs.php

というURLにアクセスしたとしよう。
サーバーのディレクトリ構成的には、Web公開ディレクトリのルート直下にbbs.phpというファイルがあることになる。
で、bbs.phpではデータファイルとして、dataというディレクトリの中のbbs.datというファイルを読み込むとする。dataディレクトリがbbs.phpと同じくルート直下にあるとすると、

bbs.php
<?php

fopen('./data/bbs.dat', 'r');

?>

という感じになる。
これは、当然bbs.phpが基準となっている。

それでは、bbsのメインロジックはclass/BbsLogic.phpに記述しているとする。これをbbs.phpから読み込むとすると、

bbs.php
<?php

require_once './class/BbsLogic.php';

?>

となる。
そして、先ほどのbbs.datはBbsLogic.phpから参照するとしたら、相対パスはどのようになるか。

こうなる。

BbsLogic.php
<?php

fopen('./data/bbs.dat', 'r');

?>

直接bbs.phpから読み込んだ場合と同じになる。
BbsLogic.phpを基準に見ると、../data/bbs.dat となりそうな感じがするが、そうはならない。

実はどんなファイルをrequireしようが、相対パスの基準はURLで直接指定されたファイルとなるのだ。あくまでスクリプトはbbs.phpが呼ばれており、requireは決してrequireしたファイルに処理を譲渡するのではなく、requireした側のファイルに組み込むような形となるので、基準はbbs.phpとなるのだ。

だから、汎用的なライブラリ系のクラスはどこから呼ばれるかもわからないので、中で相対パスは使用すべきではない。

知ってる者には当たり前な話題かもしれないが、知らない者にとっては結構ハマる部分だったりする。