Task Scheduling in Yii 2

在工作中总是不可避免的会需要创建或者维护一些定时脚本,那么怎么去管理 Cron Jobs 呢?最常见的是使用 linux 系统的 corntab,需要添加/删除/修改某个定时任务直接去服务器上修改 crontab 配置文件。但是随着时间的推移,开发人员越来越多,需要维护的脚本越来越多,就会变得越来越艰难。

于是 Laravel 框架弄了一个 Task Scheduling 模块来管理定时任务,配置可以直接写在 PHP 代码里,然后上传到 git 来管理。今天我们要介绍的 yii2-schesuling 插件,就是从 Laravel 移植过来的。


下面我们开始介绍 yii2-schesuling 插件的安装 & 使用。

首先是安装 yii2-scheduling,建议直接使用 composer 来安装。

composer require omnilight/yii2-scheduling "*"

如果需要使用 pingBefore($url) or thenPing($url) 方法,还需要用 composer 安装 Guzzle HTTP library。

composer require guzzlehttp/guzzle

然后你需要创建自己的配置文件 @console/config/schedule.php,具体的语法可以看 yii2-scheduling 的文档,也可以直接参考 Laravel Task Scheduling 的文档。(推荐放在 @console/config 目录下面,当然你也可以放在项目的任何地方,只要你喜欢就好。)


/**
 * @var \omnilight\scheduling\Schedule $schedule
 */

// Place here all of your cron jobs

// This command will execute ls command every five minutes
$schedule->exec('ls')->everyFiveMinutes();

// This command will execute migration command of your application every hour
$schedule->command('migrate')->hourly();

// This command will call callback function every day at 10:00
$schedule->call(function(\yii\console\Application $app) {
    // Some code here...
})->dailyAt('10:00');

最后在 crontab 中添加定时任务。

* * * * * php /path/to/yii yii schedule/run --scheduleFile=@console/config/schedule.php 1>> /dev/null 2>&1

这里简单的解释一下整个的运行过程:在服务器上创建一个定时任务,每隔一分钟执行一次 php yii schedule/run 脚本。每次执行 schedule/run 脚本, 程序都会检查一遍已经添加到配置文件里面的定时脚本,看看哪些脚本已经到了计划的执行时间,然后去执行它。定时脚本配置文件的解析用的是 cron-expression,使用多个子进程来执行脚本用的是 symfony-process,如果对实现细节感兴趣,可以去看看这些项目的源代码。


参考:

https://laravel.com/docs/5.5/scheduling

https://github.com/omnilight/yii2-scheduling

https://github.com/mtdowling/cron-expression

https://symfony.com/doc/current/components/process.html

526 total views, 1 views today

Yii2 RESTful 实践

安装 Yii

创建工作目录

mkdir yii2-rest
cd yii2-rest

创建 composer.json

{
    "require": {
        "yiisoft/yii2": "~2.0.0"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://asset-packagist.org"
        }
    ]
}

然后运行 composer install 命令。

写一个 Hello World

创建 web/index.php

<?php

// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');

$config = require __DIR__ . '/../config.php';
(new yii\web\Application($config))->run();

创建 config.php

<?php

return [
    'id' => 'yii2-rest',
    // the basePath of the application will be the `yii2-rest` directory
    'basePath' => __DIR__,
    // this is where the application will find all controllers
    'controllerNamespace' => 'api\controllers',
    // set an alias to enable autoloading of classes from the 'api' namespace
    'aliases' => [
        '@api' => __DIR__,
    ],
];

创建 controllers/SiteController.php

<?php

namespace api\controllers;

use yii\web\Controller;

class SiteController extends Controller
{
    public function actionIndex()
    {
        return 'Hello World!';
    }
}

然后运行如下命令启动内置 web 服务器。

vendor/bin/yii serve --docroot=./web

在浏览器中打开 http://localhost:8080 应该就可以看到 “Hello World!”

创建一个 REST API

首先添加 MySQL 数据库配置。

'components' => [
    'db' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=127.0.0.1;dbname=rest_api',
        'username' => 'root',
        'password' => '123456',
        'charset' => 'utf8mb4',
    ],
]

然后使用 Yii Migrate 创建表。

vendor/bin/yii migrate/create --appconfig=config.php create_post_table --fields="title:string,body:text"
vendor/bin/yii migrate/up --appconfig=config.php

创建 models/Post.php

<?php

namespace api\models;

use yii\db\ActiveRecord;

class Post extends ActiveRecord
{ 
    public static function tableName()
    {
        return '{{post}}';
    }
}

创建 controller/PostController.php

<?php

namespace api\controllers;

use yii\rest\ActiveController;

class PostController extends ActiveController
{
    public $modelClass = 'api\models\Post';

    public function behaviors()
    {
        // remove rateLimiter which requires an authenticated user to work
        $behaviors = parent::behaviors();
        unset($behaviors['rateLimiter']);
        return $behaviors;
    }
}

启用 JSON 输入

'request' => [
    'parsers' => [
       'application/json' => 'yii\web\JsonParser',
    ]
],

配置URL规则

'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
        ['class' => 'yii\rest\UrlRule', 'controller' => 'post'],
    ],
],

现在我们就可以提供如下 REST API :

GET    /posts   - 列出所有帖子
GET    /posts/1 - 显示 ID 为 1 的帖子
POST   /posts   - 创建一个帖子
UPDATE /posts/1 - 更新 ID 为 1 的帖子
PATCH  /posts/1 - 更新 ID 为 1 的帖子
DELETE /posts/1 - 删除 ID 为 1 的帖子

参考:

https://www.yiiframework.com/doc/guide/2.0/zh-cn/tutorial-yii-as-micro-framework

https://github.com/tanghengzhi/yii2-rest

333 total views, no views today