1

PHPを使用したcronjobシステムがあります。cron.phpという名前のファイルがあり、ロードされていないかどうかを確認したいので、ロードします。このファイルが1回だけ実行されることは私にとって非常に重要であり、定義がすでに実行されている方法が必要です。exec、systemなどのシステム関数を使用できません...解決策はありますか?

注:スクリプトをCURLで実行しましたが、この場合、include_oneとrequire_onceは機能しません。

4

9 に答える 9

7

flock()次のように、phpファイル自体をロックするために使用できます。

<?php

class Lock{
    private $fp;
    function __construct(){
        $this->fp=fopen(__FILE__,'r');
        if (!flock($this->fp,LOCK_EX|LOCK_NB)) {
            die('already running !'.PHP_EOL);
        }       
    }
    function __destruct(){
        flock($this->fp,LOCK_UN);
        fclose($this->fp);  
    }
}

$lock=new Lock();


// simulate some processing
sleep(60);


echo "END";
?>
于 2012-05-08T08:06:32.427 に答える
2

require_onceまたはinclude_onceを使用できますか?

require_onceファイルを評価できない場合、PHPの致命的なエラーがスローされます(実行が停止します)。 include_oncePHP警告をスローします(実行が続行される場合があります)。

// Require tasks.php to run once
require_once 'path/to/tasks.php';

// Attempt to run tasks.php and only once
include_once 'path/to/tasks.php';
于 2012-05-08T07:24:45.193 に答える
2

あなたの問題は本質的に「phpスクリプトがまだ実行されているかどうかを確認する」と同等です

こちらをご参照ください

PHPスクリプトがまだ実行されているかどうかを確認します

于 2012-05-08T07:35:42.913 に答える
2

私があなたを正しく理解しているなら、あなたはあなたのcron.phpスクリプトがcronによって二度と開始されないようにしたいのですが、それは別のPHPスクリプトから呼び出されていませんか?(その場合、require_onceが正しい答えになります)

私が理解しているように、スクリプトが実行中であることを示すマーカーを保存し、スクリプトの最後でそのマーカーを削除する必要があります。

環境に応じて、小さなファイルを作成するか.lock、データベースにステータス=ロックされたエントリを保存することができます。

編集:これはfileメソッドを使用した小さなコード例です:

<?php
// cron.php
$path = '/path/to/your/data/directory/';
if (file_exists($path . '.lock') {
   die('cron.php is already running');
}
// if script reaches this point, it is not locked -> create a lock
file_put_contents($path . '.lock', 'lockfile created at ' . now());

//... your code....

//unlocking
unlink($path . '.lock');
?>
于 2012-05-08T07:36:31.970 に答える
2

cURLを使用している場合は、cURLを使用してなどのページをリクエストしていると思いますhttp://domain.com/cron.php。cURL / wget / browser / etcを介してスクリプトを要求しているマシンには、スクリプトがサーバー上ですでに実行されているかどうかを知る方法がありません。cron.phpただし、スクリプトを1回だけ実行するように構成できます。

<?php
// attempt to obtain a lock
$fp = fopen(basename(__FILE__) . ".lock", "w");
if (flock($fp, LOCK_EX | LOCK_NB) === false) {
    echo basename(__FILE__) . ": already running\n";
    exit(-1);
}

// code goes here
echo date("Y-m-d H:i:s") . ": cron job started\n";
sleep(30);
echo date("Y-m-d H:i:s") . ": cron job ended\n";

// release the lock
flock($fp, LOCK_UN);
fclose($fp);

サンプルコードはPHPflock関数を使用しています。このLOCK_EXフラグは、PHPに排他ロックを取得する必要があることを通知します。つまり、他のプロセスがファイルにアクセスすることは許可されていません。はPHPに、ブロックして(ロックが解放されるのを待って)すぐLOCK_NBに戻るべきではないことを通知します。false一緒に、2つのスイッチは、最初のプロセスがファイルをロックしている間、2番目のプロセスがファイルをロックできないことを保証します。

于 2012-05-08T08:23:09.223 に答える
1
include_once('class.php');

php.netの状態

include_onceステートメントは、スクリプトの実行中に指定されたファイルをインクルードして評価します。これはincludeステートメントと同様の動作ですが、唯一の違いは、ファイルのコードがすでにインクルードされている場合、再びインクルードされないことです。名前が示すように、それは一度だけ含まれます。

于 2012-05-08T07:29:56.703 に答える
1

あなたが使用することができますrequire_onceまたはinclude_once

includeステートメントとrequireステートメントの両方の一般的な構文は次のとおりです。

include "file_to_load.php";
include_once "file_to_load.php";

ステートメントを使用する場合include_once/require_once、ファイルを複数回ロードまたは実行することはできません。これらの2つの方法のいずれかを使用してファイルを2回ロードしようとすると、そのファイルは無視されます。スクリプト内で同じ関数を複数回定義することは許可されていないため、これらの関数を使用すると、開発者は、スクリプトが以前にロードされているかどうかを確認しなくても、必要に応じてスクリプトを含めることができます。

注外部include_onceファイルから値を返す機能は、ステートメントのみに制限されています。ステートメントはこのrequire_once方法では使用できません。

于 2012-05-08T07:29:43.090 に答える
0

require_onceまたはinclude_onceのいずれかを使用できます。

何を使用するか混乱している場合、この2つの違いは次のとおりです。

require_onceは先行するコードの実行を停止し、致命的なエラーが発生します。言及されたファイルが見つからない場合、先行するコードを続行する場合は、ファイルが見つからなくても使用しないでください。

ここで、include_onceは先行するコードの実行を継続します。

于 2012-05-08T07:31:40.030 に答える
0

この場合、データベースを使用して、データベースと2番目の列にページのエントリを作成し、ロードされているかどうかを確認できます(たとえば'0'、まだロードされておらず、ロードされている場合'1')。ページがロードされたときにその行の値を最初に保持し、その列をとして'0'更新します'1'

于 2012-05-08T08:18:06.037 に答える