使用PHP显示SQL数据库中的重复日期

sou*_*ous 0 php mysql

我正在访问由另一家网络公司创建的数据库,以检索当前客户端的事件信息.我的客户输入事件信息,并注明日期是否经常发生.我正在尝试显示所有重复日期.到目前为止,我已经能够显示所有内容,定期日期以及重复发生.

表格如下:

  • 活动
  • Events_Recurring

这是Events表BIGGER PICTURE的一部分

事件表

这就是Events_Recurring表的样子

事件反复出现的表

当客户端将其检查为重复发生时,events_recurring表会创建一个包含事件ID的行以及其他信息,例如事件重复发生的星期几或月份.

我只是不确定如何显示重复出现的某个ID的倍数.我有一个开始日期,我可以访问的结束日期,以及它重复出现的一周中的哪一天.

例如:如果此事件每周四重新发生.我知道它从1月1日开始到1月31日结束,我是否能够完成这个并且在1月的每个星期四的日期中吐出4个不同的事件?

这是我正在使用的完整代码,在尝试解决这个问题时有点混乱.我正在检查底部的重现

// Access external database
$events_db = new wpdb(TOP SECRET CREDENTIALS HERE);
$events_db->show_errors();

if ($events_db) :
    // Query Events Database
    $events = $events_db->get_results(
        "
        SELECT ID, RequestDateStart, RequestDateEnd, Ministry, RequestTimeStart, EventName, CoordinatorName, EventDescription, Location
        FROM gc_events
        WHERE PrivateEvent = 0
        AND Ministry = 15
        AND date(RequestDateStart)>=date(NOW())
        ORDER BY RequestDateStart
        "
    );

    // Create the event data that will be displayed
    foreach ($events as $event) :

        // Store Event ID in a variable
        $masterID = $event->ID;

        echo '<div class="col-12">';

        echo '<strong>ID:</strong> ' . $event->ID . '<br /><strong>Event Name:</strong> ' . $event->EventName . '<br /><strong>Leader:</strong> ' . $event->CoordinatorName . '<br /><strong>Date:</strong> ' . date('l, F j',strtotime($event->RequestDateStart)) . '<br /><strong>Start Time:</strong> ' . date('g:i a',strtotime($event->RequestTimeStart));

        // CHECK IF RECURRING

        $recurring_events = $events_db->get_results(
            "
            SELECT gc_event_id, period, day
            FROM gc_event_recurring
            WHERE gc_event_id = '$masterID'
            "
        );

        foreach ($recurring_events as $recurring_event) :
        if ($recurring_event->period === 'week') {

        echo '<div class="col-12"><strong>&uarr; WEEKLY</strong><br />';

        echo $recurring_event->day;

        echo '</div>';

        }
        endforeach;

        echo '</div>';

    endforeach;
endif;
Run Code Online (Sandbox Code Playgroud)

我现在得到的结果(重复发生的事件)是

事件:每周祷告
日期:2013年2月1日

我想要的结果是

事件:每周祷告
日期:2013年2月1日

事件:每周祷告
日期:2013年2月8日

活动:每周祷告
日期:2013年2月15日

事件:每周祷告
日期:2013年2月22日


如果开始日期是2月1日,结束日期是2月28日,那就是这样.

tha*_*tah 11

一句忠告.

虽然从设计的角度来看,设计一个数据库来存储重复模式的"描述"是一种非常干净的方法,但是你可能会遇到很多问题.

我已经做了类似的方法一个项目前一阵子(我将查找数据库设计,并添加到我的答案),虽然我能够重现的确切日期/重复事件的时候,你会碰上在以下情况下出现问题; 大多数起源于此:

定期事件描述重复模式,因此实际(个别)事件不是数据库中的物理记录

  1. 如果客户决定添加新事件,您将如何检查它是否与任何现有事件重叠?您必须根据重复模式计算所有"事件".
  2. 如果客户决定需要改变预定的时间的事件,你怎么会有这种变化适用于所有未来的事件,而不是为那些在过去的事件(你必须复制的原始事件,修改其结束-date,并使用新的开始日期设置重复的事件)
  3. 如果客户决定他想要删除从重复模式,单日(例如,单个事件奔取消),您也将有原始事件拆分成2次独立的重复,有一个"取消/阻塞"日期/时间表
  4. 如果人们需要"书"的特定事件,您将无法将其连接到一个"真正"的事件记录,因为个别事件,因为它们不是在数据库中实际存在.例如,要检查单个事件是否可以重新调度或取消,您需要从代码执行此操作,因为数据库无法使用外键约束来自动更新相关预留
  5. 关于表现; 因为个别事件没有物理存储,所以每次要显示它们都必须计算它们.考虑在数据库中有1000个重复发生的事件,并尝试在两年后显示第23周的"日历".您必须分析所有重复事件模式并计算它们产生的所有事件!

一切都取决于你的系统的实际使用情况,但我想警告你我们遇到的问题.

这是'schedule'表的模式(包含重复发生的事件模式);

CREATE TABLE IF NOT EXISTS `schedules` (
  `id`              int(11)     NOT NULL auto_increment,
  `date_start`      date        NOT NULL,
  `time_start`      time        NOT NULL,
  `time_end`        time        NOT NULL,
  `recur_until`     date        default NULL COMMENT 'end date when recurrence stops',
  `recur_freq`      varchar(30) default NULL COMMENT 'null, "secondly", "minutely", "hourly", "daily", "weekly", "monthly", "yearly"',
  `recur_interval`  smallint(5) unsigned default NULL COMMENT 'e.g. 1 for each day/week, 2 for every other day/week',
  `recur_byday`     smallint(5) unsigned default NULL COMMENT 'BITWISE; monday = 1, sunday = 64',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
Run Code Online (Sandbox Code Playgroud)

如何规避所描述的问题

完全描述这些问题的解决方案在这里可能不合适,但这里有一些需要考虑的事情;

如本身所述存储重复发生的事件并非不好的做法.它完美地描述了事件发生的时间和频率.但是,实际事件缺乏物理记录是导致问题的原因.

  1. 创建修改重复发生的事件,计算产生的所有事件,并将其存储为物理记录.可以查询这些记录,可以附加"预留",并且您将能够利用数据库功能(如外键约束)来正确处理它们.
  2. 当存储如1.中所述的各个事件时,请确保您保留对它们所属的"计划"的引用.如果(例如)客户想要更改周期性事件的时间,您将能够更新所有相关(个别)事件.
  3. 请记住,在情境2中,您可能只想更新未来事件,因此"重复事件"仍然需要"拆分"为两个才能实现.在这种情况下,"未来"事件需要与新的"经常性事件"相关联,旧事件将依附于现有的"重复事件"

在数据库/软件设计上投入时间,正确调查设计是否"适用"您想要实现的目标.测试它,尝试的东西,如果他们不工作,不要犹豫,"把它扔掉",往往更容易从头开始不是试图"修复"的东西.一个合适的设计需要花费时间,并可能需要几次"重新设计"才能使它正确,但它最终将为您节省时间和金钱.

希望这有帮助,祝你好运!