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

程式技術 sharkHead 10個月前 0

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

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

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

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

%E5%BF%AB%E6%A8%82%E6%B0%B0%E5%8C%96%E7%89%A9_%E5%96%9D%E9%A3%B2%E6%96%99.jpg
這傢伙到底在公三小?

這次部落格 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;

就大功告成拉!


Laravel 與 Python 菜雞工程師
喜愛研究程式相關技術
正在學習 TypeScript 與 Vue.js