2015年7月27日 星期一

使用Laravel artisan schedule:run時 exec被禁用時的替代方案

namespace App\Console;

use Artisan;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        'App\Console\Commands\Inspire',
    ];

    /**
     * Define the application's command schedule.
     *
     * @param \Illuminate\Console\Scheduling\Schedule $schedule
     */
    protected function schedule(Schedule $schedule)
    {
        // 當exec被disabled時只要改成使用Artisan::call('command')即可
        $schedule->call(function () {
             Artisan::call('inspire');
        })
        ->hourly();
    }
}

遠振主機上利用crontab執行 laravel artisan schedule:run

在專案中有個需求需要在固定時間去抓取固定資料 既然都已經使用laravel所以當然開始使用artisan寫寫console指令 於是很快速的寫完程式,當然第一時間就在自己本機上測試 測試的結果當然是一切都正常 所以很快的就把程式上傳到遠振主機上 並且設定了Cron的排程

* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1

設定完後,想說一切都妥當了, 但程式一直出錯 系統就回應

[ErrorException]
Invalid argument supplied foreach()

這要怎麼debug啊 而且明明在自己電腦內測試都能正常執行啊

所以只好開始研究程式碼囉,查到最後原來.....

遠振主機的php預設為 php-cgi 所以無法取得正確的參數 如果要artisan正常執行的話必須使用php-cli 所以在遠振主機上要執行artisan應該要改為

* * * * * /usr/bin/php-cli /path/to/artisan schedule:run 1>> /dev/null 2>&1

應該所有的cpanel主機只要是可選php版本的都會遇到這個問題......

php-cli和php-cgi兩個在console上執行的差異 php-cli 的參數會存入 $_SERVER['argv']; php-cgi的參數則會存入 $_GET; 如果要讓php-cgi能正常執行則可以用以下做法

if (empty($_GET) === false) {
    foreach ($_GET as $key => $value) {
        $_SERVER['argv'][] = $key;
    }
}