BMC IO DocsBMC IO Docs
IO v6
IO v7
Notes
Docs
IO v6
IO v7
Notes
Docs
  • IO Framework v7

    • О фреймворке
    • Что изменилось в 7 версии
    • IO7 Framework vs Laravel 13 — Сравнение
    • Структура
    • Варианты проектов
    • Доступ к участкам проекта
    • Разворачивание нового проекта
    • Установка проекта
    • Запуск локальной разработки
  • API

    • Обзор API
    • IOCore::call() и IOCore::callAction()
    • Создание API
  • CLI

    • Обзор CLI
    • iocli
    • Кастомные CLI команды
  • Работа с базами данных

    • Обзор работы с базами данных
    • Cron / Планировщик задач (Schedule)
    • Фабрики
    • Миграции
    • Сидеры
    • Query Builder
    • Подключение MinIO
    • Подключение MongoDB
    • Подключение MySQL
    • Подключение PostgreSQL
    • Подключение ProxySQL
    • Подключение RabbitMQ
    • Подключение Redis
  • Логирование

    • Обзор логирования
    • IOEvent - Логирование событий
    • Pinba (PinbaManager) - Профилировщик
  • Модели

    • Обзор моделей
    • CRUD операции
    • Связи моделей
  • Очереди

    • Обзор очередей
    • RabbitMQ
  • Маршруты

    • Обзор маршрутов
    • Определение маршрутов
    • Middleware
  • Сессии

    • Обзор сессий
    • Кроссдоменная SSO
    • JWT авторизация
    • Социальная авторизация
    • OAuth2
    • Keycloak
  • Twig

    • Обзор Twig
    • Формы (FormBuilder)
    • Twig функции
  • Тестирование

    • Обзор тестирования
    • Unit тесты
  • Backend

    • Настройки проекта Conf.php
    • Настройки модуля Module.php
    • Настройки composer
    • Функции фреймворка
    • Вспомогательные функции (Helpers)
    • Глобальные переменные
    • Константы фреймворка
    • Event класс
    • Core класс
    • Route и работа с ними
    • Request и работа с ними
    • Middleware и работа с ними
    • Class и работа с ними
    • Api model и работа с ними
    • Template и работа с ними
    • Мультиязычность и словарь фраз
    • Bin скрипты и работа с ними
    • Cron скрипты и работа с ними
    • $ioSession и работа с сессией
    • $ioHash и работа с кешем
    • $ioXCache и работа с кешем
    • $iodb и работа с базой данных
    • Миграции
  • Frontend

    • Twig шаблонизатор и работа с ним
    • Twig функции
    • Twig фильтры
    • Twig контекст
    • Настройка NPM
    • Сборка Frontend составляющей
    • Обращение к Api через JS
    • Хранилище (store)
    • Навигация в хосте
    • Навигация в микрофронтенде
    • Параметры микрофронтенда
    • Проверка полномочий
  • Tailux UI Компоненты

    • Базовый UI

      • AvatarDot
      • Avatar
      • Badge
      • Button
      • Card
      • ConfirmModal
      • Divider
      • Highlight
      • Tag
    • Загрузка

      • Circlebar
      • Progress
      • Skeleton
      • Spinner
    • Навигация

      • Accordion
      • AccordionButton
      • AccordionHeader
      • AccordionItem
      • AccordionPanel
      • AccordionProvider
      • Pagination
      • PaginationControl
      • PaginationItems
      • PaginationDots
      • PaginationFirst
      • PaginationLast
      • PaginationNext
      • PaginationPrevious
    • Отображение данных

      • Box
      • Collapse
      • ContextualHelp
      • ScrollShadow
      • Timeline
      • TimelineItem
    • Элементы таблиц

      • Table
      • CollapsibleSearch
      • ColumnFilter
      • CopyableCell
      • DateFilter
      • FacetedFilter
      • FilterSelector
      • PaginationSection
      • RadioFilter
      • RangeFilter
      • ResponsiveFilter
      • RoleFilter
      • SelectedRowsActions
      • TableColumnVisibility
      • TableSettings
      • TableSortIcon
    • Элементы форм

      • Checkbox
      • Combobox
      • DatePicker
      • Filepond
      • Input
      • Listbox
      • Radio
      • Range
      • Select
      • StyledSwitch
      • Swap
      • SwapOn
      • SwapOff
      • Switch
      • Textarea
      • TextEditor
      • Upload

Кастомные CLI команды — IO7 Framework

Внимание

Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!

  • Обзор
  • Создание команды
    • Через make:command
    • Вручную
  • Структура класса команды
    • Обязательные элементы
  • Сигнатура
    • Элементы сигнатуры
    • Примеры сигнатур
  • Доступ к аргументам и опциям
    • Позиционные аргументы
    • Опции
  • Вспомогательные методы
  • Регистрация в Module.php
    • Параметры register()
    • Порядок загрузки
  • Полные примеры
    • Пример 1: Простая команда
    • Пример 2: Команда с опциями
    • Пример 3: Команда с выводом таблицы
    • Пример 4: Команда для генерации отчёта
  • Запуск кастомных команд
    • Через имя команды (зарегистрированная команда)
    • Через command:run (по имени класса)
  • Порядок файлов
  • Важные замечания

Обзор

IO7 позволяет создавать собственные CLI команды. Пользовательские команды хранятся в app/Commands/ и регистрируются в app/Module.php.


Создание команды

Через make:command

$ php iocli make:command SendEmail
Команда создана: app/Commands/SendEmailCommand.php

Генерируется файл app/Commands/SendEmailCommand.php с базовой структурой.

Вручную

Создайте файл в app/Commands/ с пространством имён App\Commands и расширением IO\Console\Command.


Структура класса команды

<?php

namespace App\Commands;

use IO\Console\Command;

class SendEmailCommand extends Command
{
    protected string $signature = 'email:send {user_id} {--queue} {--delay=}';
    protected string $description = 'Отправить email пользователю';

    public function handle(): int
    {
        $userId = $this->argument('user_id');
        $queue = $this->option('queue');
        $delay = $this->option('delay') ?? 0;

        $this->info("Email отправлен пользователю {$userId}");
        return 0;
    }
}

Обязательные элементы

ЭлементОписание
namespace App\CommandsПространство имён
extends CommandНаследование от IO\Console\Command
protected string $signatureСигнатура команды
protected string $descriptionОписание для справки
public function handle(): intТочка входа. Возвращает 0 — успех, 1 — ошибка

Сигнатура

Свойство $signature определяет имя команды, аргументы и опции. Формат:

имя_команды {аргумент1} {аргумент2} {--опция=значение} {--флаг}

Элементы сигнатуры

ФорматТипОписаниеПример
{name}stringПозиционный аргумент{user_id}
{--key=value}stringОпция со значением по умолчанию{--delay=0}
{--flag}boolБулевый флаг (true/false){--once}
{args?*}string*Переменное число аргументов{args?*}

Примеры сигнатур

app:version
migrate
make:migration {name}
serve {--host=127.0.0.1} {--port=8000}
queue:work {--queue=default} {--once}
command:run {name} {args?*}

Доступ к аргументам и опциям

Позиционные аргументы

$name = $this->argument('user_id');

Возвращает значение аргумента или null, если не передан.

Опции

$delay = $this->option('delay');    // строка или null
$once = $this->option('once');      // true или null

Имя передаётся без --. Для флагов возвращает true или null.


Вспомогательные методы

МетодОписаниеПример
info($message)Зелёный вывод (успех)$this->info('Готово');
error($message)Красный вывод (ошибка)$this->error('Файл не найден');
line($message)Обычный вывод$this->line('Текст');
confirm($message)Запрос подтверждения y/nif ($this->confirm('Удалить?'))
ask($question)Запрос ввода строки$name = $this->ask('Имя');
self::app()Доступ к экземпляру App$app = self::app();

Регистрация в Module.php

После создания команды зарегистрируйте её в app/Module.php:

<?php

namespace App;

class Module
{
    public static function registerCommands(\IO\Console\Kernel $kernel): void
    {
        $kernel->register('email:send', \App\Commands\SendEmailCommand::class);
        $kernel->register('report:generate', \App\Commands\GenerateReportCommand::class);
    }
}

Параметры register()

ПараметрТипОписание
$namestringИмя команды (то что в $signature)
$commandClassstringПолное имя класса с \

Порядок загрузки

Точка входа iocli загружает команды в таком порядке:

  1. \IO\Module::registerCommands($kernel) — 31 встроенная команда фреймворка
  2. \App\Module::registerCommands($kernel) — пользовательские команды

Пользовательские команды могут перезаписать встроенные, если использовать одно имя.


Полные примеры

Пример 1: Простая команда

<?php

namespace App\Commands;

use IO\Console\Command;

class HelloCommand extends Command
{
    protected string $signature = 'app:hello {name}';
    protected string $description = 'Поздороваться';

    public function handle(): int
    {
        $name = $this->argument('name');
        if ($name === null) {
            $this->error('Укажите имя');
            return 1;
        }

        $this->info("Привет, {$name}!");
        return 0;
    }
}
// Module.php
$kernel->register('app:hello', \App\Commands\HelloCommand::class);
$ php iocli app:hello Мир
Привет, Мир!

Пример 2: Команда с опциями

<?php

namespace App\Commands;

use IO\Console\Command;

class MigrateFreshSeedCommand extends Command
{
    protected string $signature = 'app:fresh-seed {--class=} {--force}';
    protected string $description = 'Очистить базу и заполнить данными';

    public function handle(): int
    {
        $class = $this->option('class');
        $force = $this->option('force');

        if (!$force && !$this->confirm('Все данные будут удалены. Продолжить?')) {
            $this->line('Отменено');
            return 0;
        }

        $this->info('Очистка базы...');
        // ... логика очистки

        if ($class) {
            $this->info("Запуск сидера: {$class}");
        } else {
            $this->info('Запуск всех сидеров...');
        }

        $this->info('Готово');
        return 0;
    }
}
// Module.php
$kernel->register('app:fresh-seed', \App\Commands\MigrateFreshSeedCommand::class);
# С подтверждением
$ php iocli app:fresh-seed
Все данные будут удалены. Продолжить? (y/n): y
Очистка базы...
Запуск всех сидеров...
Готово

# Пропустить подтверждение и запустить конкретный сидер
$ php iocli app:fresh-seed --force --class=UserSeeder
Очистка базы...
Запуск сидера: UserSeeder
Готово

Пример 3: Команда с выводом таблицы

<?php

namespace App\Commands;

use IO\Console\Command;

class UsersListCommand extends Command
{
    protected string $signature = 'app:users {--role=} {--limit=50}';
    protected string $description = 'Показать список пользователей';

    public function handle(): int
    {
        $role = $this->option('role');
        $limit = (int) ($this->option('limit') ?? 50);

        $app = self::app();
        $conditions = [];
        if ($role) {
            $conditions['role'] = $role;
        }

        $users = $app->iodb->search('users', $conditions, $limit);

        $this->line(str_repeat('-', 60));
        $this->line(sprintf('%-8s %-25s %-20s', 'ID', 'Email', 'Роль'));
        $this->line(str_repeat('-', 60));

        foreach ($users as $user) {
            $this->line(sprintf('%-8d %-25s %-20s',
                $user['pkid'],
                $user['email'],
                $user['role'] ?? 'user'
            ));
        }

        $this->line(str_repeat('-', 60));
        $this->info('Всего: ' . count($users));
        return 0;
    }
}
// Module.php
$kernel->register('app:users', \App\Commands\UsersListCommand::class);
$ php iocli app:users
------------------------------------------------------------
ID       Email                     Роль
------------------------------------------------------------
1        admin@example.com         admin
2        user@example.com          user
------------------------------------------------------------
Всего: 2

$ php iocli app:users --role=admin --limit=10

Пример 4: Команда для генерации отчёта

<?php

namespace App\Commands;

use IO\Console\Command;

class ReportCommand extends Command
{
    protected string $signature = 'report:generate {type} {--from=} {--to=} {--output=}';
    protected string $description = 'Сгенерировать отчёт';

    public function handle(): int
    {
        $type = $this->argument('name');
        if ($type === null) {
            $this->error('Укажите тип отчёта (sales, users, inventory)');
            return 1;
        }

        $from = $this->option('from') ?? date('Y-m-01');
        $to = $this->option('to') ?? date('Y-m-d');
        $output = $this->option('output') ?? "reports/{$type}_" . date('Ymd') . '.csv';

        $this->line("Генерация отчёта: {$type}");
        $this->line("Период: {$from} — {$to}");
        $this->line("Файл: {$output}");

        $this->info("Отчёт создан: {$output}");
        return 0;
    }
}
// Module.php
$kernel->register('report:generate', \App\Commands\ReportCommand::class);
$ php iocli report:generate sales --from=2024-01-01 --to=2024-01-31 --output=sales_jan.csv
Генерация отчёта: sales
Период: 2024-01-01 — 2024-01-31
Файл: sales_jan.csv
Отчёт создан: sales_jan.csv

Запуск кастомных команд

Через имя команды (зарегистрированная команда)

$ php iocli app:hello Мир

Через command:run (по имени класса)

Команда command:run ищет класс в App\Commands\ по имени:

$ php iocli command:run SendEmail
# Ищет App\Commands\SendEmailCommand

$ php iocli command:run App\Commands\SendEmailCommand
# Полное имя класса

Порядок файлов

app/
├── Commands/
│   ├── SendEmailCommand.php
│   ├── GenerateReportCommand.php
│   └── UsersListCommand.php
├── Module.php          ← registerCommands()
└── ...

Важные замечания

  1. Имя команды в $signature и в $kernel->register() должны совпадать.
  2. Код возврата handle(): 0 — успех, 1 — ошибка.
  3. Позиционные аргументы — индексный массив, $argument('name') работает только если аргумент передан позиционно.
  4. Опции с = возвращают строку, флаги без = возвращают true или null.
  5. Перезапись встроенных команд: пользовательская команда с тем же именем перезапишет встроенную.
Prev
iocli