4

I am getting an error message in my Laravel 5 application:

PHP Fatal error:  Cannot redeclare class Illuminate\\Contracts\\Support\\Arrayable in /var/www/.../bootstrap/cache/compiled.php on line 156

This error only occurs on my staging environment and not on my local website. I would love to post more info but I do not have it. Because I do not know where this error is caused.

If I remove the file (cache/compiled.php) everything seems to work fine. But after every deploy the same error occurs. On my localhost everything works fine as well.

My question: does anybody have a clue where to look because I am out of ideas.

markioooo
  • 51
  • 8

4 Answers4

4

Try this way.
At first remove the cache/compiled.php file
then run this command

php artisan clear-compiled
Imtiaz Pabel
  • 5,307
  • 1
  • 19
  • 24
  • Removing the cache/compiled.php file (and executing php artisan clear-compiled and php artisan cache:clear) will temporary fix this until I redeploy my project (using Capistrano). I use the same setup for other projects and I have no problems there. – markioooo Sep 22 '15 at 15:17
  • The solution above doesn't work in cases where the dependency problem happens during regular application boot, because artisan itself won't run. In that case the only solution is to manually remove bootstrap/cache/compiled.php. – JamesG May 17 '17 at 01:29
1

I had the same problem and found the following article, which was very helpful:

https://sentinelstand.com/article/laravel-5-optimization-commands

The only solution that was working for me was manually deleting bootstrap/cache/compiled.php. Switching around the order in which the autoloaders are called in bootstrap/autoload.php did not work for me because I had the same problem the other way round, ie. I had a class in compiled.php that was causing something from autoload.php to be autoloaded before autoload.php ran.

In my case, I am using a combination of PSR4 and manual class mappings in my composer.json file. I'm sure this is part of the problem. (Don't judge me: this app started in Laravel 3, so it's taking time to add namespacing throughout the code base :-).

One reason why things may work differently in different environments is because the artisan optimize command will only generate the bootstrap/cache/compiled.php file if you provide the --force option or if debugging mode is not enabled. So it is likely that you are not getting this file in development because debugging is enabled but are getting this file in staging and/or production because debugging is not enabled.

Ultimately, here's what I have landed on as a solution for production deployments:

  1. artisan config:cache
  2. artisan optimize
  3. rm bootstrap/cache/compiled
  4. Update symlink to point to new version.

This way you still get bootstrap/cache/services.json, which is helpful, whereas artisan clear-compiled removes that file. Also, there will be a very brief period of time where bootstrap/cache/compiled.php will exist, which is why it is important to run these commands before you update the symlink to point your web server at the new version.

It is also worth noting that the compiled.php file that is created by artisan optimize in Laravel 5.1 is no longer generated in Laravel 5.4 because, as Taylor has stated, PHP 7 is much more performant and so the benefit of bundling all the application classes into one file, which is meant to save on disk I/O, is negligble now. Taylor recommends enabling and properly configuring your OPcache instead - you will get far more performance benefits from that.

JamesG
  • 4,288
  • 2
  • 31
  • 36
0

I experienced the same but eventually found the solution.

I have my own helpers.php files in laravel. Just like the framework ones, I added them as autoloads in my composer.json. A couple of those functions are macros for the Collection (\Illuminate\Support\Collection::macro(...)).

When that helpers.php file is autoloaded, the definition of those macros cause the autoloading of Illuminate\Support\Collection. This in turn uses Illuminate\Contracts\Support\Arrayable. So basically all of these are already loaded by the time they are defined again in cache/compiled.php. Boom.

Long story short: For me the fix was simply to switch inclusion of the compiled file and the autoloader around.

bootstrap/autoload.php:

$compiledPath = __DIR__.'/cache/compiled.php';

if (file_exists($compiledPath)) {
   require $compiledPath;
}

require __DIR__.'/../vendor/autoload.php';

This might not be a viable solution add include code in your compiled file runs right away and refers to helper functions, but I think the chances on that happening should be pretty minimal.

Blizz
  • 8,082
  • 2
  • 33
  • 53
-1

The problem is with the artisan optimize command. If you remove the compiled.php file and then do not run optimize, it should work.

revolt_101
  • 395
  • 3
  • 12