Я всегда был большим поклонником консольных команд, и я стараюсь максимально использовать интерфейс командной строки (CLI) в большинстве моих проектов PHP.
В этой статье я кратко сравню три библиотеки команд консоли PHP:
- Компонент консоли Symfony ( symfony / Console )
- Консоль Hoa ( hoa / console )
- Консоль Webmozart ( вебмозарт / консоль )
Происхождение истории
Консоль Symfony является самой старой и самой популярной, используемой во многих проектах (и, очевидно, частью инфраструктуры Symfony). С десятками участников это стало первым выбором для многих разработчиков.
Hoa — это модульный, расширяемый и структурированный набор библиотек PHP, который включает консоль Hoa . Он призван стать мостом между промышленным и исследовательским миром, и это делает этот проект довольно интересным.
Консоль Webmozart — это новейший проект, который хочет быть проще, удобнее в тестировании и добавляет новые функциональные возможности поверх консоли Symfony.
Зависимости, размер и сложность
Консоль Symfony имеет только предполагаемые зависимости, в отличие от библиотеки консоли Hoa, которая зависит от некоторых библиотек проекта Hoa . Проект Webmozart также напрямую зависит от консоли Symfony.
Консоль Hoa имеет наименьшее количество LOC (логических строк кода) ~ 1397, затем консоль Symfony ~ 2226 и Webmozart ~ 3126 (без зависимостей).
Чтобы получить приблизительный показатель сложности этих проектов, ниже приведены некоторые данные их анализа PHPLOC *:
Описание | Symfony | Хоа | Webmozart |
---|---|---|---|
Цикломатическая Сложность | |||
Средняя сложность за LLOC | 0,37 | 0,36 | 0,26 |
Средняя сложность на класс | 14,73 | 25,14 | 8,84 |
Средняя сложность на метод | 2,55 | 3,38 | 1,99 |
зависимости | |||
Глобальный доступ | 3 | 20 | 1 |
Доступ к атрибутам | 807 | 217 | 1285 |
Вызовы методов | 1103 | 324 | 1320 |
* Анализ выполняется только в главном исходном каталоге, за исключением тестовой папки, если она имеется.
Практический пример
Описание
Чтобы получить общее представление о функциях каждой библиотеки и увидеть код в действии, давайте напишем бизнес-функцию для описания примера использования:
Feature: I want to output a message to several people. The message should be passed via the `--message` option and should be optional (default="Hello"), the message should be followed by two or more names, the message should be coloured with `--color=` (default="white") and/or in uppercase with `--up` (default=lowercase).
Последний вызов консоли должен выглядеть примерно так:
somemsg --message='Good Morning' Nicola Bruno --color=green --up
и вывод должен быть:
GOOD MORNING NICOLA AND BRUNO
Реализация
Во-первых, нам нужно определить Message
PHP, используемое в каждой консольной реализации, для обработки примера.
Ниже приведен довольно простой код:
class Message { /** * Construct the class and initializes the properties. * * @param $names * @param string $message * @param bool $uppercase */ public function __construct($names, $message="Hello", $uppercase=false) { $this->names = implode(' and ', $names); $this->message = $message; $this->uppercase = $uppercase; } /** * Generates the output. * * @return string */ public function getMessage() { $output = $this->message . ' ' . $this->names; if ($this->uppercase) { $output = strtoupper($output); } return $output; } }
Консоль Symfony
Чтобы создать консольную команду в Symfony, необходимо:
- Создайте класс команды
— настроить аргументы и параметры
— написать логику - Создать приложение
Создать команду
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class MessageCommand extends Command { /** * Configures the argument and options */ protected function configure() { $this ->setName('demo:msg') ->setDescription('Simple message delivery') ->addArgument('names', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Who do you want to message?') ->addOption('message', null, InputOption::VALUE_REQUIRED, 'Set the message', 'Hello') ->addOption('up', null, InputOption::VALUE_NONE, 'Set the output in uppercase') ->addOption('color', null, InputOption::VALUE_REQUIRED, 'Which colors do you like?', 'white') ; } /** * Executes the logic and creates the output. * * @param InputInterface $input * @param OutputInterface $output */ protected function execute(InputInterface $input, OutputInterface $output) { $names = $input->getArgument('names'); $message = $input->getOption('message'); $uppercase = $input->getOption('up'); $color = $input->getOption('color'); $message = new Message($names, $message, $uppercase); $messageString = $message->getMessage(); $coloredMsg = '<fg='.$color.'>'.$messageString.'</fg='.$color.'>'; $output->writeln($coloredMsg); } }
Метод configure
используется для настройки аргументов и параметров команды.
Метод addArgument
может получить следующие параметры:
addArgument($name, $mode, $description, $default)
тип | имя | описание |
---|---|---|
строка | $ имя | Имя аргумента |
ИНТ | $ режим | Режим аргумента: InputArgument :: REQUIRED или InputArgument :: OPTIONAL |
строка | $ описание | Текст описания |
смешанный | $ по умолчанию | Значение по умолчанию (только для режима InputArgument :: OPTIONAL) |
addOption
может получить следующие параметры:
addArgument($name, $shortcut, $mode, $description, $default)
тип | имя | описание |
---|---|---|
строка | $ имя | Название опции |
строка | $ ярлык | Ярлык (может быть нулевым) |
ИНТ | $ режим | Режим параметра: одна из констант InputOption :: VALUE_ * |
строка | $ описание | Текст описания |
смешанный | $ по умолчанию | Значение по умолчанию (должно быть нулевым для InputOption :: VALUE_REQUIRED или InputOption :: VALUE_NONE) |
Есть три варианта цвета для вывода:
- Используйте предустановленный тег (es:
$output->writeln('<info>foo</info>');
для зеленого вывода) - Определите стиль, используя класс
OutputFormatterStyle
- Установите цвет внутри имени тега es:
// red text on a cyan background $output->writeln('<fg=red;bg=cyan>foo</fg=red;bg=cyan>');
Доступны следующие цвета переднего плана и фона: черный, красный, зеленый, желтый, синий, пурпурный, голубой и белый. Доступны следующие варианты: полужирный, подчеркивание, мигание, реверс и скрытие.
Больше информации в официальной документации Symfony .
Примечание : по умолчанию командная консоль Windows не поддерживает раскраску вывода. Вам понадобятся (и должны будут установить) инструменты Git или другая более сложная командная консоль.
Создать приложение
После настройки и выполнения мы почти закончили. Последний шаг — создание файла PHP для запуска команды.
//file myconsole.php require __DIR__.'/vendor/autoload.php'; use MessageCommand; use Symfony\Component\Console\Application; $application = new Application(); $application->add(new MessageCommand()); $application->run();
Пример вызова консоли:
php myconsole.php demo:msg Nicola Bruno --message='Good Morning' --color=blue --up
Консоль Symfony также автоматически предоставляет помощнику вывода аргумент --help
.
Хоа консоль
Консоль Hoa использует менее структурированный подход к настройке команды консоли.
Этот процесс состоит из следующих шагов:
- Разобрать команду
- Получить параметры и ввод
- Выполнить логику
Разобрать команду
/** * $argv contains an array of all the arguments passed to the script, * the first argument is always the name of the PHP file. * the Hoa Parser->parse method accept a string in input, so it's necessary to convert the $argv array in a string without the first argument as below. */ unset($argv[0]); $command = implode(' ', $argv); $parser = new Hoa\Console\Parser(); $parser->parse($command); //options definition //['longname', TYPE, 'shortname'] $options = new Hoa\Console\GetOption( [ ['up', Hoa\Console\GetOption::NO_ARGUMENT, 'u'], ['message', Hoa\Console\GetOption::REQUIRED_ARGUMENT, 'm'], ['color', Hoa\Console\GetOption::OPTIONAL_ARGUMENT, 'c'] ], $parser );
с/** * $argv contains an array of all the arguments passed to the script, * the first argument is always the name of the PHP file. * the Hoa Parser->parse method accept a string in input, so it's necessary to convert the $argv array in a string without the first argument as below. */ unset($argv[0]); $command = implode(' ', $argv); $parser = new Hoa\Console\Parser(); $parser->parse($command); //options definition //['longname', TYPE, 'shortname'] $options = new Hoa\Console\GetOption( [ ['up', Hoa\Console\GetOption::NO_ARGUMENT, 'u'], ['message', Hoa\Console\GetOption::REQUIRED_ARGUMENT, 'm'], ['color', Hoa\Console\GetOption::OPTIONAL_ARGUMENT, 'c'] ], $parser );
Получить варианты и входные данные
//definition of default values $uppercase = false; $message = "Hello"; $color = "white"; $names = $parser->getInputs(); //The following while with the switch will assign the values to the variables. while (false !== $shortName = $options->getOption($value)) { switch ($shortName) { case 'u': $uppercase = true; break; case 'm': $message = $value; break; case 'c': $color = $value; break; } }
Выполнить логику
$message = new Message($names, $message, $uppercase); $messageString = $message->getMessage(); Hoa\Console\Cursor::colorize('fg('.$color.')'); echo $messageString; Hoa\Console\Cursor::colorize('fg(white)'); //reset the cursor to default white
Для окрашивания вывода можно изменить цвет Cursor
.
Консоль Hoa поддерживает широкий спектр цветов.
Цвет можно установить по имени (черный, красный, зеленый, желтый…), по номеру (от 0 до 256, представляющему цветовую палитру 264) или по шестнадцатеричному коду #rrggbb, пример:
Hoa\Console\Cursor::colorize('fg(yellow) bg(#932e2e) underlined');
Основное использование в этом примере не обеспечивает автоматический вывод вспомогательных данных и не ориентировано строго на ООП, но расширение Hoa\Console\Dispatcher\Kit
(требует hoa/dispatcher
) может добавить больше гибкости (больше информации в официальной документации )
Команду можно вызвать с помощью:
php message.php -u --message=Hello --color=green Nicola Bruno
Одной из сильных сторон консоли Hoa является то, что она предоставляет дополнительные классы API для управления важными элементами, поддерживая различные профили терминала:
-
Cursor
(переместить, очистить, показать, раскрасить,…) -
Mouse
(слушая действия мыши) -
Window
(setSize, прокрутка, сворачивание, …) - Линия терминала с
Readline
(история, автозаполнение и т. Д.)
Консоль Webmozart
Рабочий процесс создания команды консоли Webmozart состоит из:
- настройка аргумента и параметров
- писать логику
- создание приложения
Консоль Webmozart следует подходу, аналогичному консоли Symfony, но с четким разделением между конфигурацией и логическим выполнением.
конфигурация
use Webmozart\Console\Api\Args\Format\Argument; use Webmozart\Console\Api\Args\Format\Option; use Webmozart\Console\Config\DefaultApplicationConfig; /** * Configuration of arguments and options */ class MsgApplicationConfig extends DefaultApplicationConfig { protected function configure() { parent::configure(); $this ->setName('msg') ->setVersion('0.1') ->beginCommand('msg') ->setDescription('Show a nice message') ->setHandler(new MsgCommandHandler()) ->addArgument('names', Argument::MULTI_VALUED | Argument::REQUIRED, 'Who do you want to message?') ->addOption('message', null, Option::OPTIONAL_VALUE, 'Set the message', 'Hello') ->addOption('up', null, Option::NO_VALUE, 'Set the output in uppercase') ->addOption('color', null, Option::REQUIRED_VALUE, 'Which colors do you like?', 'white') ->end() ; } }
логика
use Webmozart\Console\Api\Args\Args; use Webmozart\Console\Api\IO\IO; /** * Handling the command logic */ class MsgCommandHandler { public function handle(Args $args, IO $io) { //gets the argument and option $names = $args->getArgument('names'); $message = $args->getOption('message'); $uppercase = $args->getOption('up'); $color = $args->getOption('color'); $message = new Message($names, $message, $uppercase); $messageString = $message->getMessage(); $coloredMsg = '<fg='.$color.'>'.$messageString.'</fg='.$color.'>'; $io->writeLine($coloredMsg); } }
Сильное разделение конфигурации и логики обеспечивает большую гибкость для простого тестирования и для проекта, который будет расти с дополнительными командами.
Другие преимущества консоли Webmozart:
-
поддержка подкоманд:
php mycommand.php msg send --arg1 --arg2 php mycommand.php msg receive --someoptions=somevalue
-
поддержка документации man-страницы (например, с помощью «git help remote»)
- адаптеры для консоли Symfony (для использования классов Symfony, таких как ProgressBar)
Создание приложения
Файл приложения для запуска команды похож на файл Symfony:
require 'vendor/autoload.php'; use Webmozart\Console\ConsoleApplication; $cli = new ConsoleApplication(new MsgApplicationConfig()); $cli->run();
Консольный звонок:
php myconsole.php msg --message='Good Morning' Nicola Bruno --color=blue --up
Последние мысли
Каждая описанная выше консоль предоставляет различные функции для разных типов использования и пользовательских предпочтений.
- Консоль Symfony хорошо протестирована, надежна, имеет хорошую документацию и функции для решения большинства обычных случаев использования.
- Консоль Hoa более ориентирована на отрасль и идеально подходит для манипулирования терминальной средой (мышь, курсор, окно и т. Д.).
- Консоль Webmozart является новой (скоро будет стабильная версия), но она очень полезна для работы с проектами, которые имеют тенденцию расти до больших размеров.
Вы регулярно используете какой-либо из них? Если да, то какой? Почему? Что бы вы сказали за и против каждого? У вас есть другие претенденты, чтобы предложить? Дайте нам знать!