レンサバのcron数制限をPHPで無限に増やす方法

レンタルサーバーのcron(クーロン)機能、皆さん活用しているでしょうか?

cronは設定した時刻に指定のプログラムを実行する機能。例えば朝の8時に自動的におはようメールを送信する。みたいな事が出来るようになります。

また2分間隔で実行!等の定期起動もできるためサーバーに負荷をかけやすく、レンサバ側としてはあまり使ってほしくない機能だったりします。

そのためcronは設定数に制限がある場合が多いです。今回はPHPでその制限をぶち破る方法をご紹介します。鯖屋さん( TДT)ゴメンヨー

URLアクセスで目的のプログラムを実行する

方法は下のPHPプログラム「cron.php」の中から起動したいプログラムをURLで呼び出す事で実現します。

下のソースを「cron.php」で保存してレンサバにアップ。

その後、cron.phpを2分間隔で実行されるようにcronに登録します。※別に1分でも5分間隔でもOK。もし10分間隔なら if ( date(‘i’,$now) % 10 == 0 ){ } はいらない。

cron.php
<?php
define ( 'INI' , 'cron.ini' );
define ( 'LOG' , 'cron_log.txt' );
define ( 'RUN' , 'running' );
define ( 'LOGDATE' , 'Y/m/d' );
define ( 'LOGTIME' , 'H:i:s' );

$now = time();
$prevtime = @file_get_contents( INI );
if ( $prevtime == RUN || $prevtime + 55 > $now ) exit;
if ( empty($prevtime) ) $prevtime = $now; // 初回用初期値セット
@file_put_contents( INI , RUN ); // 実行中フラグセット

$log .= date(LOGTIME);
// 2min process
$log .= ' 2min';
$urls[] = 'http://example.com/test2.php';
$log .= " test2";

if ( date('i',$now) % 10 == 0 ) {
    // 10min process
    $log .= ' 10min';
    $urls[] = 'http://example.com/test10.php';
    $log .= " test10";
}

if ( date('H',$prevtime) != ($hour = date('H',$now)) ){
    // 1hour process
    $log .= ' 1hour';
    $urls[] = 'http://example.com/test3.php';
    $log .= " test1hour";

    if ( $hour == 21 ){
        // only 21:00
        $log .= ' 21hour';
    }

    if ( date('d',$prevtime) != ($day = date('d',$now)) ){
        // 1day process
        $log .= ' 1day '.date(LOGDATE);
        if ( date('W',$prevtime) != ($week = date('W',$now)) ){
            // 1week process
            $log .= ' 1week '.date('D');
            if ( date('m',$prevtime) != ($month = date('m',$now)) ){
                // 1month process
                $log .= ' 1month '.date('M');
            }
        }
    }
}
$log .= "\n";

if ( is_array($urls) ){
    fetch_multi_url($urls);
}

@file_put_contents( LOG , $log , FILE_APPEND );
@file_put_contents( INI , $now );

function fetch_multi_url( $url_list , $timeout = 0 ) {
// 複数URLを同時に取得
    $mh = curl_multi_init();
 
    foreach ($url_list as $i => $url) {
        $conn[$i] = curl_init($url);
        curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
        curl_setopt($conn[$i],CURLOPT_FAILONERROR,1);
        //curl_setopt($conn[$i],CURLOPT_FOLLOWLOCATION,1); // セーフモード時に動作しない
        curl_setopt($conn[$i],CURLOPT_MAXREDIRS,3);
       
        //SSL証明書を無視
        curl_setopt($conn[$i],CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($conn[$i],CURLOPT_SSL_VERIFYHOST,false);
        
        //タイムアウト
        if ($timeout){
            curl_setopt($conn[$i],CURLOPT_TIMEOUT,$timeout);
        }
       
        curl_multi_add_handle($mh,$conn[$i]);
    }
   
    //URLをすべて取得するまでループ
    $active = null;
    do {
        $mrc = curl_multi_exec($mh,$active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
   
    while ($active and $mrc == CURLM_OK) {
        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh,$active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }
   
    if ($mrc != CURLM_OK) {
        echo 'curl read error';
    }
   
    //ソースコードを取得
    $res = array();
    foreach ($url_list as $i => $url) {
        if (($err = curl_error($conn[$i])) == '') {
            $res[$i] = curl_multi_getcontent($conn[$i]);
        } else {
            //echo 'curl error';
        }
        curl_multi_remove_handle($mh,$conn[$i]);
        curl_close($conn[$i]);
    }
    curl_multi_close($mh);
   
    return $res;
}
?>

説明

起動したいプログラムはURLとしてアクセスできる必要があります。2分、10分、1時間、1日、1週間、1ヶ月という単位で設定できます。ちょっとした改造で30分間隔とか21時だけとかにも対応できるので、ソースを見て改変してください。

$urls配列に格納されるURLは、最後にcURLによって同時取得されます。これによりURLアクセスを通して希望のスクリプトが実行されます。一個ずつ file_get_contents してもいいんだけど、処理が重かったりすると、そのつど実行時間がずれ max_execution_time のタイムアウト食らう可能性があるので、実行を確実にする為に同時取得しています。

fetch_multi_url は全てのコンテンツが取得できるまでループします。もしタイムアウトを設定する場合は第2引数を利用してください。コンテンツ内容が必要な場合は fetch_multi_url の戻り値を参照のこと。

cron.php は iniファイルとlogファイルを出力します。iniファイルは動作に必ず必要ですが、logファイルが必要ない方は @file_put_contents( LOG , $log , FILE_APPEND ); をコメントアウトしてください。

safeモードだとファイル作成に失敗するかも?とか、CURLがエラー吐くかも?なので、設置前に確認必要かと!

このcron.phpをさらに短く改良。指定時間にメール送信する
cronで自分専用のアリバイ君とかリマインダーを作ってみるを公開しました。

 

広告