All tests fail with PHP Fatal error: class cannot be overridden
I am getting strange behavior with PHPUnit and I cannot figure out if I am doing something wrong or it is a bug in the test environment. Here's my case:
My project has several classes: BsInput, BsEmail, BsHidden, BsNumber. BsEmail, BsHidden, and BsNumber extend BsInput. All classes have unit test classes (BsInputTest for BsInput, BsEmailTest for BsEmail, etc.).
Each unit test done individually works great.
Now if I try to run all the tests in my project, I get the error "PHP Fatal error: cannot override class B in /some/path/to/B.php on line 80".
Here are the contents of each file:
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 {
...
}
Now, the last little thing that drives me crazy: if I comment out all the code in BsHidden.php and BsHiddenTest.php, PHPUnit All Tests execution is smooth across BsNumber and the following classes!
Has anyone seen something like this before? Any clues on what should I look at to solve my problem?
I've tried an ugly workaround: by pasting the following code into BsInput.php
var_dump(class_exists('BsInput', FALSE));
if (class_exists('BsInput', FALSE)) { return; }
And I get this result:
bool(true)
PHP Fatal error: Cannot redeclare class BsInput in /.../BsInput.php on line 87
I have looked at many problems so far, including the ones above, but until now I could not find any solution.
- PHPUnit loads all classes at the same time. Causes PHP fatal error: cannot override class
- PHPUnit Test Suite - cannot update Mocking and Concrete class classes
- "Fatal error: class cannot be overridden" ... but the class was not declared
I have also tried updating PHPUnit to the latest version (4.6) without any success.
My platform: Mac OS X 10.10 PHP 5.5.20 PHPUnit 4.6.6 Netbeans 8.0.2 (if that has something related)
Does anyone know anyone?
After trying to solve this problem, I permanently deleted my file BsHidden.php
, attached test file and recreated them exactly (I mean the same content that I copy / paste) ... And now it works! This really makes me think of an error somewhere between PHP and PHPUnit.
However, a quick and dirty workaround is similar:
- copy-paste file and contents of unit test file to another file
- delete problem file and unit test file if present)
- create file and unit test file and paste content
source to share
I finally figured out my problem. There seems to be a PHP bug, at least on my platform.
The PHP manual says ( http://php.net/manual/en/function.include-once.php ) that name resolution in PHP4 is case insensitive on case insensitive systems, while PHP5 handles such issues.
Here is the behavior I get on my platform (Mac OS X 10.10, PHP 5.5):
Assuming I have a file A.php
that defines the class A
and the following code:
<?php
require_once 'A.php';
require_once 'a.php';
?>
The second require_once
launches Can not redeclare class error
. So in PHP5.5 on Mac OS X name resolution is case insensitive, but PHP still thinks they are different files.
source to share