1. 標準の crontab ファイル ./crontab
を準備します。
コードをコピーします コードは次のとおりです:
#mhドムモンダウコマンド
* * * * * 日付 > /tmp/cron.date.run
2. crontab -e は、この cron.php スクリプトをシステム cron に追加します
コードをコピーします コードは次のとおりです:
* * * * * /usr/bin/php cron.php
3. cron.php ソースコード
コードをコピーします コードは次のとおりです:
// ./crontab または他の永続ストレージ (mysql、redis) から cron アイテムを読み取ります
$crontab = file('./crontab');
$now = $_SERVER['REQUEST_TIME'];
foreach ( $crontab として $cron ) {
$slices = preg_split("/[s]+/", $cron, 6);
if( count($slices) !== 6 ) 続行;
$cmd = array_pop($slices);
$cron_time = implode(' ', $slices);
$next_time = Crontab::parse($cron_time, $now);
if ( $next_time !== $now ) 続行します。
if ($pid == -1) {
die('フォークできませんでした');
else if ($pid) {
// 私たちは親です
pcntl_wait($status, WNOHANG) //子供たちをゾンビから守る
} その他 {
// 私たちは子供です
`$cmd`;
終了します;
}
}
クラス Crontab {
/**
* crontab 構文の次回実行時間 (スタンプ) を検索します
* 指定された開始タイムスタンプの後 (省略された場合は現在時刻)
*
* @パラメータ文字列 $_cron_string:
*
* 0 1 2 3 4
* * * * * *
* - - - - -
* | | | | |
* | | | | +----- 曜日 (0 - 6) (日曜日=0)
* | | | +---------- 月 (1 - 12)
* | | +----------- 月の日 (1 - 31)
* | +----------- 時間 (0 - 23)
* +--------------- 分 (0 - 59)
* @param int $_after_timestamp タイムスタンプ [デフォルト=現在のタイムスタンプ]
* @return int unix タイムスタンプ - 次回の実行時間は長くなります
* 指定されたタイムスタンプより (デフォルトは現在のタイムスタンプ)
* @throws InvalidArgumentException
*/
パブリック静的関数 parse($_cron_string,$_after_timestamp=null)
{
if(!preg_match('/^((*(/[0-9]+)?)|[0-9-,/]+)s+((*(/[0-9]+)?)|[ 0-9-,/]+)s+((*(/[0-9]+)?)|[0-9-,/]+)s+((*(/[0-9]+)?) |[0-9-,/]+)s+((*(/[0-9]+)?)|[0-9-,/]+)$/i',trim($_cron_string))){
throw new InvalidArgumentException("無効な cron 文字列: ".$_cron_string);
}
If($_after_timestamp && !is_numeric($_after_timestamp)){
throw new InvalidArgumentException("$_after_timestamp は有効な UNIX タイムスタンプである必要があります ($_after_timestamp が指定されています)");
}
$cron = preg_split("/[s]+/i",trim($_cron_string));
$start = empty($_after_timestamp)?time():$_after_timestamp;
$date = array( ' minutes' =>self::_parseCronNumbers($cron[0],0,59),
'時間' =>self::_parseCronNumbers($cron[1],0,23),
'dom' =>self::_parseCronNumbers($cron[2],1,31),
'月' =>self::_parseCronNumbers($cron[3],1,12),
'dow' =>self::_parseCronNumbers($cron[4],0,6),
);
// time()+366 に限定 - 1 年以上先を確認する必要はありません
for($i=0;$i
if( in_array(intval(date('j',$start+$i)),$date['dom']) &&
in_array(intval(date('n',$start+$i)),$date['month']) &&
in_array(intval(date('w',$start+$i)),$date['dow']) &&
in_array(intval(date('G',$start+$i)),$date['hours']) &&
in_array(intval(date('i',$start+$i)),$date['分'])
){
$start+$i を返す;
}
}
null を返す;
}
/**
* 単一の cron スタイル表記を取得し、それを数値に解析します
*
* @param string $s cron 文字列要素
* @param int $min 可能な最小値
* @param int $max 可能な最大値
* @return int 解析された数値
*/
保護された静的関数 _parseCronNumbers($s,$min,$max)
{
$result = array();
$v =explode(',',$s);
foreach($v として $vv){
$vvv = 爆発('/',$vv);
$step = empty($vvv[1])?1:$vvv[1];
$vvvv = 爆発('-',$vvv[0]);
$_min = count($vvvv)==2?$vvvv[0]:($vvv[0]=='*'?$min:$vvv[0]);
$_max = count($vvvv)==2?$vvvv[1]:($vvv[0]=='*'?$max:$vvv[0]);
for($i=$_min;$i
$result[$i]=intval($i);
}
}
ksort($result);
$result を返します;
}
}