Magento2 - настройка: di: compile

12

Я работал над проектом с каким-то нестандартным кодом ... это наш первый "средний" проект Magento 2, поэтому (как и все люди здесь, я думаю) каждый день мы узнаем что-то новое, и мы должны изменить способ решения с этой новой версией Magento

Причиной этого вопроса является вопрос о команде setup:di:compile

Я использую его с первого дня в Magento 2, так как bin / magento запрашивает его после каждого setup:upgradeс сообщением «Пожалуйста, повторите команду компиляции Magento»

Ну ... Я обнаружил, что setup:di:compileв этом проекте выполняется страница просмотра продуктов с перерывами с совершенно неоднозначной фатальной ошибкой. Я потратил целые рабочие дни на отладку и тестирование с изменениями кода с нулевым результатом

Сегодня я обнаружил, что если я пропущу эту команду, то все работает как чудо, даже в производственном режиме

Итак, вопрос в том ... что именно эта setup:di:compileкоманда? Это обязательно? Просто рекомендовал? Или это какая-то устаревшая команда, которую не нужно выполнять?

ОБНОВИТЬ

Как требовали некоторые пользователи, это Фатальная Ошибка, о которой я говорил

Неустранимая ошибка PHP: невозможно создать экземпляр абстрактного класса Magento \ Каталог \ Блок \ Продукт \ Вид \ AbstractView в *** / vendor / magento / framework / ObjectManager / Factory / AbstractFactory.php в строке 93

Я искал любой пользовательский блок, используя Magento \ Catalog \ Block \ Product \ View \ AbstractView, но нашел его только в файлах макета, его нет ни в одном конструкторе класса блока

Что я не могу понять, так это то, почему Magento генерирует эту Fatal Error со скомпилированным кодом, но это работает как чудо без скомпилированного кода

Рауль Санчес
источник
Вы можете подтвердить, что «setup: di: compile» также вызывает ошибку просмотра продукта в режиме разработки?
Пай
да, фатальная ошибка происходит в обоих режимах
Рауль Санчес
Можете ли вы опубликовать «совершенно неоднозначную фатальную ошибку»?
Пай
Я обновил вопрос с ошибкой. Спасибо
Рауль Санчес

Ответы:

21

Команда команда setup:di:compileгенерирует содержимое var/diпапки в Magento <2.2 и generated для Magento> = 2.2

Согласно Magento, это служит следующей цели:

  • Генерация кода приложения (фабрики, прокси и т. Д.)
  • Агрегирование конфигурации области (то есть оптимизированные конфигурации внедрения зависимостей для каждой области)
  • Генерация перехватчиков (то есть оптимизированная генерация кода перехватчиков)
  • Генерация кеша перехвата
  • Генерация кода репозитория (то есть сгенерированного кода для API)
  • Генерация атрибутов служебных данных (то есть сгенерированных классов расширений для объектов данных)

Источник ( http://devdocs.magento.com/guides/v2.0/config-guide/cli/config-cli-subcommands-compiler.html )

Тем не менее, когда вы переводите Magento в рабочий режим, без компиляции он действительно работает. Таким образом, согласно документации Magento, это скорее шаг оптимизации (то есть оптимизированная генерация кода перехватчиков)

Когда у нас есть ошибки в setup:di:compileкоманде, это в основном из-за ошибок в одном из конструкторов пользовательских классов php.

Tjitse
источник
1
Спасибо! Так что это совершенно необязательно ... Всего лишь один момент, так что для меня это более понятно. В нашем случае setup: di: compile не выдает никаких ошибок, команда заканчивается нормально. Это происходит при просмотре сайта, после выполнения команды, когда запускается Fatal Error, на страницах просмотра продукта
Рауль Санчес
Может быть, вы можете опубликовать ошибку? Это сделало бы вещь более ясной.
Тице
Я обновил вопрос с ошибкой. Спасибо
Рауль Санчес
12

Не обязательно запускать setup:di:compileкоманду каждый раз, но если вы сделали какое-либо изменение кода, особенно с использованием фабричных методов, прокси, добавления плагинов или какой-либо компиляции кода, то вам необходимо запустить эту команду.

Подробнее

magento setup:di:compileдля того, чтобы сгенерировать необходимые файлы. Оба варианта заканчиваются генерацией классов в MAGENTO_ROOT/var/generation directory(или, /generatedесли Magento 2.2+).

Какие классы генерируются?

  1. Заводы
  2. Доверенные
  3. Плагины

Заводы

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

Доверенные

Magento 2 использует инжектор конструктора, в котором требуются все зависимости. Вы не можете создать экземпляр объекта, не пройдя все зависимости. Что делать, если вы хотите иметь дополнительные зависимости? Вот почему существуют прокси.

Плагины (Перехватчики)

Проще говоря, плагины являются основными механизмами настройки для Magento 2. Больше никаких переписываний классов. Это позволяет вам подключиться и сделать что-то до, после или вокруг любого публичного метода приложения.

когда вы запускаете команду setup: di: compile, она выполняет следующие действия

Компиляция кода состоит из всего перечисленного в произвольном порядке:

  • Генерация кода приложения (фабрики, прокси и т. Д.)

  • Агрегирование конфигурации области (то есть оптимизированные конфигурации внедрения зависимостей для каждой области)

  • Генерация перехватчиков (то есть оптимизированная генерация кода перехватчиков)

  • Генерация кэша перехвата Генерация кода репозитория (то есть сгенерированного кода для API)

  • Генерация атрибутов служебных данных (то есть сгенерированных классов расширений для объектов данных)

Обратитесь к этому ответу, чтобы узнать, когда мы должны выполнить какие команды: /magento//a/184927/35758

Принц Патель
источник
Спасибо! Так что это совершенно необязательно ... Всего лишь один момент, так что для меня это более понятно. В нашем случае setup: di: compile не выдает никаких ошибок, команда заканчивается нормально. Это происходит при просмотре сайта, после завершения команды, когда запускается Fatal Error, на страницах просмотра продукта ... поэтому я не очень понимаю, почему не скомпилированный код работает хорошо, но при компиляции происходит Fatal Error
Рауль Санчес,
Это может произойти, если ваш подкласс добавил новые зависимости после существующих необязательных зависимостей родительского класса. Вы можете исправить это, переместив любой новый обязательный параметр выше необязательных.
Принц Патель
2

Magento по-прежнему будет работать в рабочей среде и разрабатываться без команды di: compile. Он на самом деле скомпилирует Interceptors и сохранит их в generatedпапке.

Даже если это работает, это не значит, что вы должны пропустить этот шаг! Фактически, когда это выполняется, magento также проверяет наличие дублированных инъекций, циклов зависимости и других фундаментальных шагов, которые сделают ваш сайт более стабильным и с меньшей вероятностью сбоят и! Умрут.

Я твердо верю, что эта ошибка связана с использованием класса, который Magento не может скомпилировать из-за неправильного аргумента конструктора.

Ошибка, которую вы опубликовали, довольно расплывчата, но я полагаю, что у вас есть класс, который расширяет AbstractViewкласс, 99% это блок где-то в ваших пользовательских модулях, который не передает правильные аргументы parent::__construct()методу . Следовательно, когда он создается, он терпит неудачу.

Обратите внимание, что все блоки расширяют класс AbstractView, поэтому вам нужно будет выполнить команду compile с помощью xdebugon и установить журнал на просмотр трассировки стека, чтобы увидеть, какой класс вызвал его последним, прежде чем произошел сбой.

Тот факт, что сайт работает без этой ошибки, означает, что вы фактически не используете поврежденный блок где-либо на своей странице, но Magento все равно будет пытаться скомпилировать его при запуске compileкоманды, поэтому он не работает.

drew7721
источник
Спасибо, что нашли время ответить на старый вопрос, подобный этому, с другими проверенными ответами ... На самом деле, я решил это, исправив неправильные блоки в пользовательских макетах, как вы указали
Рауль Санчес