PHP with APC: Fatal errors: Cannot redeclare class
Asked Answered
C

7

19

Since I installed APC for PHP with PECL I get sometimes these errors: Cannot redeclare class xxx

xxx changes from time to time. I could disable APC but APC improves the performance great! Is there a known bug or could I do something else to prevent these errors? I'm using Ubuntu 8.04 LTS with PHP 5.2.4.


Edit/Update (from comments):

I use the Zend Framework Autoloader and these error never occurred before I enabled APC. A few moments ago I get for example that error: Fatal error: require(): Cannot redeclare class zend_db_adapter_abstract in /paths/app/lib/Zend/Db/Select.php on line 27

Conatus answered 1/1, 2011 at 19:19 Comment(5)
Read the whole error message. Do not include the said file twice. Use include_once. Or failing that, wrap all definitions in if (!class_defined("xxx")) {Alcohol
In addition to only using include_once, try and re-architect the application to make use of class autoloading, so that PHP will only include files when needed. Also stick to common-sense things, like one class per file, etc.Almanac
what do you mean by xxx? is xxx actually the class you want to load?Goetz
I use the Zend Framework Autoloader and these error never occurred before I enabled APC. A few moments ago I get for example that error: Fatal error: require(): Cannot redeclare class zend_db_adapter_abstract in /paths/app/lib/Zend/Db/Select.php on line 27Conatus
What version of APC are you running?Ain
U
13

The combination of the following configs fixed it for me:

apc.include_once_override = 0
apc.canonicalize = 0
apc.stat = 0

Without all 3, I'd constantly get the error, but with all three I seem to no longer get the error :)!

Unweave answered 12/2, 2012 at 2:0 Comment(2)
These three are not working for me unfortunately (APC 3.1.13 and PHP 5.4.24 CentOS 6.5). With WordPress it is the Walker_Page class that it claims is being redeclared, even though the file is absolutely not being called up more than once. I'll dig deeper and see what I can find.Shaff
Sorry Jason, this worked with some older version of APC and PHP. I know for sure that the PHP version I was working with at the time was no newer than 5.3.*Unweave
C
12

I had the same problem with a bunch of PHP libraries as soon as I enabled APC. After a lot of hair pulling I found that setting apc.include_once_override = 0 cleared things up. Still monitoring but haven't had a the problem re-occur (before that I was able to induce the error by clearing the apc cache).

Coplin answered 16/3, 2011 at 16:4 Comment(0)
J
3

This error happened when using Amazon's AWS SDK for PHP2 in a php script running under cron. One solution was to disable apc via -d apc.enabled=0 as shown below:

/usr/bin/php -d apc.enabled=0 /path/to/myshelljob.php

For more info.

Jockey answered 11/11, 2012 at 3:23 Comment(0)
A
2

Hmmm, seems to be a common issue:

What I just noticed from your specific error message is that you wrote zend_db_adapter_abstract in all-lowercase. A problem with the horrid framework naming schemes and autoloaders is that they keep files in mixed case and expect it so. If your code tried to instantiate it this way, the autoloader might not have found it. APC might be more peculiar here, since it overrides include_once internally, maybe with side-effects.

A solution would be to adapt the Zend autoloader, and manually keep a list of loaded classes and (absolute and lowercased) filenames to proofcheck in lieu of include_once.

Otherwise, try excessive xdebug-ing. Without access to your setup, all we can do is guess here.

Alcohol answered 1/1, 2011 at 21:0 Comment(0)
G
1

Well it is a known problem with apc that it mixes up include_once directivse that are called relatively from different locations.

So if you do include_once myclass.php and then in a subdirectory do include_once ../myclass.php apc could mix this up and think its different files and loads it twice.

However this is fixed in later versions.

If you can drill down your code to the class that is loaded twice you could do some checking if the class is already loaded with class_defined or some callable stuff.

You can also use the apc.filter directive to prevent certain files from beeing cached at all.

Goetz answered 1/1, 2011 at 20:14 Comment(1)
well the problem stays the same. upgrade your apc version and/or zend framework or you either have to patch your zend framework, there are solutions available on the zend issue tracker or maby you can catch the exception in your application.Goetz
P
1

Download the latest apc version and use:

[APC]
apc.cache_by_default = 0

With apc.stat = 0 the server loads the php files in cache, if you modify it, php still loads the same.

More info:

Paltry answered 19/2, 2013 at 13:48 Comment(0)
C
0

I just had this happen to me, and I didn't find the solution suggested in any of the other answers. I am using various autoloaders including Composer autoloader and an older version of the Zend Framework Autoloader.

The problem turned out to be caused by a slight name mismatch between the file name and the class name. One character different between the class name and the file name - a discrepancy that a human could easily miss but the a couple of autoloaders successively included the same file, causing the error.

Claustral answered 1/1, 2020 at 0:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.