PHP Profi

Запуск из командной строки «исторически сложившихся» (legacy) PHP приложений Перевод

php cli

Представьте, что у вас есть приложения, которые работают уже какое-то время, но есть несколько распространенных случаев, в которых вы решаете, что нужен 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

Значит, нам нужны следующие шаги:

  1. Загрузить JSON-файл в массив
  2. Вызвать Example_Admin_ProcessConfigurationValues::process с этим массивом
  3. Готово

Symfony Console Component в помощь

Вместо того, чтобы изобретать все заново, мы можем использовать компоненты 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



Готово!

2016-02-22 ddelay оригинал
General Food

Комментарии

авторизуйтесь, чтобы оставить комментарий