View on GitHub

yii2-cookbook-chinese

Yii Application Development Cookbook(Third Edition)中文翻译

实施和执行cron任务

有时,一个应用需要一些后台任务,例如重新生成一个站点地图,或者刷新统计数据。一种常见的方式是使用cron任务。当使用Yii时,有一种方法可以使用一个命令做为任务来运行。

在这个小节中,我们将会看到如何同时实现。在我们的小节中,我们将会实现写当前时间戳到受保护文件夹中的timestamp.txt文件中。

准备

按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的yii2-app-basic应用。

如何做…

运行Hello命令

尝试作为shell命令运行app\commands\HelloController::actionIndex

<?php
namespace app\commands;
use yii\console\Controller;
/**
* This command echoes the first argument that you have entered.
*/
class HelloController extends Controller
{
    /**
    * This command echoes what you have entered as the message.
    * @param string $message the message to be echoed.
    */
    public function actionIndex($message = 'hello world')
    {
        echo $message . "\n";
    }
}
  1. 在你的应用目录中,打开shell,并执行如下命令:
php yii

此外,你也可以调用如下,确保shell可以工作:

./yii
  1. 输入如下命令,展示hello
./yii help hello
  1. 这个框架可以展示一些信息:
DESCRIPTION
This command echoes what you have entered as the message.
USAGE
yii hello [message] [...options...]
- message: string (defaults to 'hello world')
the message to be echoed.
  1. 运行缺省命令动作:
./yii hello

或者,运行指定的index动作:

./yii hello/index
  1. 你可以看到默认提示:
Hello world
  1. 运行带有任何参数的命令,将会看到响应:
./yii hello 'Bond, James Bond'

创建你自己的命令

你也可以创建你自己的控制台控制器。例如,创建一个commands/CronController.php文件:

<?php
namespace app\commands;
use yii\console\Controller;
use yii\helpers\Console;
use Yii;
/**
 * Console crontab actions
 */
class CronController extends Controller
{
    /**
     * Regenerates timestamp
     */
    public function actionTimestamp()
    {
        file_put_contents(Yii::getAlias('@app/timestamp.txt'),
            time());
        $this->stdout('Done!', Console::FG_GREEN, Console::BOLD);
        $this->stdout(PHP_EOL);
    }
}

这些完成以后,在控制台中运行命令:

./yii cron/timestamp

然后,检查响应文本,以及生成的新文件timestamp.txt

设置cron任务

在你的Linux服务器上创建/etc/cron.d/myapp,并添加如下内容,让我们的脚本在每天的半夜12点整运行一次:

0 0 * * * www-data /path/to/yii cron/timestamp >/dev/null

工作原理…

一个控制台命令被定义成了一个控制器类,这个类继承了yii\console\Controller。在控制器类中,你可以定义一个或多个动作,分别对应这个控制器的多个子命令。在每一个动作中,你可以为每一个指定的子命令实现恰当的任务。

在运行一个命令时,你需要指定控制器动作的路由。例如,migrate/create调用的子命令对应于MigrateController::actionCreate()动作函数。如果在执行时,提供的路由不包含一个动作ID,默认的动作将会被执行(作为一个web控制器)。

注意你的控制台控制器被放置在指定的文件夹中,位置由web/console.php中的controllerNamespace选项定义。

参考