Create Custom CLI Commands Using the Symfony Console Component
PHP:7.2
symfony/console:5.2.3
在軟體開發的生涯中,很多時候開發一些小工具可以幫助我們快速處理一些 routine 的事情,但當小工具一多,若是沒有整理的話,要使用時都得重新看一次 code 才能知道在做什麼,再加上這些工具的使用說明往往不夠明確,也不一定可以交接給別人使用。
symfony/console 是 Symfony Framework 中的一個套件,專門用來實作 CLI Commands
,Laravel
的 artisan
也是透過該套件實作,功能及結構相對比較完善,因此我們可以透過單獨使用 symfony/console
來實作較為完整的小工具。
Installation and Configuration
Install symfony/console
composer require symfony/console
Configure your Structure
由於 symfony/console
是結構非常完整的套件,因此就算只是開發小工具,目錄結構和 dependency 也要調整好才能運作。
先將 composer.json
的 autoload 調整好。
{
"require": {
"symfony/console": "^5.2"
},
"autoload": {
"psr-4": {
"BallBallTools\\": "src/"
}
}
}
接著按照你的需求設計目錄結構。
├── bin
│ └── console
├── composer.json
├── composer.lock
├── src
│ └── Command
│ └── CreateUserCommand.php
└── vendor
bin/console
會是我們的 CLI command 的進入點,相關的 Command 設定我都會放在 src/Command
底下。
最後再更新一下 composer
。
composer dump-autoload
Create the Console Application
在建立第一個 Command 之前,我們需要先寫好進入點。
bin/console
#!/usr/bin/env php
<?php
require __DIR__ . '/../vendor/autoload.php';
use Symfony\Component\Console\Application;
// 使用 Symfony 的 Console Object 當進入點
$application = new Application();
$application->run();
Notice: 記得把權限調整成
755
方便執行。
執行以後就會看到基本的 Command 運作。
bin/console
Console Tool
Usage:
command [options] [arguments]
Options:
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
help Displays help for a command
list Lists commands
Create the Command File
在進入點完成之後,就可以開始實作想要的功能,本篇就以實作一個 CreateUserCommand
為例。
src/Command/CreateUserCommand.php
namespace BallBallTools\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class CreateUserCommand extends Command
{
// 定義該 Command 的名字,會在執行 "bin/console" 時顯示
protected static $defaultName = 'User:create-user';
// configure() 是用來設定參數的函式
protected function configure()
{
$this
// 該 Command 的說明簡介
->setDescription('Creates a new user')
// 使用 "--help" option 時的說明
->setHelp('This command allows you to create a user...')
// 加入 Option 設定
// addOption(<long-options>, <options>, <options variants>, <message>, <default value>)
// Support --production
->addOption('production', null, InputOption::VALUE_NONE, 'Enable production')
// Support -c or --colors
// Support array. Can run command --colors=red --colors=green
->addOption('colors', 'c', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Enter your color', ['red', 'yellow'])
// 加入 Argument 設定
// addArgument(<argument>, <argument variants>, <message>, <default value>)
->addArgument('username', InputArgument::REQUIRED, 'Enter the username.')
// Support array. Can run command argument1 argument2 argument3 ...
->addArgument('his-girlfriends', InputArgument::IS_ARRAY, 'Separate multiple names with a space');
}
// execute() 是用來描述 Command 執行動作的函式
protected function execute(InputInterface $input, OutputInterface $output)
{
// Get optoins and arguments by InputInterface
$colors = $input->getOption('colors');
$username = $input->getArgument('username');
// Output by OutputInterface
$output->writeln(sprintf('Hello World!, %s', $username));
return Command::SUCCESS;
// return Command::FAILURE;
}
}
Options Variants
Type Name | 功能 |
---|---|
InputArgument::REQUIRED | 必填欄位 |
InputArgument::OPTIONAL | 選填欄位 |
InputArgument::IS_ARRAY | 支援陣列 |
Arguments Variants
Type Name | 功能 |
---|---|
InputOption::VALUE_IS_ARRAY | 支援陣列(e.g. --dir=/foo --dir=/bar) ) |
InputOption::VALUE_NONE | 可不填入值 (e.g. --production) ) |
InputOption::VALUE_REQUIRED | 必填欄位 |
InputOption::VALUE_OPTIONAL | 選填欄位 |
最後要把你開發好的 Command
註冊到進入點。
bin/console
use BallBallTools\Command\CreateUserCommand;
$application = new Application();
// Register
$application->add(new CreateUserCommand());
$application->run();
Run your Command
bin/console User:create-user --help