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.

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
+3


source to share


2 answers


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.

+3


source


You just use class_exists

, use it like this:

if (!class_exists('BsInput', FALSE)) { 
    class BsInput extends BsInputControl {
        // ToDo
    }
}

      



I don't know why this error is generated differently - are you using require_once everywhere explicitly?

0


source







All Articles