laravel中使用command实现crontab
發表於 : 2017-03-12 11:49:33
http://shaofei.leanote.com/post/laravel%E4%B8%AD
laravel5+版本支持基于框架的定时任务,在框架提供的各种组件的基础上进行业务处理,最底层调用exec()函数执行linux命令。
app\Console\Kernel.php是定时任务和artisan命令的核心文件。
Kernel类的schedule()方法内部可以定义需要系统托管的各种逻辑,简单使用如下:
protected function schedule(Schedule $schedule)
{
//开奖逻辑
$schedule->call(function(){
...
})->everyMinute();
//多期参与逻辑
$schedule->call(function(){
...
})->dailyAt('00:00');
}
项目有多个定时任务逻辑且个别逻辑可能单独执行或者对新的逻辑进行测试时,需要使用Artisan命令配合进行。
比如把开奖的逻辑抽离出来封装为一个artisan命令:
php artisan make:console Kaijiang
会在app/Console/Commands/目录下生成Kaijiana.php,Kaijiang类的handle()方法在该命令被调用时执行,该类的
signature属性为调用该命令时的artisan参数,示例代码如下:
class Kaijiang extends Command
{
protected $signature = 'zerogo:kaijiang';
protected $description = 'Command description.';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$effect = DB::update('update users set exp = exp + 1 where id = 10000');
if($effect){
echo "updated successfully \n";
}else{
echo "nothing effects \n";
}
}
}
handle()方法内,对users表id位10000的数据进行更新,该类的signature字段为’zerogo:kaijiang’,所以artisan
命令执行时参数为zerogo:kaijiang。定义命令之后需要修改Kernel类的commands属性来被框架识别。
class Kernel extends ConsoleKernel
{
protected $commands = [
\App\Console\Commands\Inspire::class,
\App\Console\Commands\Kaijiang::class,
];
...
添加之后便可在命令行执行测试(项目根目录):
php artisan zerogo:kaijiang
2015-09-22 17:50:10updated successfully
需要单独执行时在项目根目录执行命令即可,参数是类的signature属性。
在Kernel类的schedule()方法中调用命令即可进行托管:
$schedule->command('zerogo:kaijiang')->everyMinute()->sendOutputTo('/var/logs/zerogo.log');
多个独立逻辑的定时拆分为不同的artisan command即可,最后在Kernel的schedule()方法进行调用,
sendOutputTo()方法可以把echo等打印的信息进行保存,参数是文件路径,有个问题是这样执行zerogo.log
的内容不是append的,而是进行覆盖,底层执行的逻辑类似:
php demo.php > /var/log/zerogo.log 2>&1
解决方法是搞两个日志文件,Kernel的schedule()函数每分钟执行一次,每次取zerogo.log的内容append到另一个
日志文件。
还有一个emailOutputTo()方法可以把打印的日志信息以邮件形式发出(没测试,以后可能会用到)。
这些都准备好之后在服务器:
crontab -e
* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1
schedule:run是框架自带的artisan命令,执行Kernel.php的schedule()函数
laravel5+版本支持基于框架的定时任务,在框架提供的各种组件的基础上进行业务处理,最底层调用exec()函数执行linux命令。
app\Console\Kernel.php是定时任务和artisan命令的核心文件。
Kernel类的schedule()方法内部可以定义需要系统托管的各种逻辑,简单使用如下:
protected function schedule(Schedule $schedule)
{
//开奖逻辑
$schedule->call(function(){
...
})->everyMinute();
//多期参与逻辑
$schedule->call(function(){
...
})->dailyAt('00:00');
}
项目有多个定时任务逻辑且个别逻辑可能单独执行或者对新的逻辑进行测试时,需要使用Artisan命令配合进行。
比如把开奖的逻辑抽离出来封装为一个artisan命令:
php artisan make:console Kaijiang
会在app/Console/Commands/目录下生成Kaijiana.php,Kaijiang类的handle()方法在该命令被调用时执行,该类的
signature属性为调用该命令时的artisan参数,示例代码如下:
class Kaijiang extends Command
{
protected $signature = 'zerogo:kaijiang';
protected $description = 'Command description.';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$effect = DB::update('update users set exp = exp + 1 where id = 10000');
if($effect){
echo "updated successfully \n";
}else{
echo "nothing effects \n";
}
}
}
handle()方法内,对users表id位10000的数据进行更新,该类的signature字段为’zerogo:kaijiang’,所以artisan
命令执行时参数为zerogo:kaijiang。定义命令之后需要修改Kernel类的commands属性来被框架识别。
class Kernel extends ConsoleKernel
{
protected $commands = [
\App\Console\Commands\Inspire::class,
\App\Console\Commands\Kaijiang::class,
];
...
添加之后便可在命令行执行测试(项目根目录):
php artisan zerogo:kaijiang
2015-09-22 17:50:10updated successfully
需要单独执行时在项目根目录执行命令即可,参数是类的signature属性。
在Kernel类的schedule()方法中调用命令即可进行托管:
$schedule->command('zerogo:kaijiang')->everyMinute()->sendOutputTo('/var/logs/zerogo.log');
多个独立逻辑的定时拆分为不同的artisan command即可,最后在Kernel的schedule()方法进行调用,
sendOutputTo()方法可以把echo等打印的信息进行保存,参数是文件路径,有个问题是这样执行zerogo.log
的内容不是append的,而是进行覆盖,底层执行的逻辑类似:
php demo.php > /var/log/zerogo.log 2>&1
解决方法是搞两个日志文件,Kernel的schedule()函数每分钟执行一次,每次取zerogo.log的内容append到另一个
日志文件。
还有一个emailOutputTo()方法可以把打印的日志信息以邮件形式发出(没测试,以后可能会用到)。
这些都准备好之后在服务器:
crontab -e
* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1
schedule:run是框架自带的artisan命令,执行Kernel.php的schedule()函数