代码之家  ›  专栏  ›  技术社区  ›  pinkgothic sudip

php自动加载:在所有星座中防止“cannot redeclare<class>”?

  •  10
  • pinkgothic sudip  · 技术社区  · 14 年前

    问题

    有什么方法可以做PHP吗 忽视 重新声明类而不是死记硬背一个致命错误?或者至少抛出一个异常? (我可以很容易地捕捉到它并继续(以及记录尝试的自动加载)。

    我猜不,致命的错误是致命的错误——毕竟,在一百个案例中,有九十九个是合理的明智行为——而且我可能只需要逐个修正触发的案例。但也许比我聪明的人已经知道了。


    如果你问自己 你到底为什么要这么做? “继续读下去。

    背景

    我正在研究一种使用 反射 聚合有关已用函数和类的特定信息。脚本的参数之一是一个可选的引导文件 反射 自动加载更可靠(更少 ReflectionExceptions 因为类在特定的文件中是未知的,所以最终会捕获并触发一个回退启发式方法。

    现在,引导程序可以很好地加载自动加载程序,脚本按预期运行,无需抱怨就可以移动数百个文件,直到遇到障碍:

    PHP致命错误:无法重新声明类 phpunit框架约束 /usr/share/php/phpunit/framework/constraint.php 在线62

    我有两个问题:

    第一,我不知道是什么触发了这个。我已经调整了所使用的引导程序,但只能在“无法重新声明”和“无法打开文件”之间进行切换,具体取决于使用的include路径。没有中间地带,即没有发生错误的地方。不过,我还在调查。(不过,这个问题不是关于什么的。)

    第二,更重要的是,引出这个问题的主题, 我需要一种方法来抓住它 . 我试过编写一个自定义错误处理程序,但它似乎不想用于 Fatal error S(有点理智,有人可能会争辩)。

    我打算在某个时候将这个工具发布到开源世界中,这让我觉得这是一个相当不可接受的行为。对于不存在的类,我有一个后备启发式方法——我宁愿它们被声明为一次太少,而不是一次太频繁,但是没有 结束 -使用启发式方法,也就是说,我想提供使用引导程序的能力。 不会破坏脚本。曾经。 即使它是自动装弹机历史上最差的自动装弹机。

    (强调: 我不想帮助我的自动装弹机。这不是问题所在。 )

    3 回复  |  直到 12 年前
        1
  •  8
  •   Kenny Linsky    12 年前

    避免的最佳选择之一 Cannot redeclare class_exists 功能。您可以在自动加载程序中使用它来防止类重新声明。用 类存在 你不必抓住错误,只要防止它。

    实际上有两种致命错误:可捕获错误和不可捕获错误。类重新声明不会触发 E_RECOVERABLE_ERROR (一个容易上手的)而且你不能处理它。

    所以,你的问题的答案是:“你不能。”

        2
  •  3
  •   DudeOnRock    12 年前

    我不知道您是否仍然对答案感兴趣,但我在混合自动加载和反射时可能遇到了与您相同的问题。以下是我关于自动加载失败的假设:

    spl_autoload_register 区分使用完全指定的名称分隔的类标识符自动加载的类,以及使用不包含名称空间的类标识符从命名空间中加载的类。据我所知,这是一个错误。

    我的解决方案是:在创建反射类实例之前测试,如果类标识符是完全名称间隔的。如果不是,我不使用反射。由于您不介意某些类不加载,这可能也是解决您的问题的方法。

        3
  •  2
  •   Kendall Hopkins    14 年前

    自动加载永远不会自动尝试加载已经加载的类。如果您有同名的>1个类,您可能做错了。

    如果解析“不安全”代码,可能需要在加载类名之前搜索该文件,但这只能作为最后的手段,因为这是对CPU的巨大浪费,而且可能只是隐藏有效的错误。

    如果您有一个REQUEST结构和一个自动加载系统,那么您可能会在autoload中包含一个文件,然后在REQUEST中再次包含一个文件。你可以用包装的方法破解一个补丁 if( class_exists( <class_name_string> ) { ... <class declaration in here> ... }