Квест → Как хакнуть форму
Прошли: 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
Готово!