我的PHP Simple Cron实现代码运行两次


My PHP Simple Cron Implementation Code Run Twice


我的环境:
wordpress-->myplugin
myplugin中,我使用wploaded操作来触发我的cronfunc运行
mycronfunc伪代码:

add_action('wp_loaded','cronfunc');
    function cronfunc()
    {
        if(defined('IN_MY_CRON_FUNC'))
            return;
        define('IN_MY_CRON_FUNC',true);
        if nowtime - get_option('last_do_work_time') > 3600:
            update_option('last_do_work_time',nowtime);
            run cronjob
    }

问题是cronfunc有时会运行两次
有人告诉我为什么?

我似乎无法在手动设置的插件上加载两次。这是代码:

<?php
/*
Plugin Name: test
Plugin URI: http://localhost
Description: nothing really
Version: 00.001
Author: somebody
Author URI: http://localhost
*/
add_action('wp_loaded','cronfunc');
function cronfunc() {
    $myFile = (pathinfo(__FILE__));
    $myFile = $myFile['dirname']."/testFile.txt";
    $now = microtime(true);
    if ( $now - get_option('last_do_work_time') > 3 ) { #I set to 3 seconds to test
        $fh = fopen($myFile, 'a+') or die("can't open file");
        fwrite($fh, microtime(true)." - ".$now - get_option('last_do_work_time')."-'n");
        fclose($fh);
        update_option('last_do_work_time',$now);
    }
}
?>

保存为test.php,放在插件中的文件夹中并激活它。它是经常发生还是偶尔发生?在再次更新之前,它们可能已经通过了IF。如果是这种情况,您可能需要锁定该选项,然后等待或跳过(如果它已经在运行(。您可能需要使用信号量或使用数据库创建类似的东西。。。也许您可以使用wordpress选项来定义一种互斥对象之类的。DEFINE((不会有帮助,因为如果它再次并排运行,那么它们就不会相互影响。

这可能是一种糟糕的方法,但目前可能有效:

<?php
/*
Plugin Name: test
Plugin URI: http://localhost
Description: nothing really
Version: 00.001
Author: somebody
Author URI: http://localhost
*/
function wplock_release($id='check_cronfunc') {
    delete_option($id);
}
# not the best, but might work
function wplock_aquire($id='check_cronfunc') {
    $guid = com_create_guid(); #maybe just need uniqid or something, but just testing stuff
    # check if anyone else has lock and set, not sure if we can force lines inside php
    if ( get_option($id) !== false
        || !update_option($id,$guid)
        || get_option($id) != $guid )
    { 
        return false;
    }
    register_shutdown_function(wplock_release($id)); # probably don't need this
    return true; # maybe just return true or something
}

add_action('wp_loaded','cronfunc');
function cronfunc() {
    $myFile = (pathinfo(__FILE__));
    $myFile = $myFile['dirname']."/testFile.txt";
    $now = microtime(true);
    if ( wplock_aquire() ) {
        if ( $now - get_option('last_do_work_time') < 3 ) { # less than 3 seconds
            wplock_release();
            return;
        }
        wplock_release();
    } else {
        return;
    }
    $fh = fopen($myFile, 'a+') or die("can't open file");
    fwrite($fh, microtime(true)." - ".$now - get_option('last_do_work_time')."-'n");
    fclose($fh);
    update_option('last_do_work_time',$now);
}
?>

编辑:将锁放在选项周围,如果无法获得则返回。。。有点草率,但只是为了

我的插件出现了一个问题,我的所有统计条目都翻了一番。WordPress似乎在每个页面上都做了一些奇怪的双重调用。

我从来没有弄清楚为什么,但我的解决方法是在插件中编写日志记录代码,但我从<entry>元素中的single.php模板中调用日志记录函数。