PHP を cron で動かす際に、「相対パス」を使うとなぜか上手く動かない! 初心者あるあるだと思います。
簡単な解決法と、「そもそもなぜ動かないの?」という説明です。
簡単な解決法
プログラムの先頭あたりに以下の 1 行を書くと、相対パスでも動くようになります。
chdir(__DIR__);
//-- PHP5.3以下の環境も考慮する必要がある場合は↓をchdir()の「前」に追加します
// if (!defined('__DIR__')) {
// define('__DIR__', dirname(__FILE__));
// }
もちろん、相対パスではなく、絶対パスを使っても良いです。
file_get_contents('./example.txt');
↓ ↓ ↓
file_get_contents(__DIR__ . '/example.txt');
補足
調べ方
getcwd() を使って…
//-- パーミッションに注意
file_put_contents(__FILE__ . '.test.txt', getcwd());
exit;
- cron から動かした場合
- ウェブブラウザからアクセスして動かした場合
で、結果を見比べてみると良いと思います。
なぜ相対パスだと動かないのか
上記を試せば分かる通り、cron から実行すると、「ワークディレクトリが、cron を実行するユーザーのホームディレクトリになるから」です。
-
ホームディレクトリ
- ユーザーのデフォルトのワークディレクトリ
「相対パス」というのは、読んで字の如く、○○を『基準』として『相対的に』ファイルのパスを表現する方法です。
ですので、そもそも基準となる○○が、自分が想定している場所と異なる(PHP ファイルのある場所ではない)のであれば、動かないのは当然ですよね。
chdir(__DIR__)
は、「ワークディレクトリを、PHP ファイルのあるディレクトリへ変更する」という意味になりますので、cron からでも、PHP ファイルを『基準』にした、相対的なパスの指定が可能となるわけです。
PHP に限った話ではなく…
- どのユーザーで実行されているのか?
- ユーザーのホームディレクトリはどこなのか?
- ワークディレクトリはどこなのか?
…といった事を意識しておくと、色んな事に応用が効くと思います。