CronでPHPを動かすとき DOCUMENT_ROOT が参照できない対処法

Cron(クーロン)を使ってPHPを自動実行してると、
次みたいなサーバー変数が一切参照できなくなります。

  • $_SERVER['DOCUMENT_ROOT']
  • $_SERVER['HTTP_HOST']

いわゆるサーバー変数と呼ばれるもの

こういうのが参照できくなるって、かなり困りますよね...

そこでCron実行時でもサーバー変数を参照する方法についてまとめました。

$_SERVER の DOCUMENT_ROOT が空になる原因

まず Cronクーロン) とは何かについて

正確にいうと cron は crontab とも呼ばれていて、
サーバー側(Unix系)で自動的に処理を行うコマンドのことです。

以下 Wikipedia からの引用

crontabクロンタブ、あるいはクローンタブ、クーロンタブとも)コマンドはUnix系オペレーティングシステム (OS) において、コマンドの定時実行のスケジュール管理を行うために用いられるコマンドである。標準入力からコマンド列を読み取り、crontabと呼ばれるファイルにそれを記録する。この記録を元に定時になると、その命令内容を読み取り、実行が行われる。cronという名称はギリシア語のクロノス (χρόνος) に由来するという説がある(Command Run ON の略という説も)。日本語ではクーロンという読みが慣習的に広く用いられているが、英語では通常クロンまたはクローンと発音する[1]

引用元 : crontab - Wikipedia

cronという名前の由来には諸説あるみたいですね。(なんで諸説あるんだろう・・・?)

あと日本語だと "クーロン" と呼んでるけど、英語だと "クロン" とか "クローン" という言い方が一般的な模様

 

まあそれはさておき、
問題なのは cron を使ってPHPを自動実行するとサーバー変数が参照できない事

例えば cron に登録したスクリプトで次コードを書いたとしましょう。

何の変哲もないありふれた書き方

でも cron で実行すると 次みたいな警告 が出て怒られてしまいます。

何でこういう警告が出るかというと、

Cronジョブはサーバー上で独立した状態で実行されるから

$_SERVER  から参照できる変数はHTTP経由から呼ばれないとセットされないみたいですね。

なので HTTP_HOST  とか HTTP_USER_AGENT  の中身ももちろん参照不可です。

ですが、この問題の解決策は次で紹介するようにいくつかあります。

Cron実行時に DOCUMENT_ROOT を参照する2つの対処法

この問題の対処法として、自分が思いつくのは次の2つ

対処法1.Cronジョブのオプションから渡す

まず1つめ

Cronジョブを実行するコマンドから渡してあげるという対処法

つまりコマンドオプションにドメイン直下からのパスを指定してあげればいいんです。

具体的なやり方は次の通り

 

まず次みたいなコマンドを cron に登録するとしましょう。

上コマンドの --doc-root="path/to/docroot"  という部分に注目

ここで $_SERVER['DOCUMENT_ROOT']  から本来取得できるパスを指定してください。

そして実際のスクリプト上では次みたいなコードを書けばOKです。

getopt関数を使えばコマンドオプションの値が参照できます。

詳しく知りたい方は次記事をご覧ください。

▼ PHPでのコマンドライン引数とかオプションの受け取り方

これでCron実行時でも DOCUMENT_ROOT  が参照可能

もちろんオプションを増やせば HTTP_HOST  とかも指定できます。

対処法2.dirname関数で現在のパスから取得する方法

2つ目の方法は dirname 関数から設定する方法

dirname関数は渡されたパスの親ディレクトリのパスを返す関数です。

つまり __FILE__  を渡せば、現在スクリプトが動いている親ディレクトリのパスが取得できるという訳

これを何回か使えば DOCUMENTO_ROOT  を設定することができます。

 

例えばドメイン直下からのディレクトリ構成が次みたいなってるとしましょう。

  • - root
    • - hoge
      • - hoge.php
      • - piyo.php

そして hoge.php  をCronジョブとして登録してるとします。

その場合、 hoge.php  から DOCUMENT_ROOT  は次コードで設定可能

dirname関数を2回繰り返してます。

この繰り返し回数はドメイン直下からの深さによって変えてください

ここまでのまとめ

ここまでで紹介した対処法は次の2つ

  • Cronジョブのオプションに渡す方法
    コマンド実行時に --doc-root="path/to/docroot"  みたいな感じでオプションを付ける。PHPからは getopt 関数を使って取得し、 $_SERVER['DOCUMENT_ROOT']  に入れる
  • dirname関数を繰り返す方法
    例えば dirname(dirname(__FILE__))  みたいにドメイン直下からの深さに応じて、dirname関数を繰り返す。そしてその値を $_SERVER['DOCUMENT_ROOT']  に代入すればOK

Cronを実行してると サーバー変数はそのまま受け取れないので要注意です。

以上、CronでPHPを動かすとサーバー変数が参照できない対処法でした。

PHP

Commentsこの記事についたコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください