Начинай с registration.php. Без него расширение просто не существует в системе. Строка подключения вида \Magento\Framework\Component\ComponentRegistrar::register() не обсуждается. Жестко, однозначно, без вариантов. Не подключил – система игнорирует весь код. Убедись, что путь прописан точно. Ошибка в регистре имени – и ты два часа разбираешься, почему Composer всё видит, а Magento – нет.
Дальше module.xml – декларация намерений. setup_version – это якорь миграций. Меняешь – Magento пересоздаёт структуру БД. Пропустил или ошибся – получаешь странное поведение и неконсистентную схему. Файл должен лежать в каталоге etc/. Не в корне, не в setup. Только там. Формат строгий, не допускает самодеятельности. От версии ядра зависит допустимая структура. На 2.4.6 – одна, на 2.3 – другая.
composer.json нужен не Magento, а системному окружению. Тут идут зависимости, авто-загрузка классов, namespace. Важное: PSR-4. Без правильного "autoload": { "psr-4": {}} класс из Helper или Model не загрузится. У тебя всё написано, а система говорит – ничего нет. Боль, ярость, grep по всей vendor-папке. Лучше проверь дважды, чем зарываться в логи.
Важно помнить: структура директории, регистр имён, соответствие namespace – всё должно быть безошибочно. Magento не прощает мелочей.
Особенность: в Linux важно, чтобы registration.php имел корректные права. Особенно на системах с SELinux. На CentOS с этим просто беда. chcon или restorecon может понадобиться, если модуль «невидим» для PHP-FPM. Проверяй через ls -Z. На Debian проще, но тоже без гарантий – смотря как настроен Apache или Nginx.
Слишком часто вижу попытки использовать require_once вместо автозагрузки. Это не Laravel. Это не Slim. Тут жёсткая архитектура. Нарушишь её – получишь проблемы при компиляции, в DI, при deploy с использованием bin/magento setup:di:compile.
Внимание! Любые изменения в структуре модуля требуют выполнения
bin/magento setup:upgradeи желательно – очистки кэша. Без этого можешь не понять, что изменения не применились.
Не забывай про etc/di.xml и etc/frontend/routes.xml – без них контроллеры и зависимости не работают. Но об этом – в следующем разделе.
Содержание статьи
Создание и настройка файла module.xml для регистрации модуля
Путь однозначный: app/code/Vendor/Namespace/etc/module.xml. Файл обязан существовать. Без него система не инициализирует компонент. Вообще. Никак. Неважно, какие классы, контроллеры и зависимости ты написал – без этого элемента вся структура будет проигнорирована.
Минимальная структура выглядит так:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_Namespace" setup_version="1.0.0"/>
</config>
name должен точно совпадать с названием, указанным в registration.php и composer.json. Без этого – конфликт идентификаторов, ошибки компиляции, невозможность отката миграций. Регистр важен. Linux не прощает расхождений. Особенно на Arch и CentOS с жёсткими SELinux политиками.
setup_version влияет на работу setup:upgrade. Изменил значение – запустится обновление структуры БД. Не изменил – миграции проигнорируются. Зависит от твоего InstallSchema.php и UpgradeSchema.php. Без них – просто фиксация версии. С ними – триггер обновлений.
Внимание! Если ты вручную правишь таблицы, но не меняешь setup_version – получаешь рассинхрон состояния и трудноотлавливаемые баги при деплое.
Вариант с зависимостями тоже возможен:
<module name="Vendor_Namespace" setup_version="1.0.0">
<sequence>
<module name="Magento_Store"/>
<module name="Magento_Catalog"/>
</sequence>
</module>
Поле sequence определяет порядок загрузки. Если ты переопределяешь layout, observer или di-конфигурации – зависимость нужна. Не указал – получил race condition. Компонент загружается раньше, чем его основа. Результат – ошибки, которых не должно быть.
Важно помнить:
module.xmlчитается только при первом включении и при обновлениях. Безsetup:upgradeизменения игнорируются.
Никаких комментариев в теле. Никаких нестандартных тегов. Всё валидацию проходит по module.xsd, и если ты добавишь нечто нестандартное – получишь сбой на этапе deploy или компиляции.
Хочешь быть уверен – запускай bin/magento module:status и проверяй, что компонент отображается как активный. Если нет – файл либо отсутствует, либо написан с ошибками. Простая проверка, экономит кучу времени.
Определение зависимостей и версии модуля в файле composer.json
Не укажешь autoload – классы не подтянутся. Не укажешь require – система не соберётся. Простой, но строгий синтаксис. Ошибся – Composer выбросит.
Пример работающего блока:
{
"name": "vendor/namespace",
"description": "Локальное расширение",
"type": "magento2-module",
"version": "1.0.3",
"require": {
"php": "^7.4 || ^8.1",
"magento/framework": "103.0.*"
},
"autoload": {
"psr-4": {
"Vendor\\Namespace\\": ""
}
}
}
type должен быть magento2-module. Это не обсуждается. Composer без этого не распознаёт структуру. version используется для контроля зависимости в других пакетах. Также может быть подхвачена setup_version из module.xml при корректной интеграции.
require – единственный механизм, чтобы указать совместимость. Хочешь, чтобы твой компонент не устанавливался в старую версию ядра? Укажи жёсткое ограничение. Иначе – ловишь сегфолт на проде.
Важно: всегда указывай зависимости от ядра. Без этого Composer может стянуть несовместимую версию библиотеки. Результат – нерабочий код, странные ошибки, поломанный контейнер зависимостей.
Теперь к autoload. Без PSR-4 система не найдёт классы. Даже если они лежат по пути, даже если IDE их видит. Magento использует автозагрузку Composer, всё или ничего.
Если папка Vendor/Namespace лежит в корне, путь должен быть пустым – "". Укажешь "src/" или ошибёшься в слэше – автозагрузка мимо. В CentOS, где SELinux режет права по умолчанию – всё ещё хуже. Класс не грузится, логов нет, просто 500-я ошибка. Ищи иголку в стоге логов.
Помните: любые правки в composer.json требуют
composer dump-autoload. Иначе ничего не произойдёт. Magento не знает о твоих изменениях, пока Composer не перегенерирует карту автозагрузки.
Никогда не оставляй require пустым. Даже если компонент без зависимостей – укажи минимальную версию PHP. Без этого Composer может подумать, что ты не знаешь, что делаешь.
- type: всегда
magento2-module - autoload.psr-4: строгое соответствие namespace и пути
- require: минимум php и magento/framework
- version: для контроля и понимания состояния
Проверь валидность через composer validate. Ошибки там часто неочевидны. И никогда, вообще никогда, не комить composer.lock в репозиторий локального расширения. Это не библиотека. Composer с ума сходит от такого поведения в monorepo.
Описание настроек модуля и точек расширения в файле etc/module.xml
Без setup_version никакие миграции не запустятся. Это якорь. Меняешь версию – триггерится обновление схемы. Не меняешь – система игнорирует изменения в InstallSchema или UpgradeSchema. Особенно критично на Red Hat и CentOS, где кеш агрессивно держится в памяти.
Если требуется, указывай последовательность запуска через sequence. Это влияет на порядок регистрации. Используется в случаях, когда нужно перекрыть настройки других компонентов или зависит загрузка классов и интерфейсов.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_Namespace" setup_version="1.0.2">
<sequence>
<module name="Magento_Catalog"/>
<module name="Magento_Customer"/>
</sequence>
</module>
</config>
name должен быть строго уникальным. Иначе конфликт на уровне регистрации. Особенно при использовании composer path-repository. Частая ошибка – копипаст названия и забывание переименовать. И результат – полное бездействие без ошибок.
sequence позволяет контролировать момент активации. Нужно доработать layout, который уже определён другим расширением? Ставь его в зависимости. Надо внедриться в события, которые объявлены Magento_Sales? Добавляй зависимость, иначе компонент с твоими подписчиками просто не прогрузится.
Важно помнить: порядок в
sequenceвлияет на ди-компиляцию и цепочку плагинов. Ошибся – получил недетерминированное поведение. Ловить потом в xdebug – боль.
Дополнительные теги, вроде schema_version или кастомные атрибуты, не поддерживаются. Любое отклонение от схемы module.xsd вызовет падение при компиляции. Проверяется при bin/magento setup:upgrade и di:compile.
Внимание! Никогда не редактируй этот XML в IDE без схемы. Автозаполнение может вставить атрибуты, несовместимые со спецификацией. Проверяй через xmllint или по xsd вручную.
Системы на базе Debian обычно прощают мелкие ошибки из-за менее агрессивного кеширования. Arch, наоборот, моментально выстреливает ошибкой. На проде, где сборка идёт в Docker – малейшее отклонение и ты получаешь ошибку прямо в пайплайне CI/CD.
Файл читается один раз – в момент регистрации. Если изменил структуру – перезапускай setup:upgrade, сбрасывай кеш, компилируй повторно. Иначе ты тестируешь старое состояние, думая, что работаешь с новым кодом. Глупо. Опасно.

