|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-06-07 19:02 UTC] aschmidt at anamera dot net
Description:
------------
If a class extends a parent class from an include/require, then the subclass cannot be referenced until AFTER the class definition.
However, if a class extends a parent class from the SAME script, then the subclass CAN be referenced anywhere in the code.
I can't tell at what point this broke, but this appears to have worked in earlier 7.2 releases.
Test script:
---------------
<?php
declare(strict_types=1);
require( 'bug2.php' );
// Error: mySubClass2 does NOT exist!
var_dump( class_exists( 'myClass1', FALSE ), class_exists( 'mySubClass1', FALSE ), class_exists( 'myParentClass', FALSE ), class_exists( 'mySubClass2', FALSE ) );
class myClass1 {
const myConst = 'C1';
}
class mySubClass1 extends myClass1 {
const myConst = 'S1';
}
class mySubClass2 extends myParentClass {
const myConst = 'S2';
}
// Correct: Now mySubClass2 DOES exist!
var_dump( class_exists( 'myClass1', FALSE ), class_exists( 'mySubClass1', FALSE ), class_exists( 'myParentClass', FALSE ), class_exists( 'mySubClass2', FALSE ) );
Content of file "bug2.php":
<?php
declare(strict_types=1);
class myParentClass {
const myConst = 'Parent';
}
Expected result:
----------------
subclass_bug.php:7:boolean true
subclass_bug.php:7:boolean true
subclass_bug.php:7:boolean true
subclass_bug.php:7:boolean true
Actual result:
--------------
subclass_bug.php:7:boolean true
subclass_bug.php:7:boolean true
subclass_bug.php:7:boolean true
subclass_bug.php:7:boolean false
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 09:00:02 2025 UTC |
The VLD output[1] hints at what's happening. The point is that PHP first compiles a file, and runs it afterwards. When it compiles the main script, myClass1 and mySubClass1 are fully defined, and so can be linked. However, mySubClass2 cannot be linked, because myParentClass is not yet known. Then the main script is run, starting with including the file where myParentClass is defined; then the script proceeds to the first var_dump() where mySubClass2 is still not defined, because it is only linked afterwards (see the ADD_INTERFACE opcode). For the second var_dump(), all classes are defined. Well, bug or not a bug? Let's say wont-fix. That is just how PHP works. The best *general* advice to never face these kinds of issues is to never mix declarations and execution logic[2]. And then rely on autoloading, to avoid loading classes you don't need. > With OPcache running, the entire script appears not be parsed > unless I remove the "return;". I presume you're hitting OPcache's optimizer's dead code elimination here. The code after the `return` is never supposed to be executed, so isn't even compiled (practically). I think you can deactivate DCE with opcache.optimization_level=0x7FFE9FFF [1] <https://3v4l.org/GnDr2/vld#output> [2] <https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md#23-side-effects>