2016-06-10 2 views
1

У меня есть модель с мутаторами даты, например created_at. Скажем, общее свойство timestamp.Laravel5 Красноречивый мутатор по умолчанию неудачно с вводом даты JSON

При передаче данных от клиента в формате JSON, я буду получать

{ 
    timestamp: "2016-06-07T22:00:00.000Z" 
} 

Это свойство будет использоваться, чтобы установить некоторые модели, как так:

$model = new Foo(); 
$model->timestamp = Input::get('timestamp'); 

Поскольку это вызовет дату мутатор, PHP Carbon вызывается и не с

InvalidArgumentException in Carbon.php line 425 
Unexpected data found. 
Trailing data 

Теперь, это не проблема с самим Carbon, которая способна обрабатывать форматы JSON. Если вы попробуете

new Carbon('2016-06-07T22:00:00.000Z'); 

Вы получите инфляционный результат, ожидаемый результат.

Из того, что я вижу, проблема возникает из-за странного красноречивого поведения. Смотрите этот след от выше InvalidArgumentException in Carbon.php line 425:

in Carbon.php line 425 
at Carbon::createFromFormat('Y-m-d H:i:s', '2016-06-07T22:00:00.000Z') in Model.php line 2915 
at Model->asDateTime('2016-06-07T22:00:00.000Z') in Model.php line 2871 
at Model->fromDateTime('2016-06-07T22:00:00.000Z') in Model.php line 2826 
at Model->setAttribute('timestamp', '2016-06-07T22:00:00.000Z') in Model.php line 3351 

Eloquent пытается createFromFormat пропусканием плохого формата которого Doesnt зеркала фактического формата JSON, который вызывает исключение углерода.

С другой стороны, простой вызов, такой как вышеупомянутый new Carbon($jsonDate), будет работать в этом случае.

  1. Как я должен подойти, чтобы решить эту проблему?
  2. Разве это не должно быть красноречивой ошибкой?

== EDIT ==

я не закодировать любую мутаторный себя. Я использую даты по умолчанию мутаторов так:

public function getDates() { 
    return ['timestamp']; 
} 
+0

Это должно работать должным образом. Как вы определяете мутатор? Можете ли вы опубликовать код модели и точное значение 'Input :: get ('timestamp)' (я предполагаю, что это не объект). Я оставлю мутатор, который я установил здесь, чтобы проверить: 'public function setTimestampAttribute ($ value) {$ this-> attributes ['timestamp'] = new \ Carbon \ Carbon ($ value); } 'и код контроллера:' $ obj-> timestamp = '2016-06-07T22: 00: 00.000Z'; ' –

+0

Пожалуйста, разместите свой мутатор. –

+0

Я не использую какой-либо пользовательский мутатор, см. Edit. – brazorf

ответ

1

Eloquent анализирует дату, вы даете его, когда атрибут установлен в функции getDates.

В это анализирует четыре этапа: (см Modal.phpasDateTime способ осветления, код довольно хорошо прокомментирован: https://github.com/illuminate/database/blob/master/Eloquent/Model.php#L2898)

  1. Если это уже экземпляр углерода, использовать что
  2. Если это является примером реализации DateTimeInterface, использовать что
  3. Если это числовое, синтаксический как Отметка времени Unix
  4. Если это простой год месяц день формат (судимым регулярное выражение) использовать, что
  5. Если ни один из вышеперечисленных, не создать экземпляр Carbon с форматом вы определяете по умолчанию

В вас случае, 1-4 не совпадают, поэтому он пытается 5.

У вас нет пользовательских dateFormat, указанный в модели, поэтому он использует формат даты по умолчанию, применимый к типу подключения к базе данных, которое вы используете. Вы можете изменить это, добавив переменную $ DateFormat модели:

protected $dateFormat = 'U';

Но ваши нормальные метки времени, вероятно, в правильном формате уже. Таким образом, это решение не сработает для вас.

В вашем случае я бы просто сделать: $model->timestamp = Carbon::parse(Input::get('timestamp'));

Или используйте Carbon::createFromFormat() с соответствующим форматом.

Я точно не знаю, почему они не просто разбирают его с помощью Carbon напрямую. Я думаю, что это более склонный к ошибкам и менее контролируемый. В разных международных форматах вы можете получить неожиданный результат (месяц и день и т. Д.). Это может также быть медленнее, чем их нынешний подход.

Смежные вопросы