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]) ?> <?= $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 ]) ?> ~ <?= $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
相关产品推荐
相关产品推荐

