You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CakePHP 3.2 如何创建保存带日期时间区间的表单并展示数据

CakePHP 3.2 日期时间区间存取方案

1. 调整表单模板(ctp文件)

首先要给所有表单控件加上明确的name属性,方便后端获取提交值,推荐直接使用CakePHP自带的表单助手,还能自动处理编辑场景的默认值回填:

<tr>
    <th>date</th>
    <th class="require"><span class="red">※</span></th>
    <td colspan="3">
        <?= $this->Form->control('date', ['type' => 'text', 'class' => 'calendar', 'label' => false]) ?>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <?= $this->Form->control('start_hour', [
            'type' => 'select',
            'options' => range(0,23),
            'label' => false,
            'value' => isset($record) ? $record->start_time->format('H') : 0
        ]) ?>:
        <?= $this->Form->control('start_min', [
            'type' => 'select',
            'options' => array_combine(range(0,59), array_map(fn($i) => str_pad($i,2,'0',STR_PAD_LEFT), range(0,59))),
            'label' => false,
            'value' => isset($record) ? $record->start_time->format('i') : 0
        ]) ?>
        &nbsp;&nbsp;~&nbsp;&nbsp;
        <?= $this->Form->control('end_hour', [
            'type' => 'select',
            'options' => range(0,23),
            'label' => false,
            'value' => isset($record) ? $record->end_time->format('H') : 0
        ]) ?>:
        <?= $this->Form->control('end_min', [
            'type' => 'select',
            'options' => array_combine(range(0,59), array_map(fn($i) => str_pad($i,2,'0',STR_PAD_LEFT), range(0,59))),
            'label' => false,
            'value' => isset($record) ? $record->end_time->format('i') : 0
        ]) ?>
    </td>
</tr>

如果坚持用原生HTML,只要给每个控件加上对应name属性即可,比如<input name="date" type="text" class="calendar" value="">。


2. 后端控制器处理保存逻辑

拿到提交数据后,把选中的日期分别和起止时分拼接成合法的datetime格式,再赋值给对应字段保存即可,示例代码(以Records模型为例,可替换为你自己的模型名):

public function add()
{
    $record = $this->Records->newEmptyEntity();
    if ($this->request->is('post')) {
        $data = $this->request->getData();
        // 拼接开始时间
        $startStr = $data['date'] . ' ' . str_pad($data['start_hour'],2,'0',STR_PAD_LEFT) . ':' . str_pad($data['start_min'],2,'0',STR_PAD_LEFT) . ':00';
        $data['start_time'] = \Cake\I18n\FrozenTime::createFromFormat('Y-m-d H:i:s', $startStr);
        // 拼接结束时间
        $endStr = $data['date'] . ' ' . str_pad($data['end_hour'],2,'0',STR_PAD_LEFT) . ':' . str_pad($data['end_min'],2,'0',STR_PAD_LEFT) . ':00';
        $data['end_time'] = \Cake\I18n\FrozenTime::createFromFormat('Y-m-d H:i:s', $endStr);
        // 赋值并保存
        $record = $this->Records->patchEntity($record, $data);
        if ($this->Records->save($record)) {
            $this->Flash->success('保存成功');
            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error('保存失败,请检查输入内容');
    }
    $this->set(compact('record'));
}

如果你的日期选择器输出格式不是Y-m-d,同步修改createFromFormat方法的第一个参数即可,比如日期格式为m/d/Y就改为m/d/Y H:i:s。


3. 视图层展示已保存的时间区间

查询结果中的start_time和end_time默认是CakePHP封装的FrozenTime对象,直接调用format方法自定义输出格式即可:

<!-- 输出效果示例:2024-05-20 09:00 ~ 18:30 -->
<p>预约时间:<?= $record->start_time->format('Y-m-d H:i') ?> ~ <?= $record->end_time->format('H:i') ?></p>

因为你的表单设计是选择同一天的时间区间,所以结束时间不需要重复输出日期。


注意事项

  • 可增加前端校验逻辑,确保提交的结束时间晚于开始时间,减少无效数据入库
  • 如果保存时出现字段无法赋值的错误,检查对应Table类的$_accessible属性,确保start_time和end_time被设置为允许批量赋值

内容的提问来源于stack exchange,提问作者unknown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:45:03