我试图通过返回基于class_exists来保护重新声明的类。这在Wordpress中创建插件时很常见,因为可能有多个插件使用相同的类。使用以下简单示例:
您可以在Youtube上http://www.youtube.com/watch?v=llVTvh6ffmw
查看此内容以下链接演示了问题和根本原因http://www.youtube.com/watch?v=VcNLoDvRLDc
的index.php
<?php
include_once('debug1.php');
include_once('debug2.php');
$test = new SomeClass();
echo $test->someVar;
debug1.php &amp; debug2.php 是重复文件......
<?php
if(class_exists('SomeClass')) return;
class SomeClass {
var $someVar = "test";
}
尽管有一个返回声明,我们仍然会收到致命错误“无法重新声明课程”。
旁注:奇怪的是80%的时间这个代码通过在debug2中添加/删除空格来工作 - 通过工作我的意思是它运行一次然后它就会中断。
我正在运行PHP 5.4.4版。
所以我的问题是。这是预期的行为吗?如果是的话,我错过了什么。如果不是,就像我在一些Wordpress插件中看到的那样令人担忧。
请注意:我每次使用其他包装都可以使用它,但这是更多的代码......:
<?php
if(class_exists('SomeClass')) return;
else {
class SomeClass {
var $someVar = "test";
}
}
答案 0 :(得分:2)
我可以确认这与xcache编译/安装代码的方式有所不同。 默认情况下,PHP在编译期间安装类,然后删除类代码,以便在执行时不再安装它。这被称为早期绑定。在此过程中,第二个类的安装将失败,因为“类存在”并且代码将保持完整无法执行。
执行完毕后,PHP将按照与称为后期绑定的代码相同的顺序安装任何剩余的类。在执行期间未达到的任何类(例如在debug2中)都未安装,因此不会导致错误。这提供了一定程度的灵活性,允许不良实践,例如在声明类之前实例化类。或者在这种情况下避免重复包括通过检查课程是否存在而不是更加努力地使用您的包含或通过使用自动加载使您的生活更轻松。
虽然PHP允许这种做法xcache已经确认它们只执行早期绑定,这反过来会强制类重新声明错误。 (见:http://xcache.lighttpd.net/ticket/314)
由于xcache在实时环境中被大量使用,我建议不要使用不带else的return语句。但是,正如Jon所说,自动加载是要走的路,或者在else语句中包装类。
此视频显示了xcache和PHP之间的不一致:http://www.youtube.com/watch?v=VcNLoDvRLDc
P.S。 Jon的答案是关于PHP如何解析页面的问题,但是我已经创建了这个更详细的答案,因为xcache也对结果有影响。
答案 1 :(得分:0)
类结构可以在文档中的任何位置定义,然后在别处使用。这就是为什么你可以在页面末尾声明类,并在开头使用它们的原因。这不是建议的做法,但确实有效。这是由于PHP如何解析页面。如果将类声明包装在if/else
语句中,则在满足条件(或之前未满足)之前不会执行它 - 因此您可以否定尝试重新声明现有类的错误。