將部落格的 Laravel 版本從 6 升級至 7,當中所遇到的問題

程式技術
sharkHead

花了點時間,將部落格的 Laravel 版本升級至 7。

原本想說反正 8 也快出來了, 不如直接 6 跳 8 (錯誤示範,官方建議是一版一版慢慢升級),省得升級兩次,麻煩,不過 Laravel 新版本推出的時候,可能會有套件突然無法支援的情況,所以如果就算 8 出來,建議還是觀望一下比較好,太早升級,可能就是第一批白老鼠。

基本上 Laravel 的升版有以下兩種方式。

  1. 跟著官方文件,一步一步修改受影響的地方。
  2. 土法煉鋼,直接開一個新專案重新寫。

一般當然是使用第一種,不過由於此部落格是小型專案,開一個重新寫其實沒什麼問題 (誤),大型的多人協作專案,如果你提議要重新寫一個,我想其他人的反應一定會是…

2021_07_14_14_01_16_60ee7dac32d5f.jpeg
這傢伙到底在公三小?

這次部落格 6 升級 7的過程算是非常順利,唯一有一個需要注意的點,就是對時間格式的更改,Laravel 中的 Carbon 套件的預設時間格式轉成 ISO-8601

原本的格式是 2019-12-02 20:01:00。

現在改為 2019-12-02T20:01:00.283041Z。

如果 faker 中使用 now() 這樣的方法,就會因為時間儲存格式不符合資料庫格式而發生錯誤。雖然文件中特別備註不影響資料儲存,但是當你使用 seed 填充假資料的時候,有可能就會發生時間格式上錯誤。

$ php artisan migrate:refresh --seed
PDOException::("SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2020-03-24T23:36:15.000000Z' for column `weibo`.`users`.`email_verified_at` at row 1")

論壇也有人遇到類似的事情:https://learnku.com/laravel/t/42337

其實官方也有說明,如果你想使用舊的時間格式,只要覆寫 serializeDate 方法就好,那具體要怎麼做呢?

就是在每個需要填入數據的 Model 加上以下這一段。

use DateTimeInterface;

protected function serializeDate(DateTimeInterface $date)
{
    return $date->format('Y-m-d H:i:s');
}

一開始我就是這麼做,但後來想想,這好像不符合 DRY (Don’t Repeat Yourself) 原則,所以上網研究一下,並換了一種方式。

首先,我的 Model 全部都是放在 app/Models 這個資料夾底下,因此我先在這邊再創一個資料夾 Traits

並在裡面新增一個檔案 SerializeDate.php,內容如下。

<?php

namespace App\Models\Traits;

use DateTimeInterface;

// 因 Laravel 7 調整了時間格式會導致 seeding 出錯,這裡對 serializeDate() 進行覆寫
trait SerializeDate
{
    /**
     * Prepare a date for array / JSON serialization.
     *
     * @param  \DateTimeInterface  $date
     * @return string
     */
    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }
}

這樣如果 User Model 需要調整時間格式,只要在 User.php 加入一行。

// trait SerializeDate
use Traits\SerializeDate;

就大功告成拉!

sharkHead
written by
sharkHead

後端打工仔,在下班後喜歡研究各種不同的技術。稍微擅長 PHP,並偶爾涉獵前端開發。個性就像動態語言般隨興,但渴望做事能像囉嗦的靜態語言那樣嚴謹。

0 則留言