Re: Should there be a `get_declared_enums()` function ?

From: Date: Sat, 17 Aug 2024 05:36:26 +0000
Subject: Re: Should there be a `get_declared_enums()` function ?
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to internals+get-125023@lists.php.net to get a copy of this message
Hi Mike,
There is one problem I can see with this approach though: since PHP 7.4, the return value of get_declared_classes() (and friends) does not guarantee any particular order anymore [2]. So, an array_slice($symbols, $n) may not get you the _latest_ classes loaded, so I think this would only work if the order of classes is guaranteed in some way.
That is a super relevant insight and one I was actually not aware of. Do you happen to know if it was triggered by an explicit RFC to that effect, or if it resulted because of a side-effect of some other implementation change? I honestly don't know, but if I look through the PHP 7.4 RFC list, I have a niggling suspicion it may have something to do with the Preloading RFC [1] ? I may very well be wrong though.
From my perspective, that is definitely a BC break and one that I am surprised I never noticed before? Do you also know if it is a case of "not guaranteed, but in-fact actual fact it always works that way, or not?"
Well, for the autoloader I previously linked to [2], it was a problematic change which we did have to work around, see [3] and [4] for details of the issues we saw (parent class vs child class order reversals, issues when multiple classes were declared in one file). I haven't deep-dived into the order change, other than to validate the reported issues and proposed fixes.
What if instead PHP were to implement an optional 2nd callback parameter to include() / require() / include_once() / require_once() to allow us to capture the symbols loaded and their paths? The callback function could return void and accept an array of $symbols with the following guaranteed minimum structure? $symbols = array(
    'classes' => [],
    'interfaces' => [],
    'traits' => [],
    'enums' => [],
);
Except include() and friends aren't function calls, but language constructs/expressions and don't take parameters as such, so I don't see how that would be possible without changing include() and friends to function calls (along the lines of what happened for exit in PHP 8.4 with non-parenthesized use still possible to mitigate the otherwise huge breaking change), or alternatively, introducing wrapper functions for the language constructs - so no change to the existing functionality, but new functions with a signature along the lines of include_and_get_symbols( $path ): array with the return value being the symbols loaded from $path.
This approach would be a less disruptive than my prior suggestion
Not so sure about that considering the above ;-)
What do you think if this alternate approach?
This probably needs some more bike shedding ;-) Smile, Juliette 1: https://wiki.php.net/rfc/preload 2: https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/6fbbc1078094d905f0773421f13830744a144d1e/autoload.php#L153-L247 3: https://github.com/squizlabs/PHP_CodeSniffer/pull/3130 4: https://github.com/squizlabs/PHP_CodeSniffer/issues/3145

« previous php.internals (#125023) next »