Квест → Как хакнуть форму
Прошли: 77
Представьте, что у вас есть приложения, которые работают уже какое-то время, но есть несколько распространенных случаев, в которых вы решаете, что нужен CLI интерфейс:
cron
задания, которые выполняют HTTP вызовы к некоторому API для запуска различных задач на вашем web-сайте (например, отправка почты и т. д.)chef
или чего-то подобного), а через HTTP- запрос нельзя сделать это красиво
Так как же мы можем сделать это? особенно не переизобретая все заново?
Представьте, что в вашем приложении уже есть класс, описывающий бизнес-логику, а также у вас есть форма, в которой вы можете отредактировать несколько значений, отправить их на сервер, а они применятся в приложении
class Example_Admin_ProcessConfigurationValues { public function process(array $values) { // do some magic stuff with the configuration values } }
теперь нам нужно сопроводить конфигурационные значения из командной строки файлом с JSON описанием, примерно так:
{ "configuration_key_a": "some value", "configuration_key_b": [ "value 1", "value 2", "value 3", ] "configuration_key_c": "other value }
То есть мы хотим получить возможность выполнять примерно такую команду:
php somecommand.php config.json
Значит, нам нужны следующие шаги:
Example_Admin_ProcessConfigurationValues::process
с этим массивомВместо того, чтобы изобретать все заново, мы можем использовать компоненты Symfony. Я предполагаю, что вы уже использовали composer и у вас есть composer.json файл, выглядящий как-то так:
{ "name": "example/project", "license": "MIT", "require": { "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "~4.4" }, "autoload": { "classmap": ["src/"] } }
Тогда вы можете просто воспользоваться Symfony Console Component
для выполнения вашего приложения из командной строки.
Нужно только добавить symfony/console
в качестве новой зависимости:
composer require symfony/console
И тогда вы сможете создать новую консольную команду как в следующем примере:
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class Example_Command_ConfigFromJsonCommand extends Command { protected function configure() { $this->setName('setup:load-json') ->setDescription('Load configurations values from a JSON file') ->addArgument( 'jsonFile', InputArgument::REQUIRED, 'Json file with configurations' ); } protected function execute(InputInterface $input, OutputInterface $output) { $jsonFile = $input->getArgument('jsonFile'); if (!file_exists($jsonFile)) { $output->writeln('Error: Json file does not exists'); return 1; } $jsonFileContent = file_get_contents($jsonFile); $config = json_decode($jsonFileContent, true); if (!is_array($config)) { $output->writeln('Error: Json file does not seams valid'); return 1; } // Call the existing code, with the content of the JSON file $oldClass = new Example_Admin_ProcessConfigurationValues(); $oldClass->process($config); return 0; } }
А теперь эту команду нужно зарегистрировать. Давайте создадим скрипт cli.php
, который будет входной точкой из командной строки и добавим в нем регистрацию команды.
require __DIR__.'/vendor/autoload.php'; use Symfony\Component\Console\Application; $application = new Application(); $application->add(new Example_Command_ConfigFromJsonCommand()); $application->run();
Теперь, если вы запустите cli.php
из командной строки, то увидите:
$ php cli.php Console Tool Usage: command [options] [arguments] Options: -h, --help Display this help message -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 setup setup:load-json Load configurations values from a JSON file
и чтобы выполнить только что созданную команду, нужно просто сделать:
php cli.php setup:load-json config.json
Готово!