web-dev-qa-db-ja.com

PHP:スケジュールされたジョブ(cronジョブ)の実行

ウェブホテルにいくつかのスケジュールされたタスクを実行したいサイトがあります。これを達成するためのどの方法をお勧めしますか?

これまで考えてきたのは、すべてのページの上部にスクリプトを含めて、このスクリプトにこのジョブを実行する時間があるかどうかを確認させることです。

これは、私が考えていたことの簡単な例です。

if ($alreadyDone == 0 && time() > $timeToRunMaintainance) {
   runTask();
   $timeToRunMaintainance = time() + $interval;
} 

私が考慮する必要がある他の何か、またはこれよりも良い方法がありますか?

40
Eikern

それがcronjobの目的です。 man crontab Linuxサーバーを実行していると仮定します。シェルアクセスがない場合、またはcronjobをセットアップする方法がない場合は、外部サーバーでcronjobをセットアップし、URLの1つにpingを実行する無料のサービスがあります。

34
Armin Ronacher

誰もこの正確な解決策について言及していないようですので、私は今これに答えています。

現在作業中のサイトでは、cPanelを使用してcronジョブを設定しましたが、PHP Interpreterを直接実行する代わりに(CodeIgniterを使用しており、コードがマッピングされているため、コントローラー関数にとって、これはおそらく素晴らしいアイデアではありません)wgetを使用しています。

wget -q -O cron_job.log http://somehost/controller/method

-qは、wgetが出力を生成しないようにするためです(したがって、メールを受信し続けることはありません)。 -O cron_job.logは、コントローラーが生成したものの内容をログファイルに保存します(毎回上書きされるため、成長し続けることはありません)。

これが、「適切な」cronを機能させる最も簡単な方法であることがわかりました。

17
user7094

CPanelホストをお持ちの場合は、Webインターフェイスからcronジョブを追加できます。[詳細設定]-> [cronジョブ]に移動し、高度でないフォームを使用してcron頻度を設定します。次のようなコマンドが必要です。

/usr/bin/php /path/to/your/php/script.php
12

ATrigger を見たことはありますか? PHPライブラリ も、オーバーヘッドなしでスケジュールされたタスクの作成を開始できます。

免責事項:私は彼らのチームの一員です。

6
Kousha

cronからPHPスクリプトを実際に実行する方法を知りたい場合は、2つのオプションがあります。PHPインタプリタを直接呼び出します(つまり、 "php/foo /myscript.php ")、またはlynx(lynx http://mywebsite.com/myscript.php )を使用します。どちらを選択するかは、主にスクリプトで環境を構成する方法に依存します。ファイルアクセス許可は、シェル経由で呼び出すかWebブラウザ経由で呼び出すかによって異なります。

1つの副作用は、実行するたびに電子メールを受け取ることです。これを回避するために、cronが正常に完了した場合はcron PHPスクリプトは何も出力せず(空白も含めないようにする必要があります)、失敗した場合はエラーメッセージを出力します。 cronから小さなPHPスクリプトを使用します。このように、失敗した場合にのみ電子メールを受け取ります。これは基本的にlynxメソッドと同じですが、シェルスクリプトはHTTPリクエストを行います。リンクスではありません。

このスクリプトを「docron」または何か(chmod + xを忘れないでください)と呼び、crontabでコマンド「docron http://mydomain.com/myscript.php "」を使用します。ページが何かを返す場合、ページの出力をHTML電子メールとして電子メールで送信します。

#!/usr/bin/php
<?php

$h = @file_get_contents($_SERVER['argv'][1]);

if ($h === false)
{
        $h = "<b>Failed to open file</b>: " . $_SERVER['argv'][1];
}

if ($h != '')
{
        @mail("[email protected]", $_SERVER['argv']['1'], $h, "From: [email protected]\nMIME-Version: 1.0\nContent-type: text/html; charset=iso-8859-1");
}

?>
5
MrZebra

Cronジョブのセットアップなどを避けたい場合(より良い方法をお勧めしますが)、提供したソリューションは非常に優れています。多くのプロジェクトで、PHPスクリプト自体が更新を実行する時かどうかを確認するためのチェックを行いました。

欠点(大丈夫、one欠点)は、特定の期間中に誰もアプリを使用していない場合、スクリプトが実行されないということです。

利点は、特定の期間中に誰もアプリを使用していない場合、スクリプトが実行されないことです。私が設定したタスクは、「キャッシュファイルの更新」、「毎日のバックアップの実行」などです。誰かがアプリを使用していない場合、キャッシュファイルを更新する必要はなく、バックアップするデータベースの変更も必要ありません。

私が提案するあなたの方法の唯一の変更は、誰かが正常にログインしたときにのみそれらのチェックを実行することです。あなたはすべてのページの読み込みでチェックする必要はありません。

4
nickf

Cronは、スケジューリング問題の汎用ソリューションです。ただし、規模が大きくなり、スケジュールの頻度が高くなると、信頼性/重複の問題が発生する可能性があります。このような問題が発生した場合は、 supervise またはより洗練された monit のようなものを検討してください。

4
mixdev

Cpanel uを使用する場合は、次のように追加する必要があります。

/usr/local/bin/php -q /home/yoursite/public_html/yourfile.php
3
mokiSRB

使用している方法は、cronジョブや外部の何かを使用したくない場合は問題ありませんが、ページがロードされるたびに確認するのは大変です。

最初は、おそらくいくつかのcronjobsを置き換えることができます。たとえば、Webサイトに登録しているユーザー数のカウンターがある場合、ユーザーが登録するときにこの番号を更新するだけなので、cronjobやスケジュールされたタスクを使用する必要はありません。

スケジュールされたタスクを使用する場合は、現在使用している方法を少し変更して使用することをお勧めします。サイトに1日に十分なヒットがある場合は、ヒットのすべてではなく1%または多分0.01%だけタスクを実行(またはタスクチェック機能を実行)することができます。使用する割合は異なりますページのヒット数と、タスクを実行する回数。したがって、この機能を実現するには、ランダマイザーを追加するだけです。

このような関数を単純に使用できます。

if(Rand (1, 100) <= 1) { // 1, 100 is used to generate a number between 1 and 100. 1 is for one percent.
    // Run the tasks system
}

お役に立てれば、

1
Tim Visée

Www.guardiano.pmでcronjobsを外部委託し、X分ごとにURLを呼び出します。 URL(つまりwww.yoursite.com/dothis.php)が呼び出されると、コードを実行します。必要なときにWebにページを要求させたくない場合は、POSTでの要求のみを許可し、guardiano.pmでのみ知っているパラメーターを送信できます。

ペットプロジェクトでそれを行うので、それは私がすることです。楽しんで!

1
Lorenzo Sinisi

コマンドラインPHP + cronは私が行く方法です。それは簡単で、法案に合うはずです。通常はPHP 。

0
Gavin M. Roy

Cronjobをセットアップするオプションがない場合は、cUrlを使用してスクリプトを呼び出すことができます(wgetの代替として-同じ機能)。ローカルマシンでcUrl関数を実行するスケジュールされたタスクを実行するだけです。

0
meeeeeh

より抽象的なものが必要な場合は、PHPスケジューラーなど。

また、cron式を解析するには、 https://github.com/mtdowling/cron-expression などの既存のライブラリを使用できます。 cronジョブの情報を把握するのに役立つ多くの便利な方法を提供します。

お役に立てば幸いです。

0
XuDing