ZF-7894: Installation of PHPUnit 3.4.0 makes the zf --help command exit with Fatal PHP errors

Description

After having installed the latest/new PHPUnit version 3.4.0 via Pear issuing the zf --help command exits with following PHP Fatal errors.

$ zf --help PHP Fatal error: Cannot redeclare class phpunit_framework_testsuite_dataprovider in /opt/local/lib/php/PHPUnit/Framework/TestSuite/DataProvider.php on line 65 PHP Stack trace: PHP 1. {main}() /opt/local/bin/zf.php:0 PHP 2. Zend_Tool_Framework_Client_Console::main() /opt/local/bin/zf.php:77 PHP 3. Zend_Tool_Framework_Client_Abstract->dispatch() /opt/local/lib/php/Zend/Tool/Framework/Client/Console.php:96 PHP 4. Zend_Tool_Framework_Client_Abstract->initialize() /opt/local/lib/php/Zend/Tool/Framework/Client/Abstract.php:209 PHP 5. Zend_Tool_Framework_Loader_Abstract->load() /opt/local/lib/php/Zend/Tool/Framework/Client/Abstract.php:118 PHP 6. include_once() /opt/local/lib/php/Zend/Tool/Framework/Loader/Abstract.php:90

Fatal error: Cannot redeclare class phpunit_framework_testsuite_dataprovider in /opt/local/lib/php/PHPUnit/Framework/TestSuite/DataProvider.php on line 65

Call Stack: 0.0005 643208 1. {main}() /opt/local/bin/zf.php:0 0.0071 1452848 2. Zend_Tool_Framework_Client_Console::main() /opt/local/bin/zf.php:77 0.0071 1454344 3. Zend_Tool_Framework_Client_Abstract->dispatch() /opt/local/lib/php/Zend/Tool/Framework/Client/Console.php:96 0.0071 1454344 4. Zend_Tool_Framework_Client_Abstract->initialize() /opt/local/lib/php/Zend/Tool/Framework/Client/Abstract.php:209 0.0102 1706760 5. Zend_Tool_Framework_Loader_Abstract->load() /opt/local/lib/php/Zend/Tool/Framework/Client/Abstract.php:118 0.3996 2317528 6. include_once('/opt/local/lib/php/PHPUnit/Framework/TestSuite/DataProvider.php') /opt/local/lib/php/Zend/Tool/Framework/Loader/Abstract.php:90

Comments

this just means that you have phpunit in your include path twice.

@ralph:

wouldn't it make sense to extend the include loader to block equal paths relative from the different include paths?


/path/a/
/path/b/

now:


/path/a/Foo/Bar/Baz.php

disallows the inclusion of another file:


/path/b/Foo/bar/Baz.php

The problem is that $filterAcceptFilePattern = '.*(?:Manifest|Provider).php$'; on line 60 in Zend_Tool_Framework_Loader_IncludePathLoader lets slip the /opt/local/lib/php/PHPUnit/Framework/TestSuite/DataProvider.php through, as it has Provider in the class file name, and therefore adds it twice to the list of classes to include. I temporarly fixed it by filtering out the one item that has PHPUnit/Framework in it (see attached patch 7894.diff).

@Ralphschindler I may have a possible fix for the symlink || file in include path twice problem.

How about the _getFiles() maintains an array of visited files in a reverse tree like schema relative to the include path:

Zend/OpenId/Provider.php would become


$visited = array(
    'Provider' => array('OpenId' => array('Zend')),
);

when adding a potential new hit one could then do:


$fileParts = explode(DIRECTORY_SEPARATOR, str_replace($currentIncludePath, "", $file));
$alreadyVisited = true;
$currentLeaf = $visited;
while(count($fileParts)) {
    $item = array_pop($fileParts);
    if(!isset($currentLeaf[$item]) || !is_array($currentLeaf[$item])) {
       $alreadyVisited = false;
       break;
    } elseif(!in_array($item, $currentLeaf)) {
        $alreadyVisited = false;
    }
    $currentLeaf = $currentLeaf[$item];
}
if($alreadyVisited == false) {
   // add to $visited
   // add to $files
}

Edit: Fixed the code

Just want to confirm that the patch provided by Raphael Stolt is working.

I had the same issue trying to run "zf show version"

Fixed in trunk and merged into 1.9 release branch, this hack will not be necessary for 1.10 anymore since the IncludePathLoader will be removed.

I set fix version