2 · курс
0%
Главная/🧰Инструменты и тесты

40Консольные приложения

Входной скрипт yii и config/console.php, консольные контроллеры и действия с аргументами, опции через options()/optionAliases(), диалог с пользователем (prompt/confirm/select), цветной вывод, коды выхода ExitCode, встроенные команды help/migrate/cache/asset/serve/fixture/message.

⏱ ~5 мин 📚 1 глава руководства

Консольное приложение — тот же Yii с той же конфигурацией моделей и компонентов, только вместо HTTP-запроса — аргументы командной строки. Cron-задачи, миграции, импорт, очереди — всё это контроллеры в commands/, запускаемые через ./yii.

Запуск#

Консоль
./yii <route> [--option1=value1 ...] [arg1 arg2 ...]
./yii help                       # список команд
./yii help migrate               # справка по команде и её действиям
./yii migrate/create create_post --interactive=0
./yii hello world                # HelloController::actionIndex('world')

Маршрут controller/action; без действия — defaultAction (по умолчанию index). Входной скрипт yii (в корне) создаёт yii\console\Application с config/console.php:

config/console.phpPHP
return [
    'id' => 'basic-console',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'controllerNamespace' => 'app\commands',       // где искать контроллеры
    'components' => [
        'cache' => ['class' => 'yii\caching\FileCache'],
        'log' => [...],
        'db' => require __DIR__ . '/db.php',
    ],
    'controllerMap' => [
        'fixture' => ['class' => 'yii\console\controllers\FixtureController', 'namespace' => 'tests\unit\fixtures'],
    ],
    'params' => require __DIR__ . '/params.php',
];

Общее с web-конфигурацией выносите в отдельный файл и подключайте в обоих. YII_DEBUG/YII_ENV задаются во входном скрипте; в консоли YII_DEBUG по умолчанию true, чтобы видеть стек ошибок.

Контроллер#

commands/HelloController.phpPHP
namespace app\commands;

use yii\console\Controller;
use yii\console\ExitCode;
use yii\helpers\Console;

/**
 * Демонстрационная команда (эта строка попадёт в ./yii help).
 */
class HelloController extends Controller
{
    /** @var bool сохранять ли результат — опция --save */
    public $save = false;
    /** @var string опция --format */
    public $format = 'json';

    public function options($actionID)
    {
        return ['save', 'format'];             // какие свойства доступны как опции (для всех действий)
    }

    public function optionAliases()
    {
        return ['s' => 'save', 'f' => 'format'];   // ./yii hello -s -f=xml
    }

    /**
     * Здоровается (описание действия для help).
     * @param string $name кому
     * @param int $times сколько раз
     */
    public function actionIndex($name = 'world', $times = 1)
    {
        for ($i = 0; $i < $times; $i++) {
            $this->stdout("Hello, $name!\n", Console::FG_GREEN);
        }
        return ExitCode::OK;
    }

    public function actionImport(array $ids)      // ./yii hello/import 1,2,3 → [1, 2, 3]
    {
        // ...
        return ExitCode::OK;
    }
}
Аргументы
параметры метода по порядку; необязательные — со значениями по умолчанию; array $x — из строки через запятую
Опции
публичные свойства, перечисленные в options(); --name=value, --flag (bool), -a через optionAliases(); для массивов — --ids=1 --ids=2
Общие опции
--interactive=0, --color, --help есть у всех команд
Код выхода
return ExitCode::OK (0), ExitCode::UNSPECIFIED_ERROR (1), DATAERR, USAGE… — так cron и CI поймут результат
Справка
из PHPDoc класса, действия и @param; ./yii help hello

Диалог и вывод#

PHP
$name = $this->prompt('Ваше имя:', ['required' => true, 'default' => 'anon']);
if ($this->confirm('Продолжить?')) { … }                        // yes/no; при --interactive=0 — всегда да
$choice = $this->select('Формат:', ['json' => 'JSON', 'xml' => 'XML']);

$this->stdout("Готово\n", Console::FG_GREEN, Console::BOLD);
$this->stderr("Ошибка\n", Console::FG_RED);
echo $this->ansiFormat('внимание', Console::FG_YELLOW);
Console::startProgress(0, $total);  Console::updateProgress($done, $total);  Console::endProgress();
// цвета включаются, если терминал их поддерживает (--color)
$this->isColorEnabled();

Не используйте exit() — верните код; не используйте echo для ошибок — stderr.

Встроенные команды#

Команда Назначение
helpсправка по всем командам
migrateмиграции: create, up, down, redo, fresh, history, new, mark
cacheflush, flush-all, flush-schema
assetсборка и сжатие ассетов (asset/template, asset config.php bundles.php)
fixtureзагрузка тестовых данных (fixture/load, fixture/unload)
messageизвлечение строк для перевода (message/config, message)
serveвстроенный сервер разработки: ./yii serve --port=8080
helloпример из шаблона

Команды расширений (например, queue) добавляются в controllerMap или через bootstrap.

Особенности консольного окружения#

  • Нет request в web-смысле: Yii::$app->request — yii\console\Request с params; нет session, user (компоненты web).
  • Url::to() без hostInfo не построит абсолютный URL — задайте 'urlManager' => ['hostInfo' => 'https://example.com', 'baseUrl' => '/'] в консольной конфигурации (нужно для писем из cron).
  • Псевдоним @web/@webroot не определены — задайте вручную, если нужны.
  • Ошибки идут в stderr и в log; errorHandler — yii\console\ErrorHandler.
  • Длинные задачи: следите за памятью (batch() в запросах, gc_collect_cycles()), логи с flushInterval.

Cron#

Консоль
*/5 * * * * cd /var/www/app && ./yii cleanup/temp --interactive=0 >> runtime/logs/cron.log 2>&1

Запускайте от пользователя приложения, чтобы файлы в runtime/ создавались с правильными правами.

Проверь себя5

Объявить публичное свойство $dryRun, вернуть 'dryRun' из options(); вызывать ./yii cmd --dryRun=1 (или --dry-run — оба варианта работают с 2.0.x).

Объявить параметр действия array $ids и передать 1,2,3.

Ненулевой код: ExitCode::UNSPECIFIED_ERROR или другой из yii\console\ExitCode.

В консоли нет HTTP-запроса; задайте hostInfo и baseUrl у urlManager в консольной конфигурации.

Опция --interactive=0.