ZF-11421: CLONE - Fatal error: Class 'Zend_CodeGenerator_Php_Docblock_Tag' not found

Description


set_include_path('/path/to/library'); // current trunk
require_once "Zend/CodeGenerator/Php/Docblock/Tag.php";
$foo = new Zend_CodeGenerator_Php_Docblock_Tag();

Fatal error: Class 'Zend_CodeGenerator_Php_Docblock_Tag' not found in /path/to/library/Zend/CodeGenerator/Php/Docblock/Tag/Param.php on line 34

Comments

Clone of ZF-8739 as the issue has remained closed for a while now.

I was able to reproduce this in trunk by running this command:


[adam@zfdev trunk]$ php -r "set_include_path('/path/to/zf/library'); require_once 'Zend/CodeGenerator/Php/Docblock/Tag.php';"

Results in fatal error:


PHP Fatal error:  Class 'Zend_CodeGenerator_Php_Docblock_Tag' not found in /usr/local/apache2/htdocs/lib/zfdev/trunk/library/Zend/CodeGenerator/Php/Docblock/Tag/Param.php on line 35
PHP Stack trace:
PHP   1. {main}() Command line code:0
PHP   2. require_once() Command line code:1
PHP   3. require_once() /usr/local/apache2/htdocs/lib/zfdev/trunk/library/Zend/CodeGenerator/Php/Docblock/Tag.php:31

Zend/CodeGenerator/Php/Docblock/Tag.php require_once's Zend/CodeGenerator/Php/Docblock/Tag/Param.php, which in turn require_once's Zend/CodeGenerator/Php/Docblock/Tag.php. That second require_once of Zend/CodeGenerator/Php/Docblock/Tag.php isn't performed since the file is already included, but because it hasn't been fully processed by PHP yet the class Zend_CodeGenerator_Php_Docblock_Tag doesn't exist, so PHP throws a fatal error when trying to define class Zend_CodeGenerator_Php_Docblock_Tag_Param.

Fix suggested in original bug (ZF-8739) is to remove


require_once 'Zend/CodeGenerator/Php/Docblock/Tag/Param.php';
...
require_once 'Zend/CodeGenerator/Php/Docblock/Tag/Return.php';

from Zend_CodeGenerator_Php_Docblock_Tag.

Workaround is to manually require abstract class to modify include order:


set_include_path("/path/to/library");
require_once "Zend/CodeGenerator/Php/Abstract.php";
require_once "Zend/CodeGenerator/Php/Docblock/Tag.php"; // works

The question is why are _Param and _Return require_once'd into Zend/CodeGenerator/Php/Docblock/Tag.php?


/**
 * @see Zend_CodeGenerator_Php_Docblock_Tag_Param
 */
require_once 'Zend/CodeGenerator/Php/Docblock/Tag/Param.php';

/**
 * @see Zend_CodeGenerator_Php_Docblock_Tag_Return
 */
require_once 'Zend/CodeGenerator/Php/Docblock/Tag/Return.php';

Those classes are not directly referenced anywhere in the code of the class. If I remove those require_once statements, the errors go away:


[adam@zfdev trunk]$ phpsh
php> set_include_path('/home/webadmin/htdocs/lib/zfdev/trunk/library');
php> require_once 'Zend/CodeGenerator/Php/Docblock/Tag.php';
php> $o = new Zend_CodeGenerator_Php_Docblock_Tag();
php> var_dump(get_class($o));
string(35) "Zend_CodeGenerator_Php_Docblock_Tag"

And the unit test suite results are unchanged.

Is there any practical reason why those seemingly-unnecessary require_once statements can't be removed?

See my comment on the original bug; they were left over from before the class used the plugin loader for the factory.

That explanation works for me. I've updated the file in trunk to remove the require_once statements.

Fixed in trunk r24098 Merged to release-1.11 in r24099