yii1tech/async-cmd

为Yii1提供异步shell命令运行器

1.0.0 2023-08-30 14:50 UTC

This package is auto-updated.

Last update: 2024-08-30 01:32:46 UTC


README

Yii1异步Shell命令运行器


本扩展为Yii1提供异步shell命令运行器。

有关许可证信息,请检查LICENSE文件。

Latest Stable Version Total Downloads Build Status

安装

安装此扩展的首选方式是通过composer

运行

php composer.phar require --prefer-dist yii1tech/async-cmd

或添加

"yii1tech/async-cmd": "*"

到您的composer.json文件中的"require"部分。

用法

此扩展为Yii1提供异步shell命令运行器。它依赖于Linux命令行工具来运行命令而不等待其结果。它允许运行Yii控制台命令和任意外部命令。

应用程序配置示例

<?php

return [
    'components' => [
        \yii1tech\async\cmd\CommandDispatcher::class => [
            'class' => \yii1tech\async\cmd\CommandDispatcher::class,
        ],
        // ...
    ],
    // ...
];

用法示例

<?php

use yii1tech\async\cmd\CommandDispatcher;

/** @var CommandDispatcher $dispatcher */
$dispatcher = Yii::app()->getComponent(CommandDispatcher::class);

// run Yii console command:
// executes: `php /path/to/project/yiic stats generate --date='2023-08-29'`
$dispatcher->create()
    ->yiic(StatsCommand::class, 'generate', ['date' => '2023-08-29']); 

// run arbitrary console command:
// executes: `curl -X POST -d 'param1=value1&param2=value2' http://example.com/api/notify`
$dispatcher->create()
    ->external('curl', [
        '-X' => 'POST',
        '-d' => 'param1=value1&param2=value2',
        'http://example.com/api/notify',
    ]);

有关命令选项指定更详细的信息,请参阅\yii1tech\async\cmd\Command

日志记录

由于命令以异步方式执行,很难控制它们是否成功或以错误结束。您可以使用\yii1tech\async\cmd\Command::setOutputLog()轻松地将执行命令的输出记录到文件中。例如

<?php

use yii1tech\async\cmd\CommandDispatcher;

/** @var CommandDispatcher $dispatcher */
$dispatcher = Yii::app()->getComponent(CommandDispatcher::class);

$dispatcher->create()
    ->yiic(StatsCommand::class, 'generate', ['date' => '2023-08-29'])
    ->setOutputLog(Yii::app()->getRuntimePath() . '/stats-generate.log');

此外,实际执行的shell命令也被记录为'info'类别下的'yii1tech.async-cmd'。您可以使用以下日志路由捕获它们

<?php

return [
    'components' => [
        'log' => [
            'class' => \CLogRouter::class,
            'routes' => [
                'fileRoute' => [
                    'class' => \CFileLogRoute::class,
                    'logFile' => 'async-cmd.log',
                    'levels' => 'info',
                    'categories' => 'yii1tech.async-cmd',
                ],
            ],
            // ...
        ],
        // ...
    ],
    // ...
];

编写单元测试

异步流程的测试很麻烦。然而,您可以使用\yii1tech\async\cmd\ArrayCommandRunner来处理。它不会执行给定的命令,而是将它们存储到内部数组中,您可以从中访问和检查它们。应用程序配置示例

<?php

return [
    'components' => [
        \yii1tech\async\cmd\CommandDispatcher::class => [
            'class' => \yii1tech\async\cmd\CommandDispatcher::class,
            'commandRunner' => [
                'class' => \yii1tech\async\cmd\ArrayCommandRunner::class,
            ],
        ],
        // ...
    ],
    // ...
];

单元测试示例

<?php

use yii1tech\async\cmd\Command;
use yii1tech\async\cmd\CommandDispatcher;

class StatsGenerateLauncherTest extends TestCase
{
    public function testLaunchStatsGenerate(): void
    {
        $launcher = Yii::app()->getComponent(StatsGenerateLauncher::class);
        $launcher->launch(); // dispatches async command inside
        
        $dispatcher = Yii::app()->getComponent(CommandDispatcher::class);
        $runner = $dispatcher->getCommandRunner();
        $command = $runner->getLastCommand();
        
        // check if the async command has been dispatched with the correct parameters:
        $this->assertTrue($command instanceof Command);
        $this->assertSame(StatsCommand::class, $command->getCommandClass());
        $this->assertSame('generate', $command->getCommandAction());
    }
}