試用 EasySwoole 自定義命令
創(chuàng)建文件
<?php
declare(strict_types=1);
namespace App\Command;
use EasySwoole\EasySwoole\Command\CommandInterface;
class DemoCommand implements CommandInterface
{
public function commandName(): string
{
return 'demo:command';
}
public function exec(array $args): ?string
{
var_dump('Hello World');
return 'success';
}
public function help(array $args): ?string
{
return 'help';
}
}
運(yùn)行
$ php easyswoole
______ _____ _
| ____| / ____| | |
| |__ __ _ ___ _ _ | (___ __ __ ___ ___ | | ___
| __| / _` | / __| | | | | \___ \ \ \ /\ / / / _ \ / _ \ | | / _ \
| |____ | (_| | \__ \ | |_| | ____) | \ V V / | (_) | | (_) | | | | __/
|______| \__,_| |___/ \__, | |_____/ \_/\_/ \___/ \___/ |_| \___|
__/ |
|___/
Welcome To EASYSWOOLE Command Console!
Usage: php easyswoole [command] [arg]
Get help : php easyswoole help [command]
Current Register Command:
demo:command
help
install
start
stop
reload
phpunit
$ php easyswoole demo:command
string(11) "Hello World"
success
不得不說,還是相當(dāng)簡(jiǎn)潔的。
改造
接下來(lái),讓我們開始改造一部分代碼辕坝,給 EasySwoole 插上 Hyperf 的 Command。
EasySwoole 運(yùn)行模式十分簡(jiǎn)單荐健,所有的命令都保存在 CommandContainer
中酱畅,所以我們大可以修改入口文件,把其中的命令全部查出來(lái)江场,動(dòng)態(tài)翻譯成 HyperfCommand
纺酸,然后直接運(yùn)行 HyperfCommand
就可以了。
為了不與 easyswoole
命令行沖突址否,我們新建一個(gè) hyperf
好了餐蔬。
首先我們創(chuàng)建一個(gè)組件
$ composer create hyperf/component-creater hyperf
Installing hyperf/component-creater (v1.1.1)
- Installing hyperf/component-creater (v1.1.1): Downloading (100%)
Created project in hyperf
> Installer\Script::install
Setting up optional packages
What is your component name (hyperf/demo): hyperf-cloud/easyswoole-command
What is your component license (MIT) :
What is your component description : HyperfCommand for EasySwoole
What is your namespace (HyperfCloud\EasyswooleCommand):
Removing installer development dependencies
Do you want to use hyperf/framework component ?
[1] yes
[n] None of the above
Make your selection or type a composer package name and version (n):
Do you want to use hyperf/di component ?
[1] yes
[n] None of the above
Make your selection or type a composer package name and version (n):
...
并給組件增加 "hyperf/command": "1.1.*"
依賴碎紊。
下面修改根目錄 composer.json
{
"require": {
"easyswoole/easyswoole": "3.x",
"hyperf-cloud/easyswoole-command": "dev-master"
},
"require-dev": {
"swoft/swoole-ide-helper": "^4.2",
"friendsofphp/php-cs-fixer": "^2.14",
"mockery/mockery": "^1.0",
"phpstan/phpstan": "^0.11.2"
},
"autoload": {
"psr-4": {
"App\\": "App/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true
},
"scripts": {
"test": "co-phpunit -c phpunit.xml --colors=always",
"cs-fix": "php-cs-fixer fix $1",
"analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./App"
},
"repositories": {
"hyperf": {
"type": "path",
"url": "./hyperf"
},
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer"
}
}
}
接管CommandInterface
讓我們創(chuàng)建一個(gè) EasySwooleCommand
來(lái)接管所有的 CommandInterface
。
<?php
declare(strict_types=1);
namespace HyperfCloud\EasyswooleCommand;
use EasySwoole\EasySwoole\Command\CommandInterface;
use EasySwoole\EasySwoole\Core;
use Hyperf\Command\Command;
use Symfony\Component\Console\Input\InputOption;
class EasySwooleCommand extends Command
{
/**
* @var CommandInterface
*/
protected $command;
/**
* @var bool
*/
protected $coroutine = false;
public function __construct(CommandInterface $command)
{
parent::__construct($command->commandName());
$this->command = $command;
}
public function configure()
{
$this->addOption('args', 'a', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'EasySwoole 入?yún)?, []);
}
public function handle()
{
$args = $this->input->getOption('args');
if (in_array('produce', $args)) {
Core::getInstance()->setIsDev(false);
}
Core::getInstance()->initialize();
$result = $this->command->exec($args);
$this->output->success($result);
}
}
增加 Application
初始化所有 CommandContainer
中的 Command
仗考。
<?php
declare(strict_types=1);
namespace HyperfCloud\EasyswooleCommand;
use EasySwoole\Component\Singleton;
use EasySwoole\EasySwoole\Command\CommandContainer;
use Hyperf\Command\Command;
use Hyperf\Contract\ApplicationInterface;
use Symfony\Component\Console\Application as SymfonyApplication;
class Application implements ApplicationInterface
{
use Singleton;
protected $commands;
public function __construct()
{
$container = CommandContainer::getInstance();
$list = $container->getCommandList();
foreach ($list as $name) {
$this->commands[] = new EasySwooleCommand($container->get($name));
}
}
public function add(Command $command)
{
$this->commands[] = $command;
}
public function run()
{
$application = new SymfonyApplication();
foreach ($this->commands as $command) {
$application->add($command);
}
return $application->run();
}
}
最后改造入口函數(shù)
<?php
declare(strict_types=1);
use EasySwoole\EasySwoole\Command\CommandRunner;
use HyperfCloud\EasyswooleCommand\Application;
defined('IN_PHAR') or define('IN_PHAR', boolval(\Phar::running(false)));
defined('RUNNING_ROOT') or define('RUNNING_ROOT', realpath(getcwd()));
defined('EASYSWOOLE_ROOT') or define('EASYSWOOLE_ROOT', IN_PHAR ? \Phar::running() : realpath(getcwd()));
$file = EASYSWOOLE_ROOT . '/vendor/autoload.php';
if (file_exists($file)) {
require $file;
} else {
die("include composer autoload.php fail\n");
}
// 初始化 CommandContainer
CommandRunner::getInstance();
if (file_exists(EASYSWOOLE_ROOT . '/bootstrap.php')) {
require_once EASYSWOOLE_ROOT . '/bootstrap.php';
}
Application::getInstance()->run();
執(zhí)行命令 demo:command
$ php hyperf.php demo:command
string(11) "Hello World"
[OK] success
啟動(dòng) Server
$ php hyperf.php start -a produce
創(chuàng)建 HyperfCommand
接下來(lái)必搞,我們創(chuàng)建一個(gè) HyperfCommand
看看效果梅割。
<?php
declare(strict_types=1);
namespace App\Command;
use Hyperf\Command\Command;
class Demo2Command extends Command
{
public function __construct()
{
parent::__construct('demo:command2');
}
public function handle()
{
var_dump('Hello Hyperf Command.');
}
}
修改 bootstrap.php
<?php
declare(strict_types=1);
use EasySwoole\EasySwoole\Command\CommandContainer;
use App\Command\{DemoCommand, Demo2Command};
use HyperfCloud\EasyswooleCommand\Application;
CommandContainer::getInstance()->set(new DemoCommand());
Application::getInstance()->add(new Demo2Command());
執(zhí)行結(jié)果
$ php hyperf.php demo:command2
string(21) "Hello Hyperf Command."
寫在最后
Hyperf 是基于 Swoole 4.4+ 實(shí)現(xiàn)的高性能惦银、高靈活性的 PHP 協(xié)程框架,內(nèi)置協(xié)程服務(wù)器及大量常用的組件,性能較傳統(tǒng)基于 PHP-FPM 的框架有質(zhì)的提升,提供超高性能的同時(shí),也保持著極其靈活的可擴(kuò)展性,標(biāo)準(zhǔn)組件均基于 PSR 標(biāo)準(zhǔn) 實(shí)現(xiàn)田盈,基于強(qiáng)大的依賴注入設(shè)計(jì)瓷式,保證了絕大部分組件或類都是 可替換 與 可復(fù)用 的。
框架組件庫(kù)除了常見的協(xié)程版的 MySQL 客戶端踱卵、Redis 客戶端廊驼,還為您準(zhǔn)備了協(xié)程版的 Eloquent ORM、WebSocket 服務(wù)端及客戶端惋砂、JSON RPC 服務(wù)端及客戶端妒挎、GRPC 服務(wù)端及客戶端、Zipkin/Jaeger (OpenTracing) 客戶端西饵、Guzzle HTTP 客戶端酝掩、Elasticsearch 客戶端、Consul 客戶端眷柔、ETCD 客戶端期虾、AMQP 組件、Apollo 配置中心驯嘱、阿里云 ACM 應(yīng)用配置管理镶苞、ETCD 配置中心、基于令牌桶算法的限流器鞠评、通用連接池茂蚓、熔斷器、Swagger 文檔生成剃幌、Swoole Tracker聋涨、Blade 和 Smarty 視圖引擎、Snowflake 全局ID生成器 等組件负乡,省去了自己實(shí)現(xiàn)對(duì)應(yīng)協(xié)程版本的麻煩牛郑。
Hyperf 還提供了 基于 PSR-11 的依賴注入容器、注解敬鬓、AOP 面向切面編程淹朋、基于 PSR-15 的中間件笙各、自定義進(jìn)程、基于 PSR-14 的事件管理器础芍、Redis/RabbitMQ 消息隊(duì)列杈抢、自動(dòng)模型緩存、基于 PSR-16 的緩存仑性、Crontab 秒級(jí)定時(shí)任務(wù)惶楼、Translation 國(guó)際化、Validation 驗(yàn)證器 等非常便捷的功能诊杆,滿足豐富的技術(shù)場(chǎng)景和業(yè)務(wù)場(chǎng)景歼捐,開箱即用。