我得到一个奇怪的行为与PHPUnit,我不知道如果我做错了什么,或者如果它是一个bug从测试框架。以下是我的例子:
我的项目有几个类:BsInput, BsEmail, bshiden, BsNumber。BsEmail, bshiden和BsNumber扩展了BsInput。所有类都有单元测试类(bsinputttest用于BsInput, BsEmailTest用于BsEmail,等等)。
每个单独执行的单元测试都很好。
现在,如果我尝试在我的项目中运行所有测试,我得到一个错误和消息"PHP致命错误:不能在/some/path/to/b.p p上重新声明类B "。
每个文件的内容如下:
BsInput.php
require_once __DIR__ . "/BsInputControl.php";
class BsInput extends BsInputControl {
...
}
BsEmail.php
require_once __DIR__ . "/BsInput.php";
class BsEmail extends BsInput {
...
}
BsHidden.php
require_once __DIR__ . "/BsInput.php";
class BsHidden extends BsInput {
...
}
BsNumber.php
require_once __DIR__ . "/BsInput.php";
class BsNumber extends BsInput {
...
}
BsInputTest.php
require_once "../colibri/bs/BsInput.php";
class BsInputTest extends PHPUnit_Framework_TestCase {
...
}
BsEmailTest.php
require_once "../colibri/bs/BsEmail.php";
class BsEmailTest extends PHPUnit_Framework_TestCase {
...
}
BsHiddenTest.php
require_once "../colibri/bs/BsHidden.php";
class BsHiddenTest extends PHPUnit_Framework_TestCase {
...
}
BsNumberTest.php
require_once "../colibri/bs/BsNumber.php";
class BsNumberTest extends PHPUnit_Framework_TestCase {
...
}
最后一件让我抓狂的事:如果我注释掉BsHidden.php和BsHiddenTest.php中的所有代码,PHPUnit的所有测试在BsNumber和下面的类上执行得很顺利!
有人已经看到类似的东西了吗?有没有什么线索可以帮我解决这个问题?
我尝试了一个丑陋的解决方案:在BsInput.php
中插入以下代码var_dump(class_exists('BsInput', FALSE));
if (class_exists('BsInput', FALSE)) { return; }
我得到这个结果:
bool(true)
PHP Fatal error: Cannot redeclare class BsInput in /.../BsInput.php on line 87
到目前为止,我已经研究了很多问题,包括上面的问题,但到目前为止,我还没有找到任何解决方案。
- PHPUnit一次加载所有类。导致PHP致命错误:不能重新声明类
- PHPUnit Test Suite -不能重新声明类mock &具体类
- "致命错误:不能重新声明类"... 但是类没有被声明
我也尝试将PHPUnit更新到最新版本(4.6),但没有成功。
我的平台是:Mac OS X 10.10PHP 5.5.20PHPUnit) 4.6.6Netbeans 8.0.2
有线索吗?
在试图解决这个问题后,我终于删除了我的BsHidden.php
文件,附加的测试文件并完全重新创建了它们(我的意思是与我复制/粘贴的内容完全相同)…现在它成功了!这让我想到了PHP和PHPUnit之间的某个bug。
然而,一个快速&肮脏的解决方案似乎是:
- 复制粘贴文件和单元测试文件内容到另一个文件
- 删除有问题的文件和单元测试文件(如果有)
- 重新创建文件和单元测试文件并粘贴内容
我终于确定了我的问题。似乎有一个PHP错误,至少在我的平台上是这样。
PHP的手册说(http://php.net/manual/en/function.include-once.php) PHP4中的名称解析在不区分大小写的系统上是不区分大小写的,而PHP5处理这样的问题。
这是我在我的平台(Mac OS X 10.10, PHP 5.5)上得到的行为:
假设我有一个文件A.php
,定义了一个A
类和以下代码:
<?php
require_once 'A.php';
require_once 'a.php';
?>
第二个require_once
触发Can not redeclare class error
。所以在Mac OS X上的PHP5.5中,至少名称解析是不区分大小写的,但是PHP仍然认为它们是不同的文件。
如果你只是使用class_exists
,那么像这样使用它:
if (!class_exists('BsInput', FALSE)) {
class BsInput extends BsInputControl {
// ToDo
}
}
我不知道为什么会产生这个错误-你是否在 require_一次显式地使用 ?