我尝试从cakephp 3表格中保存数据。所有数据都保存得很好,但日期时间没有。我有2个日期时间字段。这些字段由jquery-ui小部件填充。
当实体化时,问题似乎发生了。
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
调试$ this-> request-> data:
'user_id' => '1',
'description' => 'test',
'starttime' => '2015/11/15 10:00',
'endtime' => '2015/11/15 12:10'
在pacthEntity之后调试我的对象$干预:
对象(App \ Model \ Entity \ Intervention)
'id' => (int) 3,
'user_id' => (int) 1,
'description' => 'test',
'starttime' => null,
'endtime' => null
...
starttime和endtime变为null,我不明白为什么。
以前有人有这个pb吗?
我尝试(用于调试和理解)在修补时强制字段值 和mysql中的datetime字段都可以。
$intervention->starttime = date('Y-m-d H:i:s', strtotime($this->request->data['starttime']));
$intervention->endtime = date('Y-m-d H:i:s', strtotime($this->request->data['endtime']));
感谢您的帮助
答案 0 :(得分:19)
更新:这是3.2.5之前的CakePHP应用程序模板版本的默认行为。从3.2.5开始,默认情况下不再启用语言环境解析,这将使日期/时间编组逻辑期望默认格式为Y-m-d H:i:s
。
在编组过程中,根据相应的列类型对值进行“转换”。对于DATETIME
列,这由\Cake\Database\Type\DateTimeType
类型类完成。
确切地说,这是在 \Cake\Database\Type\DateTimeType::marshall()
中完成的。
使用默认的应用模板配置,DateTimeType
配置为使用区域设置感知解析,并且由于未设置默认的区域设置格式, \Cake\I18n\Time::parseDateTime()
将根据值解析值默认为“字符串格式”( Time::$_toStringFormat
),默认为区域设置[IntlDateFormatter::SHORT, IntlDateFormatter::SHORT]
。
因此,如果您的语言环境设置为en_US
,那么该值将使用预期格式M/d/yy, h:mm a
进行解析,您的值不适合,因此您最终最终为实体属性设置了null
。
TL;博士
如果jQuery小部件的格式未在应用程序的任何位置使用,您可以例如临时设置正确的区域设置格式,或者禁用区域设置解析,例如
// for time- or date-only comlumn types you'd use 'time' or 'date' instead of 'datetime'
$dateTimeType = Type::build('datetime')->setLocaleFormat('yyyy/MM/dd HH:mm');
// ...
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
// ...
$dateTimeType->setLocaleFormat(null);
或
$dateTimeType = Type::build('datetime')->useLocaleParser(false);
// ...
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
// ...
$dateTimeType->useLocaleParser(true);
应该注意,这会影响所有日期/时间输入,而不仅仅是starttime
和endtime
字段!
另一方面,jQuery小部件使用的格式应该是您希望在应用程序中使用的格式,然后更改默认格式也可以这样做,例如
use Cake\I18n\Time;
use Cake\I18n\FrozenTime;
// To affect date-only columns you'd configure `Date` and `FrozenDate`.
// For time-only columns, see the linked SO question below.
Time::setToStringFormat('yyyy/MM/dd HH:mm');
FrozenTime::setToStringFormat('yyyy/MM/dd HH:mm');
在bootstrap.php
中。请注意,您可能还需要修改Time/FrozenTime::setJsonEncodeFormat()
和Time/FrozenTime::$niceFormat
。
另见
另一种选择是在编组过程之前将数据转换为Time
个实例。这可以避免前面提到的解决方案可能会影响所有输入的问题。
在您的InterventionsTable
课程中(也可以放入行为或外部听众):
use Cake\Event\Event;
use Cake\I18n\Time;
...
public function beforeMarshal(Event $event, \ArrayObject $data, \ArrayObject $options)
{
foreach (['starttime', 'endtime'] as $key) {
if (isset($data[$key]) && is_string($data[$key])) {
$data[$key] = Time::parseDateTime($data[$key], 'yyyy/MM/dd HH:mm');
}
}
}
另见
<强> Cookbook > Database Access & ORM > Saving Data > Modifying Request Data Before Building Entities 强>