Magento2-设置:di:编译


12

我一直在一个带有自定义代码的项目中工作……这是我们的第一个“中等” Magento 2项目,因此(正如我在这里的所有人一样),我们每天都在学习新事物,我们必须改变处理方式这个新的Magento版本

这个问题的原因是询问命令 setup:di:compile

从第一天开始,我就一直在与Magento 2一起使用它,因为bin / magento每次都要求它setup:upgrade,并显示消息“请重新运行Magento编译命令”

好吧...我发现setup:di:compile在这个项目中执行中断产品视图页面时,出现了完全模棱两可的致命错误。我花了整个工作日试图调试它,并用零结果更改代码进行测试

今天,我发现如果省略该命令,那么即使在生产模式下,所有命令都可以像超级按钮一样工作

所以,问题是...该setup:di:compile命令究竟是什么?需要吗?刚推荐?还是它是一些已过时的命令,不需要执行?

更新

正如某些用户所要求的,这是我所指的致命错误

PHP致命错误:无法在第93行的*** / vendor / magento / framework / ObjectManager / Factory / AbstractFactory.php中实例化抽象类Magento \ Catalog \ Block \ Product \ View \ AbstractView

我已经使用Magento \ Catalog \ Block \ Product \ View \ AbstractView搜索了任何自定义块,但仅在布局文件中找到了它,而在任何块类构造函数中都没有

我不明白的是:为什么Magento会在编译后的代码中引发致命错误,但如果没有编译后的代码,它就像一个咒语


您是否可以确认“ setup:di:compile”也会在开发模式下导致产品视图错误?
paj

是的,两种模式都发生致命错误
Raul Sanchez

您可以发布“完全模棱两可的致命错误”吗?
paj

我已将问题更新为错误。谢谢
Raul Sanchez

Answers:


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类的构造函数之一存在错误。


1
谢谢!因此,这完全是可选的...仅一点,所以对我来说更清楚。在我们的例子中,setup:di:compile不会抛出任何错误,命令可以正常结束。在产品视图页面中,当命令执行完毕后,在浏览站点时,当引发致命错误时
Raul Sanchez

也许您可以发布错误?那会让事情变得更清楚。
吉尔吉斯(Tjitse)'17

我已将问题更新为错误。谢谢
Raul Sanchez

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生成的代码)

  • 服务数据属性生成(即,生成的数据对象扩展类)

当我们应该运行哪些命令时,请参考此答案:https : //magento.stackexchange.com/a/184927/35758


谢谢!因此,这完全是可选的...仅一点,所以对我来说更清楚。在我们的例子中,setup:di:compile不会抛出任何错误,命令可以正常结束。它是在浏览网站时,在命令完成之后,在产品视图页面中引发致命错误时……所以我不太明白为什么编译后的代码无法正常工作,但是编译时会发生致命错误
Raul Sanchez

如果您的子类在父类的现有可选依赖项之后添加了新的依赖项,则会发生这种情况。您可以通过将任何新的必需参数上移到可选参数之上来解决此问题。
帕特尔王子(Patel Prince)

2

Magento仍将在没有di:compile命令的情况下在生产和开发环境中运行。实际上,它将根据需要编译拦截器并将其存储在generated文件夹中。

即使有效,也不意味着您应该跳过此步骤!实际上,当运行该命令时,magento还会检查重复的注入,依赖项循环和其他基本步骤,这些步骤将使您的站点更稳定,并且更不会崩溃和死!

我坚信该错误是由于使用了由于某些错误的构造函数参数而导致Magento无法编译的类。

您发布的错误非常模糊,但是我相信您有一个扩展AbstractView该类的类,有99%的错误是您的自定义模块中某个未将正确参数传递给parent::__construct()方法的块。因此,在实例化时会失败。

请注意,所有块都扩展了AbstractView类,因此您必须使用xdebugon 命令执行compile命令,并在堆栈跟踪中设置日志,以查看在失败之前最后一次调用它的类。

该站点可以正常运行而没有该错误,这意味着您实际上并没有在页面上的任何地方使用损坏的块,但是Magento在运行compile命令时仍会尝试对其进行编译,因此会失败。


感谢您抽出宝贵的时间回答这样一个较旧的问题以及其他经过验证的答案...实际上,正如您所指出的,我通过在自定义布局中修复错误的块来解决了这一问题
Raul Sanchez
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.