Консольні команди з PHPixie Console

image
PHPixie Console — це новий компонент дозволяє створювати, роутити і запускати консольні команди. Як і інші бібліотеки фреймворку він може легко використовуватися без самої PHPixie як більш проста альтернатива аналогічної бібліотеки з Symfony. В першу чергу це стаття розрахована на тих хто вже користується PHPixie і в ній буде короткий опис стандартних команд фреймворку, але в кінці я так наведу приклад того, як запустити PHPixie Console окремо.

Апгрейд існуючих проектівЯкщо у вас вже є PHPixie проект, то для роботи Console треба зробити кілька простих змін:

  1. Скопіюйте https://github.com/PHPixie/Project/blob/master/console в корінь проекту. Якщо ви на лінуксі то поставте на цей файл права на виконання (chmod +x console)

  2. Додати «phpixie/framework-bundle»: "~3.0" в composer.json
  3. Поключите бандл \PHPixie\FrameworkBundle і додайте /*GeneratorPlaceholder*/
    як тут: https://github.com/PHPixie/Project/blob/master/src/Project/Framework/Bundles.php


Опціонально можна також скопіювати стандартну архітектуру і демо-команду з оновленого скелета проекту:

  1. Console.php
  2. Console/Greet.php
  3. Builder класі банда підключіть клас консолі як тут: Builder.php


Увага, замініть NamespacePlaceholder на неймспейс свого проекту (за замовчуванням Project) і BundleNamePlaceholder на ім'я свого пакету (швидше за все це App).

Після цього ваша структура буде така-ж як у свіжого проекту.


Використання

Запустіть консоль щоб побачити список доступних команд:

cd your_project_directory/

./console
# або
php ./console


Результат буде приблизно таким:

Available commands:

app:greet Greet the user
framework:installWebAssets Symlink or copy bundle web files to the projects web folder
framework:generateBundle Generate a new bundle
help Print command list and usage


Команда help покаже більше інформації та список доступних параметрів:

./console help framework:installWebAssets

framework:installWebAssets [ --copy ]
Symlink or copy bundle web files to the projects web folder

Options:
copy Whether to copy web directories instead of symlinking them


Стандартні команди

  • framework:installWebAssets — створює ярлики в папці /web/bundles вказуючі на /web папки всередині бандлів, наприклад /web/bundles/app -> /bundles/app/web. Це робиться для того, щоб бандли інстальовані за допомогою композера могли надати свої веб файли. Прапорець --copy скопіює файли замість створення ярликів. Це зручно, наприклад, для створення архіву для CDN.
  • framework:generateBundle — генерує і підключає новий пакет в проект. Більше не доведеться вручну створювати бандли шляхом копіювання існуючого.


Додавання власних команд

У вас в проекті вже додана проста команда app:greet. Робота з командами повністю аналогічна додавання HTTP процесорів, використовуючи клас \Project\App\Console. Досить додати ім'я команди в масив повертається методом commandNames() і додати метод build<command_name>Command.

У конструкторі команди ви можете задати опис і список параметрів і аргументів:

namespace Project\App\Console;

class Greet extends \PHPixie\Console\Command\Implementation
{
public function __construct($config)
{
// Опис
$config->description('Greet the user');

// Додамо параметр 'message'
$config->argument('message')
->description("Message to display");

parent::__construct($config);
}

/**
* Цей метод викликається при запуску команди.
* $argumentData і $optionData працюють так само
* як HTTP $request->query() і $request->data()
*/
public function run($argumentData, $optionData)
{
$message = $argumentData->get('message', "Have fun coding!");
$this->writeLine($message);
}
}


Аргументи і опції

Припустимо ми хочемо додати наступну команду:

sqldump --user=root --skip-missing -f myDatabase users items


Тут myDatabase ім'я бази даних, а за нею список таблиць які ми хотіли б забекапіть. Це аргументи нашої команди. А user, skip-missing, f опції. Зауважте, що для аргументів важливий порядок, в якому вони задаються, а для опцій немає. Також короткі опції з однієї літери використовують один знак - замість двох.

У коді це буде виглядати ось так:

$config->option('user')

//Обов'язкова опція
->required()

//Її опис, буде показано при запуску команди 'help'
->description("User to connect to the database with");

$config->option('skip-missing')
->description("don't throw an error if the tables are missing")

//Задати опцію прапорець.
//Опціям-прапорців не задається значення,
//натомість вони встановлюються в 'true' якщо вони присутні.
->flag();

$config->option('f')
->flag()
->description("Force database dump");


При описі аргументів треба пам'ятати, що задавати їх треба в тому порядку в якому вони повинні бути присутніми в команді. У нашому випадку аргумент database ідеї перед tables:

$config->argument('database')
->required()
->description("Which database to dump the tables from");

$config->argument('таблиця')
->description("Tables to dump")

// Приймає масив значень
// В команді може бути тільки один такий аргумент,
// і логічно що він повинен бути останнім
->arrayOf();


Тепер при запуску help ми отримаємо ось такий результат:

./console help app:sqldump

app:sqldump --user=VALUE [ -f ] [ --skip-missing ] DATABASE [ TABLES... ]

Options:
user User to connect to the database with
f Force database dump
skip-missing Dont throw an error if the tables are missing

Arguments:
DATABASE Which database to dump the tables from
TABLES Tables to dump


При запуску команди методу run() передадуться опції і аргументи, звідки їх можна отримати аналогічно як і в HTTP процесор:

public function run($argumentData, $optionData)
{
$database = $argumentData->get('database');

// Із зазначенням дефолтного значення
$user = $optionData->get('user', 'phpixie');
}


Введення і висновок

Найпростіший метод виводу на консоль це просто return-уть текст. Але якщо процес повинен працювати тривалий час і треба виводити проміжний результат, те можна використовувати додаткові методи:

public function run($argumentData, $optionData)
{
// Виведення тексту
$this->write("Привіт ");

// Виведення тексту з новим рядком
$this->writeLine("World");

// Вважати введення користувача з консолі
$str = $this->readLine();

// Якщо кинути CommandException то в консолі відобразиться текст помилки
// та сама команда поверне не-нульовий статус код (корисно при роботі з Bash).
throw new \PHPixie\Console\Exception\CommandException("Something bad happened");
}


Додатково можна отримати доступ до CLI контексту і працювати вже з ним:

public function run($argumentData, $optionData)
{
$context = $this->cliContext();

$inputStream = $cliContext->inputStream();
$outputStream = $cliContext->outputStream();
$errorStream = $cliContext->errorStream();

$outputStream->write("Привіт");
$errorStream->writeLine("Something bad happened");
$context->setExitCode(1); // вказати код статусу


Код статусу нагоді при перевірці вдало здійснилася команда ззовні, наприклад з Bash:

if ./console app:somecommand ; then
echo "Command succeeded"
else
echo "Command failed"
fi


Як я вже писав з самого початку, компонент можна легко використовувати і без фреймворку:

class YourCommandRegistry extends \PHPixie\Console\Registry\Provider\Implementation 
{
public function commandNames()
{
return ['greet'];
}

public function buildGreetCommand($config)
{
return new Greet($config);
}
}

$slice = new \PHPixie\Slice();
$cli = new \PHPixie\CLI();
$registry = new YourCommandRegistry();

$console = new \PHPixie\Console($slice, $cli, $registry);
$console->runCommand();


Таким чином додати консольні можливості можна в будь-який проект, все це з мінімальними залежностями і вельми інтуїтивно.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.