21

I have been working in a project with some custom code... this is our first "medium" Magento 2 project, so (as all people here I think) every day we learn new things, and we have to change the way to deal with this new Magento version

The reason for this question is asking about the command setup:di:compile

I've been using it since the first day with Magento 2, as bin/magento asks for it after every setup:upgrade, with message "Please re-run Magento compile command"

Well... I have found executing setup:di:compile breaks product view page in this project, with a totally ambiguous Fatal Error. I've spent whole working days trying to debug it and testing with code changes with zero result

Today, I have discovered that if I omit that command then all works like a charm, even in production mode

So, the question is... what exactly does that setup:di:compile command? Is it required? Just recommended? Or it is some deprecated command, which is not needed to be executed?

UPDATE

As some users have required, this is the Fatal Error I was referring

PHP Fatal error: Cannot instantiate abstract class Magento\Catalog\Block\Product\View\AbstractView in ***/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93

I've searched for any custom block using Magento\Catalog\Block\Product\View\AbstractView but I've found it only in layout files, it is not present in any block class constructor

What I can't understand is: why Magento is throwing this Fatal Error with compiled code, but it works like a charm without compiled code

4
  • can you confirm that 'setup:di:compile' causes the product view error in development mode too?
    – paj
    Commented Jul 18, 2017 at 10:28
  • yes, Fatal Error occurs in both modes Commented Jul 18, 2017 at 14:51
  • Can you post the "totally ambiguous Fatal Error"?
    – paj
    Commented Jul 18, 2017 at 15:55
  • I have updated the question with error. Thanks Commented Jul 19, 2017 at 8:06

3 Answers 3

31

The command setup:di:compile command generates the contents of the var/di folder in Magento <2.2 and generated for Magento >= 2.2

According to Magento, this serves the following purpose:

  • Application code generation (factories, proxies, and so on)
  • Area configuration aggregation (that is, optimized dependency injection configurations per area)
  • Interceptor generation (that is, optimized code generation of interceptors)
  • Interception cache generation
  • Repositories code generation (that is, generated code for APIs)
  • Service data attributes generation (that is, generated extension classes for data objects)

Source (http://devdocs.magento.com/guides/v2.0/config-guide/cli/config-cli-subcommands-compiler.html)

However, when you place Magento in production mode, without compilation it indeed still works. So according to the Magento docs this is more an optimization step (that is, optimized code generation of interceptors)

When we have errors in the setup:di:compile command, this is mostly because of errors in one of the constructors of custom php classes.

3
  • 1
    Thanks! So, it is totally optional... Just one point, so it is more clear to me. In our case, setup:di: compile does not throw any error, command ends ok. It is when browsing the site, after command has finished, when Fatal Error is fired, in product view pages Commented Jul 18, 2017 at 14:55
  • Maybe you can post the error? That would make thing more clear.
    – Tjitse
    Commented Jul 19, 2017 at 7:15
  • I have updated the question with error. Thanks Commented Jul 19, 2017 at 8:06
17

It's not mandatory to run setup:di:compile command everytime but if you have done any code change specially with factory methods ,proxy, add plugins or any code compilation then you must need to run this command.

More Details

magento setup:di:compile in order to generate necessary files. Both options ends up with generating classes in MAGENTO_ROOT/var/generation directory (or /generated if Magento 2.2+).

What classes are generated?

  1. Factories
  2. Proxies
  3. Plugins

Factories

Factories are used to instantiate objects that can not be injected automatically. For example, a product object has to be loaded from the database, but dependency injection container doesn’t have enough information to create this object. That’s why we use factories.

Proxies

Magento 2 uses constructor injection in which all dependencies are required. You cannot instantiate an object without passing all dependencies. What if you’d like to have optional dependencies? That’s why proxies exist.

Plugins (Interceptors)

Simply put, plugins are the primary customization mechanisms for Magento 2. No more class rewrites. It allows you to hook in and do something before, after or around any public method of the application.

when you run setup:di:compile command it do below things

Code compilation consists of all of the following in no particular order:

  • Application code generation (factories, proxies, and so on)

  • Area configuration aggregation (that is, optimized dependency injection configurations per area)

  • Interceptor generation (that is, optimized code generation of interceptors)

  • Interception cache generation Repositories code generation (that is, generated code for APIs)

  • Service data attributes generation (that is, generated extension classes for data objects)

Refer this answer for when we should run which commands: https://magento.stackexchange.com/a/184927/35758

4
  • Thanks! So, it is totally optional... Just one point, so it is more clear to me. In our case, setup:di: compile does not throw any error, command ends ok. It is when browsing the site, after command has finished, when Fatal Error is fired, in product view pages... so I don't really understand why not compiled code works nice but when compiling then Fatal Error happens Commented Jul 19, 2017 at 7:56
  • This can happen if your sub-class added new dependencies after the existing optional dependencies of the parent class. You can fix this by moving any new required parameter up above the optional ones. Commented Jul 19, 2017 at 8:32
  • @PrincePatel Please can you answer this question magento.stackexchange.com/questions/279795/…
    – Duke
    Commented May 31, 2020 at 6:25
  • I often added plugins and I never had to run setup:di:compile after it. It worked without (developer mode)
    – Black
    Commented Dec 2, 2020 at 14:22
3

Magento will still run in production and dev without the di:compile command. It will actually compile the Interceptors as it needs to and store the in the generated folder.

Even if it works, that does not mean you should skip this step! In fact, when this is ran, magento also checks for duplicated injections, dependency loops and other fundamental steps that will make your site more stable and less likely to crash and !die.

I strongly believe that that error is due to the use of a class that Magento can't compile due to some wrong constructor argument.

The error you posted is pretty vague, but I believe you have a class that extends the AbstractView class, 99% it's a block somewhere in your custom modules that does not pass the correct arguments to the parent::__construct() method. Hence when instantiated it fails.

Note that all blocks extend the AbstractView class so you'll have to execute the compile command with xdebug on and set a log at look at the stack trace to see what class called it last before it failed.

The fact that the site runs without that error means that you're not actually using the corrupted block anywhere on your page, but Magento will still try to compile it when running the compile command, hence it fails.

1
  • Thanks for taking the time to answer an older question like this, with other validated answers... In fact, I resolved this by fixing that wrong blocks in custom layouts, as you have pointed Commented Feb 22, 2018 at 15:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.