带有 APC 的 PHP:致命错误:无法重新声明类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4575341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 13:31:48  来源:igfitidea点击:

PHP with APC: Fatal errors: Cannot redeclare class

apcphp

提问by Poru

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

由于我使用 PECL 为 PHP 安装了 APC,因此有时会出现以下错误: 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.

xxx 不时变化。我可以禁用 APC,但 APC 提高了性能!是否存在已知错误,或者我可以采取其他措施来防止这些错误吗?我使用 Ubuntu 8.04 LTS 和 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

我使用 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

回答by Peter

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 withall three I seem to no longer get the error :)!

如果没有全部 3 个,我会不断收到错误,但是有了这三个,我似乎不再收到错误 :)!

回答by Coalpaw

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 = 0cleared 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).

启用 APC 后,我在一堆 PHP 库中遇到了同样的问题。经过大量的头发拉扯后,我发现设置apc.include_once_override = 0清除了一切。仍在监控但没有再次出现问题(在此之前我能够通过清除 apc 缓存来诱发错误)。

回答by Fred Lovine

This error happened when using Amazon's AWS SDKfor PHP2in a php script running under cron. One solution was to disable apcvia -d apc.enabled=0as shown below:

在 .php 下运行的 php 脚本中使用亚马逊的AWS SDKfor时会发生此错误。一种解决方案是禁用via ,如下所示:PHP2cronapc-d apc.enabled=0

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

For more info.

欲了解更多信息

回答by mario

Hmmm, seems to be a common issue:

嗯,似乎是一个常见的问题

What I just noticed from your specific error message is that you wrote zend_db_adapter_abstractin 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_onceinternally, maybe with side-effects.

我刚刚从您的特定错误消息中注意到您zend_db_adapter_abstract用全小写字母编写。可怕的框架命名方案和自动加载器的一个问题是它们以混合大小写形式保存文件,并且期望如此。如果您的代码试图以这种方式实例化它,则自动加载器可能找不到它。APC 在这里可能更奇特,因为它在include_once内部覆盖,可能会产生副作用。

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.

一种解决方案是调整 Zend 自动加载器,并手动保存已加载类和(绝对和小写)文件名的列表,以代替 include_once 进行验证检查。

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

否则,尝试过度的 xdebug-ing。如果无法访问您的设置,我们所能做的就是在这里猜测。

回答by The Surrican

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

嗯,apc 的一个已知问题是它混淆了include_once从不同位置相对调用的指令。

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

所以如果你这样做include_once myclass.php,然后在一个子目录中做include_once ../myclass.phpapc 可能会混淆它并认为它的不同文件并加载它两次。

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_definedor some callable stuff.

如果您可以将代码深入到加载两次的类,则可以检查该类是否已加载class_defined或某些可调用的东西。

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

您还可以使用该apc.filter指令来完全防止某些文件被缓存。

回答by JoniJnm

Download the latest apcversion and use:

下载最新的apc版本并使用:

[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.

当 apc.stat = 0 时,服务器加载缓存中的 php 文件,如果你修改它,php 仍然加载相同的。

More info:

更多信息:

回答by ec2011

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.

我刚刚发生了这种情况,我没有在任何其他答案中找到建议的解决方案。我正在使用各种自动加载器,包括 Composer 自动加载器和旧版本的 Zend 框架自动加载器。

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.

问题原来是由文件名和类名之间的轻微名称不匹配引起的。类名和文件名之间有一个不同的字符 - 人类很容易错过的差异,但几个自动加载器连续included 同一个文件,导致错误。