RaspberryPIでPHPプログラムを実行する際、ブラウザからは実行できるのに、コマンドラインからだと実行できない原因と対処について

■スポンサードリンク
この記事の所要時間: 36

RaspberryPIで、とあるPHPプログラムを実行するときに、
ローカル内で、別のPCからブラウザから実行すると実行できるのに、
TeraTermやcronなどでコマンドラインベースで実行させると、
実行できないという珍現象が起こりました。

一日悩んで、ようやく原因がわかったので、
メモに残しておきます。

結論から言うと、今回の場合
「相対パスの設定間違い」
でした。

まず、私が作っていたプログラムの
簡単な中身ですが、
ツイッターAPIのやり取りをして、
結果を、fopen、fwriteなどでログをサーバに保存。
といった内容でした。

ツイッターAPIは問題なく実行できていたのですが、
fwriteがうまく実行できていませんでした。

よくよく、サーバ内を見てみると、
/var/www/twitter
にログが残っていてほしいのに、
/home/pi
にログファイルが保存されているのが分かりました。

つまり、ブラウザから
/var/www/twitter
にあるPHPプログラムを実行して、fwriteでファイルを保存すると、
/var/www/twitter
に保存されるのに、
TeraTermやcronなどでコマンドラインベースで実行させると、
/home/pi
にファイルが保存される、
という状況だったわけです。

この原因が、「相対パスの設定間違い」でした。

インクルードや、ファイル入出力をする際、パスを指定するときには、
「絶対パス」と「相対パス」がありますが、
今回、プログラム内では相対パスですべて記入していました。
たとえば、下記のようにです。

例1:
include ‘common_API.php’;

例2:
$fp = fopen(“test.txt”, “w”);
fwrite($fp, $contents);
fclose($fp);

※きちんと、パスが設定してあれば、./test.txtでも可能

こんな風に書いていたわけですね。
これで、今までレンタルサーバ上では
問題なく実行できていたのですが、
ラズパイでコマンドラインで実行すると、
ファイル出力ができなかったのです。

基本的には、プログラムを実行すると、
そのプログラムの場所が相対パスの基点になります。
しかし、今回は例外的に実行プログラムの
基点がプログラムの場所になっていませんでした。

つまり、ブラウザで実行すると、
/var/www/twitter
が基点になるのに、
コマンドラインベースだと、
/home/pi
が基点になっていたことになります。

こういった、基点の問題を解決する方法が、
「dirname(__FILE__) 」の使用です。

これは、実行しているプログラムの場所を返す関数です。
これを使って、以下のように書き換えました。

例1:
include dirname(__FILE__) . ‘/common_API.php’;

例2:
$fp = fopen(dirname(__FILE__) . “/one_way_follow.txt”, “w”);
fwrite($fp, $one_way_follow_text);
fclose($fp);

これで、問題なくプログラムを実行することができました。
めでたし、めでたし

相対パスは便利で、ついつい使ってしまいますが、
落とし穴もあるので、熟知しておく必要がありますね。
ではでは。

PR
■スポンサードリンク
  • このエントリーをはてなブックマークに追加

コメントをどうぞ

メールアドレスが公開されることはありません。