在重叠日期时间上使用PHP foreach循环问题

时间:2015-08-23 05:15:16

标签: php mysql loops foreach

数据摘要

我有以下数据,$existing_events现有事件数组和新事件请求($requested_start$requested_end)。通常是从SQL中提取的,但我在这里用静态数组复制了这个问题:

$existing_events = array(
    0   => array(
        'time_start' => '2015-09-05 11:30:00',
        'time_end'   => '2015-09-05 18:45:00'
    ),
    1   => array(
        'time_start' => '2015-09-05 07:15:00',
        'time_end'   => '2015-09-05 10:30:00'
    )
);

$requested_start    =   strtotime('2015-09-05 3:30:00 AM');
$requested_end  =   strtotime('2015-09-05 9:30:00 AM');

结果阵列

一个$results数组,用于跟踪进行比较的次数('comparison_counter')以及发现了多少冲突('冲突'):

$results = array(
    'conflicts' => 0,
    'comparison_counter' => 0
);

FOREACH LOOP

最后,在转出json_encode'd结果之前,foreach循环比较start&请求的新活动的结束时间,反对开始和每个预先存在的事件的结束时间,使用this logic。注意comparison_counterconflict增量 - 前者在每次循环运行时运行,而后者仅在其if语句中“到达”,此时请求的事件时间与当前活动时间正在测试中。

if (!empty($existing_events)){
    foreach ($existing_events as $existing_event){
        $existing_start = strtotime($existing_event['time_start']);
        $existing_end = strtotime($existing_event['time_end']);
        $results['comparison_counter']++;
        if ($requested_start > $existing_end) {
            break;
        } elseif ($requested_end < $existing_start) {
            break;
        } else {
            $results["conflicts"]++;
        }
    }
}

echo json_encode($results);
exit;

实际响应

但是,我收到的内容似乎只是执行了一次foreach循环,尽管我的$existing_events数组中有两个项目。以下是我收到的数据:

comparison_counter: 1
conflicts: 0

VS。我的期望:

comparison_counter: 2
conflicts: 1

奇怪的是,只要我做出以下更改 11 :30开始时间(尝试与两个事件重叠):

$requested_end  =   strtotime('2015-09-05 11:30:00 AM');

...... comparison_counter现在有效。我现在收到以下内容:

comparison_counter: 2
conflicts: 2

我的问题

为什么foreach循环不能正常运行,基于我传递的数组中的内容?我希望每次它发射时它至少会击中它$results['comparison_counter']++;

2 个答案:

答案 0 :(得分:0)

我认为这可能是您正在寻找的:

if (!empty($results['same_day'])){
    foreach ($results['same_day'] as $same_day){
        $exist_start = strtotime($same_day->time_start);
        $exist_end = strtotime($same_day->time_end);
        // Check if new meeting plans to start during existing meeting
        if ( ($requested_start > $exist_start) && ($requested_start < $exist_end) ) {
            $results["conflicts"]++;
            break;
        }
        // Check if new meeting plans to end during existing meeting
        if ( ($requested_end > $exist_start) && ($requested_end < $exist_end) ) {
            $results["conflicts"]++;
            break;
        }
        // Check if existing meeting starts during new meeting
        if ( ($exist_start > $requested_start) && ($exist_start < $requested_end) ) {
            $results["conflicts"]++;
            break;
        }
        // Check if existing meeting ends during new meeting
        if ( ($exist_end > $requested_start) && ($exist_end < $requested_end) ) {
            $results["conflicts"]++;
            break;
        }
    }
}

我以前测试的完整代码:

<?php

$a = new stdClass();
$b = new stdClass();

$a->time_start = "2015-09-05 11:30:00";
$a->time_end = "2015-09-05 18:45:00";

$b->time_start = "2015-09-05 07:15:00";
$b->time_end = "2015-09-05 10:30:00";

$results['same_day'] = array( $a, $b );
$results['conflicts'] = 0;

$requested_start = strtotime( "2015-09-05 03:00" );
$requested_end = strtotime( "2015-09-05 11:00" );


if (!empty($results['same_day'])){
    foreach ($results['same_day'] as $same_day){
        $exist_start = strtotime($same_day->time_start);
        $exist_end = strtotime($same_day->time_end);
        // Check if new meeting plans to start during existing meeting
        if ( ($requested_start > $exist_start) && ($requested_start < $exist_end) ) {
            $results["conflicts"]++;
            break;
        }
        // Check if new meeting plans to end during existing meeting
        if ( ($requested_end > $exist_start) && ($requested_end < $exist_end) ) {
            $results["conflicts"]++;
            break;
        }
        // Check if existing meeting starts during new meeting
        if ( ($exist_start > $requested_start) && ($exist_start < $requested_end) ) {
            $results["conflicts"]++;
            break;
        }
        // Check if existing meeting ends during new meeting
        if ( ($exist_end > $requested_start) && ($exist_end < $requested_end) ) {
            $results["conflicts"]++;
            break;
        }
    }
}

var_dump( $results );

?>

答案 1 :(得分:0)

这应该是一个比它更直接的实现。如果您使用break,您基本上会说&#34;我找到了我想要的东西,完全退出了foreach。&#34;如果你使用continue,它只是退出当前的迭代(据我所知)并继续(看看他们做了什么,那里?)到下一次迭代。找到this "diagram"可以很好地解释它并且似乎适用于foreach循环,而不仅仅是while

while ($foo) {   <--------------------┐
    continue;    --- goes back here --┘
    break;       ----- jumps here ----┐
}                                     |
                 <--------------------┘

希望这有助于其他人下线!