Bug #40875 [Com]: Circular require_once causes fatal error
Edit report at https://bugs.php.net/bug.php?id=40875&edit=1
ID: 40875
Comment by: lemsan dot inc at gmail dot com
Reported by: epotocko at gmail dot com
Summary: Circular require_once causes fatal error
Status: Not a bug
Type: Bug
Package: Compile Failure
Operating System: Windows XP Pro
PHP Version: 5.2.1
Block user comment: N
Private report: N
New Comment:
Hi,
Actually something doesn't agree in the logic path in the case "extends ClassA" is
removed in ClassB.php. The code is working in this case, though following the logic you described,
it should fail.
Previous Comments:
------------------------------------------------------------------------
[2015-07-07 15:45:03] lemsan dot inc at gmail dot com
Hi,
Actually something doesn't agree in the logic path in the case "extends ClassA" is
removed in ClassB.php. The code is working in this case, though following the logic you described,
it should fail.
------------------------------------------------------------------------
[2007-03-21 05:53:21] cellog@php.net
Unfortunately, this is expected behavior.
Here is the logic path:
test.php => require_once classB.php
classB.php required yet? no
classB.php => require_once classA.php
classA.php required yet? no
classA.php => declare class A
classB.php => require_once classD.php
classD.php required yet? no
classD.php => require_once classC.php
classC.php required yet? no
classC.php => require_once classB.php
classB.php required yet? YES, SKIP
classC extends ClassB => fatal error, classB doesn't exist.
There is a way around this, and it is to re-design your classes so
they don't have such a complex relationship, or to re-order your
require_once statements. PHP can't be changed, as the parse order
always requires parsing included files first in order to grab
dependencies (parent classes), and so these are processed before the
class declaration is even parsed. Otherwise the simplest example of
having two classes in separate files would fail.
For instance, if you were to place
require_once 'ClassD.php' after the classB declaration:
<?php
require_once 'ClassA.php';
class ClassB extends ClassA {}
require_once 'ClassD.php';
?>
your code sample will work. Incidentally, PEAR makes use of this
exact technique in order to handle complex inter-relationships.
PEAR/Config.php has require_once statements at the end of the file
after PEAR_Config class is created.
not a PHP bug => bogus.
------------------------------------------------------------------------
[2007-03-21 00:47:51] epotocko at gmail dot com
I can also reproduce this in Linux with PHP 5.1.6
------------------------------------------------------------------------
[2007-03-21 00:46:46] epotocko at gmail dot com
Description:
------------
A circular reference between three files is causing a fatal error.
The simplest example I could reproduce this with is:
B extends A
C extends B
B uses D
D uses C
If class B is modified so that it does not extend class A, the error does not occur.
Reproduce code:
---------------
ClassA.php:
<?php
class ClassA {}
?>
ClassB.php:
<?php
require_once('ClassA.php');
require_once('ClassD.php');
class ClassB extends ClassA {}
?>
ClassC.php
<?php
require_once('ClassB.php');
class ClassC extends ClassB {}
?>
ClassD.php
<?php
require_once('ClassC.php');
class ClassD {}
?>
test.php
<?php
require_once('ClassB.php');
?>
Expected result:
----------------
If you execute test.php no errors should occur.
Actual result:
--------------
PHP Fatal error: Class 'ClassB' not found in ClassC.php on line 3
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=40875&edit=1
Thread (5 messages)