创建CLI命令

Yii有一个好的命令行支持,允许创建可复用的控制台命令。控制台命令比创建web GUI更快。如果你需要为你的应用创建一些工具,可以被开发者或者管理使用,那么控制台命令就是很好的工具。

为了展示如何创建一个控制台命令,我们将会创建一个简单的命令,它会清理一些东西,例如assets和临时文件夹。

准备

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

如何做...

执行如下过程来创建CLI命令:

  1. 使用如下代码创建commands/CleanController.php
<?php
namespace app\commands;
use yii\console\Controller;
use yii\helpers\FileHelper;
/**
 * Removes content of assets and runtime directories.
 */
class CleanController extends Controller
{
    public $assetPaths = ['@app/web/assets'];
    public $runtimePaths = ['@runtime'];
    /**
     * Removes temporary assets.
     */
    public function actionAssets()
    {
        foreach ((array)$this->assetPaths as $path) {
            $this->cleanDir($path);
        }
        $this->stdout('Done' . PHP_EOL);
    }
    /**
     * Removes runtime content.
     */
    public function actionRuntime()
    {
        foreach ((array)$this->runtimePaths as $path) {
            $this->cleanDir($path);
        }
        $this->stdout('Done' . PHP_EOL);
    }
    private function cleanDir($dir)
    {
        $iterator = new
        \DirectoryIterator(\Yii::getAlias($dir));
        foreach($iterator as $sub) {
            if(!$sub->isDot() && $sub->isDir()) {
                $this->stdout('Removed ' . $sub->getPathname()
                    . PHP_EOL);
                FileHelper::removeDirectory($sub->getPathname());
            }
        }
    }
}
  1. 现在我们可以使用我们自己的控制台命令。只需要运行yii shell脚本。
./yii
  1. 查找自己的clean命令:
This is Yii version 2.0.7.
The following commands are available:
- asset Allows you to combine...
asset/compress Combines and compresses the asset...
asset/template Creates template of configuration
file...
...
- clean Removes content of assets and
runtime directories.
clean/assets Removes temporary assets.
clean/runtime Removes runtime content.
- fixture Manages fixture data loading and
unloading.
fixture/load (default) Loads the specified fixture data.
fixture/unload Unloads the specified fixtures.
...
  1. 运行asset清理:
.yii clean/assets
  1. 查看处理报告:
Removed /yii-book.app/web/assets/25f82b8a
Removed /yii-book.app/web/assets/9b3b2888
Removed /yii-book.app/web/assets/f4307424
Done
  1. 如果你想在yii2-app-advanced应用中使用这个控制器,只需要指定自定义工作路径:
return [
    'id' => 'app-console',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'controllerNamespace' => 'console\controllers',
    'controllerMap' => [
        'clean' => [
            'class' => 'console\controllers\CleanController',
            'assetPaths' => [
                '@backend/web/assets',
                '@frontend/web/assets',
            ],
            'runtimePaths' => [
                '@backend/runtime',
                '@frontend/runtime',
                '@console/runtime',
            ],
        ],
    ],
// ...
];

工作原理...

所有的控制台命令应该继承yii\console\Controller类。因为所有的控制器命令在yii\console\Application运行,而不是yii\web\Application,我们没有办法来决定@webroot的值。此外,在yii2-app-advanced模板中,默认情况下,我们有前端、后端和控制子目录。对于这个目的,我们创建可配置的公共数据,叫做assetPathsruntimePaths

控制台命令结构本身类似一个典型的控制器。我们定义几个动作,然后可以通过yii <console command>/<command action>来执行。

正如你所看到的,没有使用视图,所以我们可以把精力集中在编程任务上,而不需要设计、标记等等。此外,你需要提供一些有用的输出,这样用户就知道现在是什么情况。这可以通过简单的PHP echo语句来完成。

如果你的命令相对复杂,例如使用Yii构建的消息或者migrate,提供额外的描述是一个好的决定,说明可用的选项和动作。它可以通过复写getHelp方法完成:

public function getHelp()
{
    $out = "Clean command allows you to clean up various temporary data Yii and an application are generating.\n\n";
    return $out . parent::getHelp();
}

运行如下命令:

./yii help clean

你会看到如下全部输出:

DESCRIPTION
Clean command allows you to clean up various temporary data Yii and
an application are generating.
Removes content of assets and runtime directories.
SUB-COMMANDS
- clean/assets Removes temporary assets.
- clean/runtime Removes runtime content.

默认情况下,当我们运行shell命令时:

./yii

我们在输出列表中看到了所有命令的简化描述:

- clean Removes content of assets and runtime directories.
    clean/assets Removes temporary assets.
    clean/runtime Removes runtime content.

这个描述将会从类和动作前边的注释中获取:

/**
* Removes content of assets and runtime directories.
*/
class CleanController extends Controller
{
    /**
    * Removes temporary assets.
    */
    public function actionAssets() { … }
    * Removes runtime content.
    */
    public function actionRuntime() { … }
}

为你的类添加描述是可选的。你不用非得为你的CLI命令做这件事。

参考

  • 本章中的创建可复用控制器小节
  • 本章中制作可发布扩展小节

results matching ""

    No results matching ""