0

我试图通过基于 if class_exists 的返回来保护重新声明的类。这在 Wordpress 中创建插件时很常见,因为可能有多个插件使用相同的类。使用以下简单示例:

您可以在 Youtube 上查看此内容:http://www.youtube.com/watch?v=llVTvh6ffmw

以下链接演示了问题和根本原因http://www.youtube.com/watch?v=VcNLoDvRLDc

索引.php

<?php
include_once('debug1.php');
include_once('debug2.php');

$test = new SomeClass();
echo $test->someVar;

debug1.php & debug2.php是重复文件...

<?php
if(class_exists('SomeClass')) return;
class SomeClass {
    var $someVar = "test";
}

尽管有一个返回语句,我们仍然得到一个致命错误“无法重新声明类”。

附带说明:奇怪的是,该代码有 80% 的时间是通过简单地在 debug2 中添加/删除空格来工作的——我的意思是它运行一次然后就中断了。

我正在运行 PHP 版本 5.4.4。

所以我的问题是。这是预期的行为吗?如果是,我错过了什么。如果不是,我在一些 Wordpress 插件中看到了这一点,这令人担忧。

请注意:我可以让它每次都使用 else 包装,但这是更多代码......:

<?php
if(class_exists('SomeClass')) return;
else {
    class SomeClass {
        var $someVar = "test";
    }
}
4

2 回答 2

2

我可以确认这与 xcache 编译/安装代码的方式不同。默认情况下,PHP 在编译期间安装类,然后删除类代码,以便在执行时不会再次安装它。这称为早期绑定。在此过程中,第二个类的安装将失败,因为“类存在”并且代码将保持不变以供执行。

执行后,PHP 将再次按照与代码相同的顺序安装任何剩余的类,这被称为后期绑定。任何在执行期间未到达的类(例如在 debug2 中)都不会安装,因此不会导致错误。这提供了一定程度的灵活性,允许不良做法,例如在声明类之前对其进行实例化。或者在这种情况下,通过检查类是否存在来避免重复包含,而不是更加勤奋地处理包含或使用自动加载使您的生活更轻松。

虽然 PHP 允许这种做法,但 xcache 已经确认它们只执行早期绑定,这反过来会强制类重新声明错误。(见:http: //xcache.lighttpd.net/ticket/314

由于 xcache 在实时环境中被大量使用,我建议不要使用没有 else 的 return 语句。但是,正如乔恩所说,自动加载是要走的路,或者将类包装在 else 语句中。

该视频显示了 xcache 和 PHP 之间的不一致:http ://www.youtube.com/watch?v=VcNLoDvRLDc

PS Jon 的回答关于 PHP 如何解析页面是正确的,但是我已经创建了这个更详细的答案,因为 xcache 也会对结果产生影响。

于 2013-07-12T00:55:58.483 回答
0

类结构可以在文档中的任何地方定义,然后在其他地方使用。这就是为什么您可以在页面末尾声明类并在开头使用它们的原因。这不是建议的做法,但确实有效。这是由于 PHP 解析页面的方式。如果将类声明包装在if/else语句中,则在满足条件(或未满足之前的条件)之前不会执行它 - 因此您否定了尝试重新声明现有类的错误。

于 2013-07-11T21:04:54.303 回答