Laravel 專案有更新時,部屬後除了需要做 database migration 以外,還要清理暫存:
- artisan route:clear
- artisan config:clear
- artisan cache:clear
- artisan view:clear
- …..
偷懶一點,可以使用 optimize 指令一次做完:
php artisan optimize:clear
軟體開發、伺服器和生活瑣事
Laravel 專案有更新時,部屬後除了需要做 database migration 以外,還要清理暫存:
artisan route:clearartisan config:clearartisan cache:clearartisan view:clear偷懶一點,可以使用 optimize 指令一次做完:
php artisan optimize:clear
在 Eloquent 中,假設要刪除某使用者的資料:
User::select(['name'])->chunk(100, function ($users) {
    foreach ($users as $user) {
        if ( condition ) {
            $user->delete();
        }
    }
}
以上的寫法,在 $user->delete(),即使 Model 回傳刪除成功,但實際上資料庫的資料不會被刪除。
原因是 Eloquent 刪除資料是以 id 欄位為準,若 select 不包含 id 則會刪除失敗。
在 select() 中加入 id 即可正常刪除資料:
User::select(['id', 'name'])->chunk(100, function ($users) {
    // ....
}
ps. 文件沒寫,fu …..
在 .env 設定檔中,遇到有特殊字元的密碼:
DB_PASS=password#2023在 ini 中 # 剛好代表註解起始點,結果 DB 一直登入失敗。
比較保險的寫法,應該是在所有的字串都加上引號:
DB_PASS="password#2023"不只 .ini,k8s 常用的 yml 中的字串也是應該加上引號,特別是 yml 雷還比較多 …
在 Laravel 中想要實作 route:
Route::get('domain/{name}')
    ->where('name', '[\w\d\.]+');
但在 local 的環境上一直顯示 404 NOT FOUND。
後來注意到 PHP build-in server (php -S) 的 log 中有顯示:
[404]: GET /whois/zeroplex.tw - No such file or directory
表示 PHP 把 zeroplex.tw 視為一個檔案,嘗試尋找並執行,當然會變成 404。
若將環境改為 Nginx + php-fpm 就不會遇到這個錯誤了。
參考資料:php – Route with dot (IP address) not found, returns 404 – Stack Overflow
Laravel 的 queue worker 與 Horizon 需要透過 artisan queue:work 在背景執行,若可以的話,再使用 systemd 或 supervisor 來監控運作狀態。
不過 systemd 和 supervisor 都需要 root 權限來操作,說起來蠻麻煩的,所以寫了一小段 shell script 來啟動與停止,沒辦法在 worker 中斷時 restart,但可以做 graceful start & shutdown。
啟動 queue worker:
./artisan queue:work \
    --no-interaction --no-ansi >> storage/logs/queue.log 2>&1 &
# 透過 $? 來檢查指令執行是否成功
if [ $? -ne 0 ]; then
    echo "FAILED !"
else
    echo "OK"
fi
停止所有的 queue worker:
# queue:restart 會送訊號給所有的 worker 來 graceful shutdown
./artisan queue:restart --quiet --no-ansi
# 檢查是否所有的 proccess 都停止
while [ 1 ]; do
    QUERY="$(ps -ef | grep queue:work | grep -v grep)"
    if [ -z "${QUERY}" ]; then
        break
    else
        sleep 1
    fi
done
echo "OK"
Laravel Horizon 的操作相對簡單一些。
啟動 Horizon:
./artisan horizon \
    --quiet --no-interaction --no-ansi >> storage/logs/horizon.log 2>&1 &
if [ $? -ne 0 ]; then
    echo "FAILED !"
else
    echo "OK"
fi
停止 Horizon:
artisan horizon:terminate --quiet --no-interaction --no-ansi
# 檢查 proccess 是否終止
while [ 1 ]; do
	QUERY="$(ps -ef | grep horizon | grep -v grep)"
	if [ -z "${QUERY}" ]; then
		echo "OK"
	else
		sleep 1
	fi
done