2. Руководство разработчика › 2.7 Эксплуатация › Служебные методы

Набор методов платформы, которые не относятся ни к шаблонизатору, ни к базе данных, но нужны в коде модуля время от времени: узнать, кто выполняется сейчас, вызвать функцию своего модуля, собрать путь к загруженному файлу, оборвать страницу и отдать вместо неё другую.

Сведения о текущем модуле

UnitName() — имя выполняющегося модуля. Может пригодиться в библиотечных функциях, которым нужно знать, кто их вызвал (например, чтобы загрузить языковые теги именно этого модуля):

$tags = MELBIS_INC_LANGS_Tags($tpl, MELBIS()->UnitName());

UnitParam() — объявленные входные параметры всех загруженных модулей, массивом «имя модуля → список объявлений». Инструмент интроспекции: нужен служебным и отладочным модулям, которые строят карту проекта, а не обычному коду витрины.

Вызов функции своего модуля

UnitFunc($mName, ...$mParams) вызывает вспомогательную функцию текущего модуля по короткому имени: движок сам добавляет префикс модуля, принятый соглашением об именовании (см. «Принятые обозначения»).

// Внутри модуля melbis_store_card вызовет MELBIS_STORE_CARD_Price()
$price = MELBIS()->UnitFunc('Price', $store, $currency);

Смысл не в экономии символов, а в том, что имя функции перестаёт зависеть от имени модуля: переименовали модуль — переименовали функции, а вызовы остались прежними. Если функции с таким именем нет, разбор останавливается с ошибкой.

Граница у UnitFunc одна: он зовёт функции своего модуля. Функция, которую вызывают чужие юниты, — библиотечная: ей место в inc-модуле, зовётся она полным именем, и внутри себя она тоже ходит полными именами — контекст имени принадлежит вызвавшему юниту, и UnitFunc собрал бы имя от него.

В модуле с пространством имён метод тоже нужен, и по более важной причине. Свою функцию, имя которой известно на месте, там зовут просто по имени — Price($store, $currency), без всякого UnitFunc. А вот имя, пришедшее данными, PHP по текущему пространству не разрешает: строка в переменной всегда считается полным именем, и $func = 'Price'; $func(); уйдёт искать глобальную Price. Собрать правильное имя может только тот, кто знает выполняющийся модуль, — этим UnitFunc и остаётся полезен:

// Диспетчер веб-модуля: имя функции пришло из POST
return MELBIS()->UnitFunc($mVars['post']['func'], $mVars);

Обе формы имени метод проверяет сам — сначала модуль\Имя, затем прежнюю МОДУЛЬ_Имя, — поэтому один и тот же диспетчер работает и в плоском модуле, и в объявленном.

UnitRun($mUnit, $mFunc, ...$mParams) подключает юнит и выполняет его функцию под его именем — как если бы её позвали изнутри этого юнита, поэтому UnitFunc внутри вызова работает. Этим методом агентский эндпоинт запускает AI-инструменты, и это его единственное назначение.

Из кешируемого модуля вызов запрещён — движок остановит страницу с ошибкой. Причина в зависимостях: запрос, выполненный под чужим именем, припишется не звавшему, и кеш звавшего перестанет зависеть от таблицы, которую он на самом деле читает. Модулю, которому нужна чужая функция, нужна библиотека: подключите её в манифесте и зовите функцию по имени напрямую — заодно уцелеют ссылки, о чём предупреждает абзац ниже.

$answer = MELBIS()->UnitRun('melbis_agent_user', 'MELBIS_AGENT_USER', $action, $user_id, $command, $params);

Имя функции здесь передаётся целиком, поэтому у юнита с пространством имён оно пишется через слеш — 'melbis_agent_user\Main'.

Ссылки через эти методы не проходят. Аргументы собираются в массив, а массив теряет связь с переменной вызывающего, поэтому функция с &$ в подписи получит копию и молча отработает вхолостую. Такие функции зовут по имени напрямую — в модуле с пространством имён это как раз обычный короткий вызов.

Путь к загруженным файлам

FilePath($mUploadTime, $mFileName = '') строит путь к файлу по дате его загрузки — картинки и вложения раскладываются по каталогам вида files/2026/07_22/14_30/:

$url = MELBIS()->FilePath($image['upload_time'], $image['file_name']);

Без имени файла вернёт путь к каталогу, со слешем на конце — в этом виде метод повторяет шаблонный модификатор |path. Если передать null вместо даты, метод переключается на каталог текущей группы шаблонов: так адресуются статические файлы оформления.

С именем файла добавляется проверка WebP. Для .jpg, .jpeg и .png метод смотрит, есть ли уже готовая WebP-версия в кеше, и если есть — возвращает путь к ней, а если нет — к оригиналу. Важно, что FilePath ничего не конвертирует: он только пользуется тем, что уже сконвертировано. Создают кеш модификаторы |webp и |text:webp — они делают преобразование на ходу, при первом же выводе картинки (см. «Модификаторы»). Поэтому путь от FilePath ведёт на WebP только для файлов, которые витрина уже хоть раз показывала.

В вёрстке пользуйтесь модификаторами; метод нужен, когда путь участвует в логике модуля — например, при проверке существования файла или при сборке ссылки для внешней выгрузки.

Аварийное завершение

Модуль, прерывающий работу нештатно, обязан снять служебную блокировку компиляции кеша — это делают методы Stop() и Halt(). Они описаны в разделе «Журналы, ошибки и метрики».

Отдать другую страницу вместо текущей

Иногда модуль посреди работы выясняет, что показывать нечего: товар удалён, раздел закрыт, ссылка устарела. Вместо того чтобы возвращать пустой фрагмент в уже собираемую страницу, её можно оборвать и отдать браузеру другую целиком.

function MELBIS_INC_404()
{
    MELBIS()->Stop();

    header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
    MELBIS()->Run('melbis_base_404', []);

    header('Content-type: text/html; charset='.MELBIS_CHARSET);
    echo MELBIS()->Fetch();

    exit;
}

По строкам:

Приём удобно держать в библиотеке (inc) и вызывать из любого модуля, которому понадобилось прервать страницу.