PHP 与 APC:致命错误:无法重新声明类
由于我使用 PECL 安装了 APC for PHP,有时会出现以下错误: Cannot redeclare class xxx
xxx 有时会发生更改。我可以禁用 APC,但 APC 极大地提高了性能!是否存在已知错误或者我可以采取其他措施来防止这些错误?我正在使用 Ubuntu 8.04 LTS 和 PHP 5.2.4。
编辑/更新(来自评论):
我使用 Zend Framework Autoloader,在启用 APC 之前从未发生过这些错误。不久前,我收到了这样的错误: Fatal error: require(): Cannot redeclare class zend_db_adapter_abstract in /paths/app/lib/Zend/Db/Select.php on line 27
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
以下配置的组合为我解决了这个问题:
如果没有全部 3 个配置,我会不断收到错误,但是有了所有三个配置,我似乎不再收到错误:)!
The combination of the following configs fixed it for me:
Without all 3, I'd constantly get the error, but with all three I seem to no longer get the error :)!
当我启用 APC 后,我对一堆 PHP 库也遇到了同样的问题。经过一番努力后,我发现设置 apc.include_once_override = 0 可以解决问题。仍在监控,但没有再次出现问题(在此之前我能够通过清除 apc 缓存来引发错误)。
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).在
cron
下运行的 php 脚本中使用适用于PHP2
的 AmazonAWS SDK
时,会发生此错误。一种解决方案是通过-d apc.enabled=0
禁用apc
,如下所示:对于 更多信息。
This error happened when using Amazon's
AWS SDK
forPHP2
in a php script running undercron
. One solution was to disableapc
via-d apc.enabled=0
as shown below:For more info.
嗯,似乎是常见问题:
我刚刚从您的具体错误消息中注意到,您以全小写形式编写了
zend_db_adapter_abstract
。可怕的框架命名方案和自动加载器的一个问题是它们以混合大小写形式保存文件并期望如此。如果您的代码尝试以这种方式实例化它,自动加载器可能找不到它。 APC 在这里可能更特殊,因为它在内部覆盖include_once
,可能会产生副作用。解决方案是调整 Zend 自动加载器,并手动保留加载的类和(绝对和小写)文件名的列表以代替 include_once 进行校对。
否则,尝试过度的 xdebug-ing。如果无法访问您的设置,我们所能做的就是在这里猜测。
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 overridesinclude_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.
这是 apc 的一个已知问题,它混合了从不同位置相对调用的
include_once
指令。因此,如果您执行
include_once myclass.php
,然后在子目录中执行include_once ../myclass.php
apc 可能会将其混合起来并认为它是不同的文件并加载它两次。不过,这在以后的版本中得到了修复。
如果您可以将代码深入到加载两次的类,您可以检查该类是否已经加载了
class_define
或一些可调用的内容。您还可以使用 apc.filter 指令来阻止某些文件被缓存。
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 doinclude_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.下载最新 apc 版本并使用:
apc.stat = 0 服务器加载缓存中的php文件,如果修改它,php仍然加载相同的内容。
更多信息:
Download the latest apc version and use:
With apc.stat = 0 the server loads the php files in cache, if you modify it, php still loads the same.
More info:
我刚刚遇到了这种情况,并且我没有找到任何其他答案中建议的解决方案。我正在使用各种自动加载器,包括 Composer 自动加载器和旧版本的 Zend Framework 自动加载器。
事实证明,该问题是由文件名和类名之间的轻微名称不匹配引起的。类名和文件名之间有一个字符不同 - 人们很容易错过这一差异,但几个自动加载器连续
包含
相同的文件,从而导致错误。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
include
d the same file, causing the error.