【问题标题】:Why is this PHP foreach loop only executing once?为什么这个 PHP foreach 循环只执行一次?
【发布时间】:2013-11-06 15:43:47
【问题描述】:

尝试调试 WordPress 臭名昭著的伪 cron 的一些问题。考虑过将其放在 WordPressAnswers 上,但我认为这与 WP 无关,而更多是关于 foreach 的基本 PHP 问题,似乎永远不会超过它的第一次运行。 (是的,肯定看了一堆类似的问题,但没有爱,对不起。)

这是代码,有 3 个检查点,我在其中添加了用于测试的输出。我将所有内容的整个代码都包含在循环中,只是为了彻底,尽管其中大部分可能是题外话。检查点 2 和 3 从不显示给我,检查点 1 只显示一次(即在循环的第一次迭代中)。未显示的是我输出 $crons 和 count($crons) 的地方,以确认,是的,它绝对有多个元素。

foreach ( $crons as $timestamp => $cronhooks ) {
    echo("<br>loop for timestamp " . $timestamp); // checkpoint 1
    if ( $timestamp > $gmt_time ) {
    break;
        }

    foreach ( $cronhooks as $hook => $keys ) {
    echo("<br>loop for hook " . $hook); // checkpoint 2

        foreach ( $keys as $k => $v ) {

            $schedule = $v['schedule'];

            if ( $schedule != false ) {
                $new_args = array($timestamp, $schedule, $hook, $v['args']);
                call_user_func_array('wp_reschedule_event', $new_args);
            }

            wp_unschedule_event( $timestamp, $hook, $v['args'] );

             do_action_ref_array( $hook, $v['args'] );

            // If the hook ran too long and another cron process stole the lock, quit.
            if ( _get_cron_lock() != $doing_wp_cron ) {
                echo("quitting!"); // checkpoint 3
                return;
            }
        }
    }
}

尽管我有 5 个元素,但我从中得到的所有输出是:

循环获取时间戳 1382968401

我会很感激能有更多人关注我所缺少的东西。我 95% 确定这是 WP 核心代码,除了我的检查点,尽管由于各种原因,另一个程序员在我们的版本控制系统的最终运行中在这里捣乱并不是不可能的。显然是另一个问题!

【问题讨论】:

  • $gmt_time 的值是多少?
  • 通过 microtime(true) 设置。此时,在我的代码中,每个输出检查点更高,1382918286.117
  • 知道了...请参阅下面的答案。
  • 1382968401 &gt; 1382918286.117 是真的,所以它会break;

标签: php wordpress loops foreach


【解决方案1】:

假设 $gmt_time 是当前的 UTC 时间,那么时间戳 1382968401 将更大(在撰写本文时):

$d = new DateTime('@'.'1382968401', new DateTimeZone('UTC'));
echo $d->format('Y-m-d H:i:s'); // output 2013-10-28 13:53:21

这可以解释为什么您的循环在第一次迭代时中断。

【讨论】:

  • 哦,对于皮特的...。我想我已经通过在某些时候用相同的结果实际注释掉那个中断来消除它,但现在再试一次,是的:输出乘以五。我准备对我的耻辱问题投反对票。谢谢两位。 (很抱歉,我不能赞成你的回答。)
【解决方案2】:

嗯,foreach 不会错的。

您的循环只能进行一次迭代的唯一方法是breaks。这只能意味着第一个$timestamp 大于$gmt_time。

(在底部附近还有return 的可能性,但你已经说过你收到了一行文本,所以它不可能是这样的......)

如果计划任务在未来,我猜您只想跳过迭代。为此,只需将break 更改为continue。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2015-04-10
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多