レンタルサーバーでPHPを継続的に動かす


通常はcronとか使えばいいのですが、大量高速に動かしたい時の方法です。

cronだと、5分毎にとか設定できますが、どこまで処理が完了しているかもわからないので、
処理が終わったら、また動かすというのを、インターバルをあまりおかずに動かしたいと時の方法です。

ローカルPCに、apiを呼びたすa.phpを
レンタルサーバーに、DB処理などをするb.phpを置きます。
a.phpの処理はapiを呼び出すだけの軽い処理ですが、
b.phpは実際のDB処理なので、重たい分、sleepをしっかりと入れるとよいです。
あまり欲張らなくても、cronで定期的に呼び出すよりもパフォーマンスがよいです。

<?php
/**
 * a.php サンプル
 */


//初期設定
const URL="";//apiのURL
$scriptname="abc";//スクリプト名
$setfilename=$scriptname."/kanryou.txt";//完了番号ファイル
$times=150000;//何回までapiを呼び出すか かなり大きくて良い

for($i=0;$i < $times;$i++){
    $result=httpfix_api($i);
    if($result === "error"){
        //apiの対象取得のselectでエラーしている
        print_r("\nMaybe get_c_name api select Error!");
        break;

    }elseif($result === "fin"){
        //完全に終了している        
        print_r("\nMaybe get_c_name All finished!");
        break;

    }else{
        //成功し番号が書かれているはず
        if(is_int($result) == true){
            //完了番号を書き込み
            print_r("\nSucces! i/times-".$i."/".$times);
            $fp=fopen($setfilename,"w");
            fwrite($fp,$result);
            fclose($fp);

        }else{
            print_r("\nIs Not number Error! get_c_name");

            //問題が起きたので、強制的にカウンターを一つすすませた
            $num=file($setfilename)[0];
            $num=$num-1;//sqlのbetweenに対応するので引く
            $fp=fopen($setfilename,"w");
            fwrite($fp,$num);
            fclose($fp);

        }

    }

    sleep(3);//適当にインターバル

}

print_r("\nExit for loop-for!");
exit;



function httpfix_api($n){
    global $setfilename,$scriptname;

    print_r($scriptname." to api start! $n times\n");

    //開始番号の取得
    if(file_exists($setfilename)){
        $end=file($setfilename)[0];
    }else{
        echo "no file $setfilename\n";
        exit;
    }

    //api接続

// APIのURLを設定
$url = URL;

// cURLセッションを初期化
$ch = curl_init($url);

// HTTPリクエストのタイプを指定
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

// HTTPリクエストのヘッダーを設定
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/x-www-form-urlencoded',
    'Authorization: Bearer YOUR_API_TOKEN'
));

// HTTPリクエストのボディを設定

$data = array('end' => $end);

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true);

// HTTPリクエストを実行
$response = curl_exec($ch);
// HTTPリクエストの結果を取得
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// cURLセッションを終了
curl_close($ch);

    return $response;
}




?>

<?php
/**
 * b.php サンプル
 * DB操作例
 */

 const HOST ='';
 const DBUSER='';
 const DBPASS=''; 
 const DBNAME=''; 

$scriptname="api_abc";


 //初期設定
$errorlog=$scriptname."_error.txt";
if(!file_exists($errorlog)){
    $fp=fopen($errorlog,"w");
    fclose($fp);
}
$oklog=$scriptname."_ok.txt";
if(!file_exists($oklog)){
    $fp=fopen($oklog,"w");
    fclose($fp);
}

//1回あたりのSELECT取得件数
$limit_num=3;


//api元から前回の完了番号を取得
if($_POST["end"] != null){
    $end=$_POST["end"];
    $scope="'id' < $end AND ";
}else{
    $end="1000000";
    $scope="";
}

//DBより対象を$limit_num件取得 テーブル名やその他where情報を書く

 $query1="SELECT * FROM `テーブル名` WHERE id BETWEEN 0 AND $end  ORDER BY id DESC  LIMIT ".$limit_num;

 // MySQLデータベースに接続する
 $link = mysqli_connect(HOST, DBUSER, DBPASS, DBNAME);
 
 // SQLを実行する
 $result = mysqli_query($link, $query1);
 $row = mysqli_fetch_assoc($result);

 if (count($row) > 0) {
     // 結果セットに行が存在する場合の処理
     do {
        print_r($row);
        $id = $row['id'];

        $result=update($id);//なんらかの処理

        if($result == false){
            echo "Error";
            exit;
        }

    } while ($row = mysqli_fetch_assoc($result));
} elseif(count($row)==0) {
    // 結果セットに行が存在しない場合の処理
    echo "fin";
}else{
echo "error";
}

 
 // MySQLデータベースから切断する
 mysqli_close($link);

 echo $id;//最終処理idを返す→呼び出しの完了番号になる
 
exit;


function update($id){
    global $errorlog,$oklog;

    //なんらかのsql処理 メインフローと同様の書き方

    //
    
    //成功したらtrue,失敗したらfalse
    return $result;
    

}