On 24.07.2016 at 11:23, Thomas Mlynarczyk:
> Consider the following code:
>
> class C extends B {}
> class B extends A {}
> class A {}
>
> This will cause an error:
>
> Fatal error: Class 'B' not found in [...] on line 1
>
> However, when switching lines 2 and 3, the error goes away:
>
> [snip]
>
> […] I would have
> expected either A-B-C to be the *only* order that works, or *any* order
> to work (including, of course C-B-A). So what's going on here? […]
Interesting question! A debug session might be helpful to *surmise*
what's going on. At least in PHP 5.6 the compilation of a file ends
with a call to zend_do_end_compilation(), so set a breakpoint there.
Then view CG(class_table) (which is the class table of the compiler).
The original code shows the following relevant keys:
"\0c/vagrant/thomas.php0x7ffff7ff2019"
"\0b/vagrant/thomas.php0x7ffff7ff202e"
"a\0"
Apparently, class C and B are marked as being somehow incomplete. Note
that the order of the entries correlates to the definition of the
classes. That makes sense, as the (1-pass) compiler can't know the
details of the superclasses, which are defined only later.
Compare that to the relevant keys after having switched line 2 and 3:
"\0c/vagrant/thomas.php0x7ffff7ff2019"
"a\0"
"b\0"
Appears to be consistent.
Later on the executor tries to look up class B (`extends B`) what will
succeed in the second case, but fails in the first one, and so the error
is thrown.
It seems to me that the PHP manual (<
http://php.net/extends>) is not
completely correct wrt. the implementation, but the fact that the second
script is accepted might be regarded as implementation detail (an
implementation which is currently slightly less restricting).
For me, this answer seems rather unsatisfactory, but I don't know
better, and there's not much documentation about the Zend engine, and
what is there seems to be pretty much scattered, unfortunately.
--
Christoph M. Becker