Подтвердить что ты не робот

Углерод в Laravel 4 InvalidArgumentException - обнаружены неожиданные данные. Трейлинг данных

Я пытаюсь получить результат запроса Eloquent для DB::raw("DATE_FORMAT(created_at, '%m-%d-%Y %r') AS created_at"), но каждый раз, когда получаю это исключение от Carbon:

InvalidArgumentException
Unexpected data found. Trailing data

Если я изменю его только на created_at вместо использования функции MySQL DATE_FORMAT(), тогда он получит данные без проблем.

Я не только сделал такое форматирование даты без проблем, но я проверил каждое поле в таблице базы данных (для этого семестра всего 10), и каждый из них является стандартной допустимой датой, поэтому мне интересно, почему Углерод подает подгонку.

Запуск этого в Laravel 4.1.

4b9b3361

Ответ 1

В ответе Eloquent запроса (модели) каждое поле date является углеродным объектом, это означает, что если вы запрашиваете модель, содержащую любой timestamp, как created_at, updated_at (в основном создается с помощью timestamps() во время миграции) и deleted_at, Laravel преобразует их в объект Carbon, и вы можете использовать любые общедоступные методы Carbon, например

$user = User::find(1);

// '2014-04-20 19:02:09' will become 'Apr 20, 2014'
$user->created_at->toFormattedDateString();

Таким образом, вы можете напрямую использовать любой открытый метод Carbon в поле timestamp, доступном в модели. Если вы попробуете это:

dd($user->created_at);

Тогда вывод будет:

object(Carbon\Carbon)[456]
  public 'date' => string '2014-04-20 19:02:09' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)

Итак, если вы хотите format дату, вы можете использовать:

// outputs like: 'Sunday 20th of April 2014 07:02:09 PM'
$user->created_at->format('l jS \\of F Y h:i:s A')

Обновление:

Если вы хотите изменить это поведение, это означает, что если вы хотите сообщить Laravel, что, какие поля должны быть автоматически преобразованы в объект Carbon, вы можете переопределить это, создав метод в вашей модели, например:

public function getDates()
{
    // only this field will be converted to Carbon
    return array('updated_at');
}

Чтобы полностью отключить мутации даты, просто верните пустой массив из метода getDates. Подробнее см. Мутаторы даты на веб-сайте Laravel.

Ответ 2

Я понимаю, что исходный вопрос относится к MySQL, но у меня была такая же ошибка с MSSQL. Проблема заключалась в том, что тип столбца столбца datetime для MSSQL имеет точность 0,001 секунды, но я не задавал формат модели:

protected function getDateFormat()
{
    return 'Y-m-d G:i:s';
}

Используя новый тип столбца DateTime2 и отключив точность, я исправил ошибку. То есть.

datetime2(0)

Вы могли бы изменить формат в getDateFormat, конечно.

Ответ 3

Если это помогает кому-то еще, я получаю ту же ошибку при попытке скопировать дату.

$user->last_login = Carbon::now();

if ($user->first_login < Carbon::createFromDate(2000, 1, 1)) {
    // This is the users first login
    $user->first_login = $user->last_login; // FAILS!
}

Оказывается, Laravel присваивает значение $user->last_login строке DateTime + Timezone. Это уже не объект Carbon.

Вы можете исправить ошибку, используя копии одного объекта Carbon (пример ниже) или путем установки мутаторов (сеттеров) в базовой модели.

$now = Carbon::now();
$user->last_login = $now;

if ($user->first_login < Carbon::createFromDate(2000, 1, 1)) {
    // This is the users first login
    $user->first_login = $now;
}