【问题标题】:Cannot redefine class on 'require_once'无法在“require_once”上重新定义类
【发布时间】:2011-07-15 07:35:43
【问题描述】:

更新

我已经放弃了 CodeIgniter,并希望通过 PHP 围绕我的数据库应用程序构建一个 Web 界面,因为没有办法摆脱这个错误......


例外

我得到了这个例外:

Fatal error: require_once(): Cannot redeclare class doctrine\orm\abstractquery in Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php on line 190

Call Stack:
    0.0007     330016   1. {main}() Q:\Digest\index.php:0
    0.0058     330800   2. require_once('Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php') Q:\Digest\index.php:163
    0.2207     935856   3. call_user_func_array() Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php:297
    0.2207     935904   4. Crud->index() Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php:0
    0.2574    1065064   5. Crud->__getEntities() Q:\Digest\Application\controllers\crud.php:19
    0.2649    1121824   6. Doctrine\ORM\AbstractQuery->getResult() Q:\Digest\Application\controllers\crud.php:49
    0.2649    1121976   7. Doctrine\ORM\AbstractQuery->execute() Q:\Digest\lib\Doctrine\ORM\AbstractQuery.php:366
    0.2651    1121976   8. Doctrine\ORM\Query->_doExecute() Q:\Digest\lib\Doctrine\ORM\AbstractQuery.php:528
    0.2651    1121976   9. Doctrine\ORM\Query->_parse() Q:\Digest\lib\Doctrine\ORM\Query.php:223
    0.2848    1185896  10. Doctrine\ORM\Query\Parser->parse() Q:\Digest\lib\Doctrine\ORM\Query.php:203
    0.3089    1238704  11. Doctrine\ORM\Query\SqlWalker->getExecutor() Q:\Digest\lib\Doctrine\ORM\Query\Parser.php:311
    0.3090    1239104  12. Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
    0.3107    1241104  13. require_once('Q:\Digest\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php') Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
    0.3108    1241440  14. Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0

如上所示,我正在使用 Doctrine 2.0 和 Symfony UniversalClassLoader 来实现数据分析脚本。为了查看结果,我建立了一个 CodeIgniter 项目。

这就是我对这个例外感到困惑的地方:我已经消除了几乎所有合理的原因,但什么也没找到。如果我在这里的淘汰赛中做错了什么,请告诉我。

如果有人对这里可能出现的问题有任何线索,请提供帮助。如果您认为我遗漏了任何信息,也请告诉我。

谢谢。


消除重复声明

它告诉我我不能重新定义一个类。我已经 grepped 我的所有文件,并且这个类仅在其特定文件中定义“Doctrine/ORM/AbstractQuery.php”。

请注意,最初在 Symfony UniversalClassLoader.php 的第 190 行调用 require 时报告了错误,我已将其更改为 require_once 以确保文件不会加载两次。


消除区分大小写的文件系统

由于我发现 here 的注释,我认为我应该分享我在 Windows 7 上运行 PHP 5.3.5。这应该意味着下面描述的错误/功能是没有影响。

这种行为在 PHP 5 中改变了,所以 例如对于 Windows,路径是 首先归一化,使得 C:\PROGRA~1\A.php 实现相同 作为 C:\Program Files\a.php 和文件 仅包含一次。


消除require 重复

我现在已经将每个库(和我自己的代码)中的每个调用都替换为函数 requirerequire_once,并且错误仍然存​​在。这意味着我现在可以有把握地说,打电话给require 是不负责任的。我的问题仍然是:什么是?


调试器输出

运行调试器绝对不会给我带来任何好处:

    ...
    0.4658    1274904                       -> Doctrine\ORM\Query\SqlWalker->getExecutor() Q:\Digest\lib\Doctrine\ORM\Query\Parser.php:311
    0.4660    1275304                         -> Logger::autoload() Q:\Digest\lib\Log4PHP\Logger.php:0
    0.4662    1275304                         -> Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
    0.4663    1275384                           -> strripos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:183
    0.4665    1275400                           -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:185
    0.4666    1275488                           -> strpos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:187
    0.4667    1275520                           -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:188
    0.4668    1275672                           -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
    0.4669    1275696                           -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
    0.4671    1275656                           -> file_exists() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
    0.4700    1277304                           -> require_once(Q:\Digest\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php) Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:192
    0.4702    1277640                             -> Logger::autoload() Q:\Digest\lib\Log4PHP\Logger.php:0
    0.4703    1277640                             -> Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
    0.4704    1277720                               -> strripos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:183
    0.4706    1277736                               -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:185
    0.4707    1278280                               -> strpos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:187
    0.4708    1278312                               -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:188
    0.4709    1278464                               -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
    0.4711    1278488                               -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
    0.4712    1278448                               -> file_exists() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
    0.5259 zu
TRACE END   [2011-03-28 11:28:00]

一些额外的检查告诉我它在崩溃时加载的文件是lib\Doctrine\ORM\Query\Exec\AbstractSqlExecutor.php,或者AbstractSqlExecutor 类......因此,一些完全不相关的东西。

【问题讨论】:

  • 在其他地方还有另一个includerequire(没有_once)实例。
  • 你在 Windows 上吗?
  • @ircmaxell:是的,我在 Windows 上。您能否分享一下为什么这与此处相关?
  • @Pepijn 你可以试试require_once realpath($file);,以确保它是一致的。
  • 呃。顺便说一句:当类定义已知时,类加载器会继续包含/需要文件吗? 不是应该修复的错误吗?

标签: php symfony1 doctrine-orm fatal-error codeigniter-2


【解决方案1】:

如果您以多种方式包含UniveralClassLoader,例如:

  1. 通过require_once
  2. 使用Symfony\Component\ClassLoader\UniversalClassLoader;

那么致命错误可能是由编译器认为类的重新声明引起的。删除require_once 行(如果存在)并使用第二个选项。

【讨论】:

  • UniversalClassLoader的文件中抛出错误,被复制的组​​件是AbstractQuery。所以不行。这不是导致它的原因。
【解决方案2】:

请检查您的服务器是否安装了 APC。如果是,请尝试将其关闭,升级或将 apc.include_once_override 设置设置为 0。

【讨论】:

  • 谢谢;这并没有解决它,但至少这是一个新鲜的想法!我正在运行 apc(现在已禁用它以进行测试)但设置 apc.include_once_override 是默认设置(手册告诉我是“0”)。
【解决方案3】:

您可能在两个文件中定义了相同的类。 require_once() 在这种情况下无济于事

【讨论】:

  • 然而,grepping for "class abstractquery" 不区分大小写只会返回一个文件,正如您在我的问题中所读到的那样;案件仍在审理中。
【解决方案4】:

你在任何地方都使用 __autoload() 吗?这是我唯一能想到的,除非您实际上在两个不同的文件中定义了相同的类。

【讨论】:

    【解决方案5】:

    可惜你放弃了。解决它的简单方法是:

    if (!class_exists('ClassName')) {
    
    
    }
    

    围绕文件。这并不能修复错误,只会使症状消失。不幸的是,Codeigniter 在 PHP5 对象实例化方面不太聪明,可能会加载您的代码两次。

    【讨论】:

    • 你不是说if (! class_exists(...吗?
    • 这个。只是出于好奇,为什么是 CI 而不是 Kohana? Kohana 是一个 PHP5 框架的 CI 分支。
    • 为我工作!太棒了!
    【解决方案6】:

    我能想到的其他可能性(在略读到目前为止提出的答案之后)是:

    1. 也许在您的源代码树中某处存在符号链接? (如果路径看起来不同,我发现 require_once() 不够聪明,无法知道您正在导入同一个文件)。

    2. 也许在您的包含依赖项中存在一个循环? (如果 A 包含 B 包含 C 包含 A,我发现 require_once() 不够聪明,无法打破循环)。

    【讨论】:

    • 我接受这个答案是因为它可能是未来读者的最佳答案,而不是因为它有效。还是,谢谢?
    • 感谢您的认可。得知您无法找到问题,我深感遗憾,但感谢您的分享 - 您的经验会让我在使用 CodeIgniter 之前三思而后行。
    • 不要。这是一个很好的平台(我猜),我只是想强迫它与 Doctrine 和外部类加载器合作。
    • Mac 和 Windows 用户注意! 根文件系统默认格式化为不区分大小写。注意混合大小写的文件/目录名称,因此可能多次“需要”。还要注意重命名操作后__DIR____FILE__ 和 statcache 的使用和检索。由于 osx 的工作原理,将目录重命名为正确大小写的最安全方法是创建一个新目录并将所有内容移入其中(然后清除系统和 php stat 缓存)。
    【解决方案7】:
     root
      + a.php
      + c/
         +c.php
         + b.php
    

    _a.php _

    require_once 'c/b.php'; -> will work
    require_once 'c/c.php'; -> will work
    

    _ c/b.php _

    require_once 'c.php'; -> will work too 'c/c.php'!='c.php' :(
    

    【讨论】:

      【解决方案8】:

      如果您已经探索了所有明显的解决方案,那么每次我遇到这个问题时,它都是缓存问题,通常与 APC 相关。

      如果是 apc 缓存问题,要修复它,请将以下内容添加到文件顶部的顶级文件中:

      apc_clear_cache();
      

      如果问题消失了,那么您就知道这就是问题所在。特别是在共享主机环境中,如果文件发生变化,我发现 APC 几乎无法使用,所以我总是将其添加到我可以调用的顶级文件中。

      PS:我什至遇到过 APC 似乎缓存了错误文件的情况,因此当我包含一个显然从未包含它所抱怨的类的文件时它会崩溃。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        • 2012-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-22
        • 1970-01-01
        相关资源
        最近更新 更多