【问题标题】:PHP with APC: Fatal errors: Cannot redeclare class带有 APC 的 PHP:致命错误:无法重新声明类
【发布时间】:2011-06-02 07:10:47
【问题描述】:

由于我使用 PECL 为 PHP 安装了 APC,因此有时会出现以下错误:Cannot redeclare class xxx

xxx 不时更改。我可以禁用 APC,但 APC 可以极大地提高性能!是否有已知的错误或者我可以做其他事情来防止这些错误?我正在使用带有 PHP 5.2.4 的 Ubuntu 8.04 LTS。


编辑/更新(来自 cmets):

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

【问题讨论】:

  • 阅读整个错误信息。不要两次包含上述文件。使用include_once。否则,将所有定义包装在 if (!class_defined("xxx")) {
  • 除了只使用 include_once 之外,尝试重新构建应用程序以使用类自动加载,以便 PHP 仅在需要时包含文件。还要坚持常识性的事情,例如每个文件一个类等。
  • 你说的xxx是什么意思? xxx 真的是你要加载的类吗?
  • 我使用 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
  • 您运行的是什么版本的 APC?

标签: apc php


【解决方案1】:

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

因此,如果您先执行 include_once myclass.php,然后在子目录中执行 include_once ../myclass.php,则 apc 可能会将其混合起来,并认为其不同的文件并加载两次。

不过,这在以后的版本中已修复。

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

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

【讨论】:

  • 问题依旧。升级您的 apc 版本和/或 zend 框架,或者您必须修补您的 zend 框架,在 zend 问题跟踪器上有可用的解决方案,或者您可以在应用程序中捕获异常。
【解决方案2】:

嗯,好像是common issue

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

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

否则,请尝试过多的 xdebug-ing。如果无法访问您的设置,我们只能在这里猜测。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      以下配置的组合为我修复了它:

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

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

      【讨论】:

      • 不幸的是,这三个对我不起作用(APC 3.1.13 和 PHP 5.4.24 CentOS 6.5)。对于 WordPress,它声称正在重新声明 Walker_Page 类,即使该文件绝对不会被多次调用。我会深入挖掘,看看能找到什么。
      • 抱歉 Jason,这适用于一些旧版本的 APC 和 PHP。我确定我当时使用的 PHP 版本不超过 5.3。*
      【解决方案5】:

      cron 下运行的 php 脚本中使用 Amazon 的 AWS SDK for PHP2 时发生此错误。一种解决方案是通过-d apc.enabled=0 禁用apc,如下所示:

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

      对于more info

      【讨论】:

        【解决方案6】:

        下载latest apc版本并使用:

        [APC]
        apc.cache_by_default = 0
        

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

        更多信息:

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            猜你喜欢
            • 2010-10-17
            • 2014-11-07
            • 2013-07-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-22
            • 1970-01-01
            相关资源
            最近更新 更多