Cakephp 3不保存datetime [英] Cakephp 3 not saving datetime

查看:276
本文介绍了Cakephp 3不保存datetime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试从cakephp 3表单保存数据。所有数据都保存得很好,但datetime不。我有2个datetime字段。这些字段由jquery-ui小部件填充。



pacthing实体时发生问题。

  $ 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) p>

 'id'=> (int)3,
'user_id'=> (INT)1,
'description'=> 'test',
'starttime'=> null,
'endtime'=> null
...

starttime和endtime变为null,我不明白为什么。



之前是否有这个pb?



我试过调试和理解,修补
和datetime字段在mysql是确定。

  $ intervention-> starttime = date('Ymd H:i:s',strtotime($ this-> request - > data ['starttime'])); 
$ intervention-> endtime = date('Y-m-d H:i:s',strtotime($ this-> request-> data ['endtime'])))

感谢您的帮助

解决方案

以区域设置感知的方式投放/解析日期/时间值






更新:是与3.2.5之前的CakePHP应用程序模板版本的默认行为。从3.2.5开始,语言环境解析在默认情况下不再被启用,这将使解析器期望默认值为 Ymd H:i:s






在编组过程中,根据相应的列类型转换值。对于 DATETIME 列,这是通过 \Cake\Database\Type\DateTimeType 类型类完成的。



确切地说,这是在 \Cake\Database\Type\DateTimeType :: marshall()

使用默认的应用模板配置, DateTypeType 配置为使用区域设置感知解析,并且由于未设置默认区域设置格式, \Cake\I18n\Time :: parseDateTime() 将根据默认的字符串格式 ( 时间:: $ _ toStringFormat ),默认为语言环境感知 [IntlDateFormatter :: SHORT,IntlDateFormatter :: SHORT]



因此,如果您的语言环境设置为 en_US ,那么该值将被解析为预期格式 M / d / yy,h:mm a ,这样你的值就不适合,因此你最终会得到



使解析器使用正确的格式



tl; dr



如果jQuery小部件的格式未在您的应用程序中的任何位置使用,您可以例如临时设置正确的语言环境格式,禁用语言区域解析,如

  $ dateTimeType = Type :: build('datetime') - > setLocaleFormat('yyyy / MM / dd HH:mm'); 

// ...
$ intervention = $ this->干预 - > 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);

请注意,这将影响所有日期/时间输入,不只是您的开始时间 endtime 字段!



另一方面,jQuery小部件使用的格式是您希望在整个应用程序中使用的格式,然后更改默认格式也可以这样做,例如

 使用Cake\I18n\Time; 
Time :: setToStringFormat('yyyy / MM / dd HH:mm');在您的 bootstrap.php 中的



<注意,还有 Time :: setJsonEncodeFormat() Time :: $ niceFormat



另请参阅





在编组之前转换输入



另一种选择是将数据转换为 Time 实例在编组过程之前。



在你的 InterventionsTable 类中可能会出现这样的问题也可以放在行为或外部监听器中):

 使用Cake \Event\Event; 
使用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>数据库访问& ORM>保存数据>修改实体之前修改请求数据


I try to save data from a cakephp 3 form. All data are well saved but datetime not. I've got 2 datetime fields. Those fields are filled by jquery-ui widget.

The problem seems to happened when pacthing entity.

$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);

  • Debug of $this->request->data :

    'user_id' => '1',
    'description' => 'test',
    'starttime' => '2015/11/15 10:00',
    'endtime' => '2015/11/15 12:10'
    

  • Debug of my object $intervention after pacthEntity :

object(App\Model\Entity\Intervention)

'id' => (int) 3,
'user_id' => (int) 1,
'description' => 'test',
'starttime' => null,
'endtime' => null
...

starttime and endtime become null and I don't understand why.

Is somebody had this pb before ?

I tried (for debuging and understanding) to force fields value afer patching and datetime fields in mysql are ok.

$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']));

Thanks for help

解决方案

Date/time values are being casted/parsed in a locale aware fashion


Update: this is the default behavior with the CakePHP application template versions prior to 3.2.5. As of 3.2.5 locale parsing is not enabled by default anymore, which will make the parser expect a default of Y-m-d H:i:s instead.


In the marshalling process, values are being "casted" according to the respective column types. For DATETIME columns, this is done by the \Cake\Database\Type\DateTimeType type class.

To be exact, this is done in \Cake\Database\Type\DateTimeType::marshall().

With the default app template configuration, DateTypeType is configured to use locale aware parsing, and since no default locale format is being set, \Cake\I18n\Time::parseDateTime() will parse the values according to its default "to string format" (Time::$_toStringFormat), which defaults to the locale aware [IntlDateFormatter::SHORT, IntlDateFormatter::SHORT].

So, if for example your locale is set to en_US, then the value would be parsed with an expected format of M/d/yy, h:mm a, which your value wouldn't fit, and hence you'd finally end up with null being set for the entity property.

Make the parser use the proper format

tl;dr

In case the format for the jQuery widget is not being used everywhere in your app, you could for example either temporarily set the proper locale format, or disable locale parsing, like

$dateTimeType = Type::build('datetime')->setLocaleFormat('yyyy/MM/dd HH:mm');

// ...
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
// ...

$dateTimeType->setLocaleFormat(null);

or

$dateTimeType = Type::build('datetime')->useLocaleParser(false);

// ...
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
// ...

$dateTimeType->useLocaleParser(true);

It should be noted that this will affect all date/time input, not just your starttime and endtime fields!

Should the format used by the jQuery widget on the other hand be the format that you wish to use all the way through your app, then changing the default format could do it too, like

use Cake\I18n\Time;
Time::setToStringFormat('yyyy/MM/dd HH:mm');

in your bootstrap.php. Note that there's also Time::setJsonEncodeFormat() and Time::$niceFormat which you may want to modify too.

See also

Convert the input before marshalling it

Another option would be to for example convert the data to Time instances before the marshalling process. This would avoid possible problems with the previous mentioned solution that would affect all input.

In your InterventionsTable class (could also be put in a behavior or an external listener):

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');
        }
    }
}

See also

Cookbook > Database Access & ORM > Saving Data > Modifying Request Data Before Building Entities

这篇关于Cakephp 3不保存datetime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆