php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80000 Child classes not exist if defined before parent class
Submitted: 2020-08-20 05:47 UTC Modified: 2020-08-20 09:09 UTC
From: ASchmidt at Anamera dot net Assigned:
Status: Open Package: Class/Object related
PHP Version: 7.4.9 OS: Windows x64 IIS
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2020-08-20 05:47 UTC] ASchmidt at Anamera dot net
Description:
------------
Produced with a fresh PHP 7.4.9 instance, empty PHP.ini, and a fresh web site. 

Child classes that are defined BEFORE the parent class can be referenced by code prior to the class definitions if running PHP 7.3.21 - but it will FAIL as non-existing in 7.4.9.

I've been struggling with various warnings/errors in WordPress and other code that imply invalid class/method references, and was finally able to extract the attached reproducable sample.



Test script:
---------------
<?php
declare(strict_types=1);

var_dump( class_exists( 'MySubclass1' ), class_exists( 'MySubclass2' ), class_exists( 'MyAbstract' )  );	// PHP 7.4.9 = FALSE, true, true (PHP 7.3.21 = TRUE, true, true)

class MySubclass1 extends MyAbstract{}
abstract class MyAbstract{}
class MySubclass2 extends MyAbstract{}

var_dump( class_exists( 'MySubclass1' ), class_exists( 'MySubclass2' ), class_exists( 'MyAbstract' )  );	// true, true, true
    
// Produced with empty php.ini !

Expected result:
----------------
If a child class is defined before or after the parent class should yield consistent results, whether the child class is referenced earlier or later in the code - as it was in 7.3.

IF it is NOT permitted to define "MySubclass1" before the parent class, then this should lead to an error at the point the definition is encountered. ACCEPTING the definition as valid but then producing chance errors depending solely on where the child class is referenced seems arbitrary when working in large projects.

Actual result:
--------------
Depending on whether the child class was defined before or after the parent, and whether that child class happens to be referenced before or after its definition, will yield different outcomes (exist / not exist)

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-08-20 05:52 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2020-08-20 05:52 UTC] requinix@php.net
Doesn't look like anything's changed recently. https://3v4l.org/bIF1m

MySubclass1 can't be defined early because it depends on MyAbstract which isn't available yet. MySubclass2 doesn't have that problem.
 [2020-08-20 07:04 UTC] ASchmidt at Anamera dot net
-Status: Feedback +Status: Open
 [2020-08-20 07:04 UTC] ASchmidt at Anamera dot net
Thank you! I followed your lead and found out - it's being "masked" by OpCache!

IF OpCache is running (in my production 7.3.21), then the output is "true/true/true" - but I had been turning off extensions in 7.4.9 to track down nyriad other errors - which then exposed the reported behavior, further adding to the confusion.

I now understand that this was NOT due to a recent change. However, I now feel even stronger that this is far from being handled "transparently", given all the various factors interacting to create ambiguity.

If a child class only works "sometimes" -- when all the stars align correctly, then I feel this should be rejected outright at the place where the child class is defined. If the only consistent "working" pattern requires the child class to FOLLOW the parent class, then PHP should enforce that sequence and not permit child classes before parent classes.
 [2020-08-20 09:09 UTC] cmb@php.net
This is documented[1] behavior:

| Unless autoloading is used, then classes must be defined before
| they are used. If a class extends another, then the parent class
| must be declared before the child class structure.

The fact that the engine is more permissible in certain cases, is
nothing code should rely upon; if you define multiple classes in
the same file, put them in the proper order.  On the other hand,
we cannot change the current behavior in stable release branches,
for BC reasons.

We *may* error on potentially unsupported class order in PHP 8,
but I see no particular point in doing so.

[1] <https://www.php.net/manual/en/language.oop5.inheritance.php>
 [2020-09-01 19:01 UTC] huynhat dot niit at gmail dot com
The following pull request has been associated:

Patch Name: Ignore externally managed and generated files
On GitHub:  https://github.com/php/web-windows/pull/21
Patch:      https://github.com/php/web-windows/pull/21.patch
 [2020-09-01 19:03 UTC] fgfgfgfgfg at gmail dot com
there are even behavior differences with or without opcache loaded which is a bad sign given that PHP is not bash where a script is read line-by-line while it runs and beware god you change something and press save
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Jan 19 09:01:23 2021 UTC