laravel 在虛擬主機或共享主機使用 Schedule + command 的方法
在一些小型專案如果是買 web hosting or share hosting 的話,因為會有一些安全性限制,是無法在主機伺服器運行 exec 之類的指令,如果在 Schedule 使用這樣,那會噴錯
$schedule->command(
CheckScheduleLiveCommand::class, [
"message" => "1. 測試透過 Command 正常運行"
]
)->everyMinute();
上面這樣寫,會噴這樣的錯誤
[2023-10-21 13:31:02] production.ERROR: The Process class relies on proc_open, which is not available on your PHP installation. {"exception":"[object] (Symfony\\Component\\Process\\Exception\\LogicException(code: 0): The Process class relies on proc_open, which is not available on your PHP installation. at /home/powerstr/jetmonster.com.tw/laravel/vendor/symfony/process/Process.php:146)
原因是因為 php.ini (可以用 phpinfo(); 快速查看) 的 disable_functions 禁止使用 proc_open。但因為是共享主機啦,廠商通常也不會願意開放樣的限制,因此 Schedul 建議改用 call 這種寫法,全部交給 php 去執行時間上的判斷再去戳 command 的 script 會是最安全的做法。
// 在共享主機可以運行的作法
$schedule->call(function () {
Artisan::call(
CheckScheduleLiveCommand::class,
[
"message" => "4. 閉包 + Artisan 正常運行"
]
);
})->everyMinute();
最後附上我的 Schedule 測試方法供參考
Log::debug("[---------- checkSchedule Start ----------]");
// 如果沒有值,但表伺服器可能阻擋了 exec 的指令
$schedule->command(
CheckScheduleLiveCommand::class, [
"message" => "1. 測試透過 Command 正常運行"
]
)->everyMinute();
$schedule->call(function () {
Log::debug("2. 測試透過 call() 閉包");
})->everyMinute();
Artisan::call(CheckScheduleLiveCommand::class,
["message" => "3. 測試透過 Artisan 正常運行"]);
$schedule->call(function () {
Artisan::call(
CheckScheduleLiveCommand::class,
[
"message" => "4. 測試閉包 + Artisan 正常運行"
]
);
})->everyMinute();