Why does this PHP foreach loop only run once?


Trying to debug some issues with WordPress' notorious pseudo-cron. Thought about putting this on WordPressAnswers but I think this is less about WP and more a basic PHP question on a foreach that seems to never get past its first run. (Yes, definitely looked at a bunch of similar questions, but no love there, sorry.)

Here's the code, with 3 checkpoints where I added output for testing. I'm including the entire code of everything in the loop, just to be thorough, though most of it's probably beside the point. Checkpoints 2 and 3 never display for me, and checkpoint 1 only shows up once (i.e. on first iteration of loop). Not shown is where I'm outputting $crons, and count($crons) for good measure, to confirm that, yes, it absolutely has multiple elements.

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

    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

All the output I'm getting from this, despite my 5 elements, is:

loop for timestamp 1382968401

I'll be grateful for extra eyes on whatever I'm missing. I'm 95% sure this is WP core code, except my checkpoints, although for various reasons it's not out of the question that another programmer was mucking about in here in an end-run around our version control system. A whole other problem, obviously!

Well, foreach can't be wrong.

The only way your loop could do only one iteration is that it breaks. And that could only mean that the first $timestamp is greater than $gmt_time.

(There's also the return possibility near the bottom, but you already said you receive one line of text, so it couldn't have gone that way...)

I'm guessing that you want to just skip the iteration if the scheduled task is in the future. To do that, just change break with continue.