You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
static $var = xxx should support any expression #8959
https://3v4l.org/G1EiN - this works, static $var can hold an object, only the initial value declaration needs longer code
<?php
class Cl {
public function scalar(): void
{
static $counter = 0;
$counter++;
var_dump($counter);
}
public function obj(): void
{
static $counter = new class() {
public int $n = 0;
};
$counter->n++;
var_dump($counter->n);
}
}
$o = new Cl();
$o->scalar();
$o->scalar();
$o->obj();
$o->obj();
$o = new class() extends Cl {};
$o->scalar();
$o->obj();
Currently php emits fatal error for static $var = new class() {};.
But static $var = ...; should support any expression like if the assign op would not be prefixed with static as such prefix only defines the statement should be evaluated only once per php request lifecycle & the variable kept alive.
It seems like some historical php limitation...
Instead of a fatal error, I expect this result for the test case above:
The use of a dynamic or non-string class name or an anonymous class is not allowed.
See the "Order of evaluation" section to get some insight why supporting arbitrary expressions might not be a good idea, or at the very least needs careful consideration.
Thank you for pointing to the RFC. It seems the RFC actually claims it will be allowed :), citing:
New expressions are allowed in parameter default values, attribute arguments, static variable initializers and global class constant initializers.
It seems you meant "new expressions in (static and non-static) property initializers and class constant initializers". But this issue is about "static variable initializers".
The "Order of evaluation" section clearly discuss when "static variable initializers" will be evaluated:
Static variable initializers are evaluated when control flow reaches the static variable declaration.
So I belive this does not require a new RFC and could be maybe even considered as a bug.
I see. The issue is not that a new is unsupported in static variable initializers, but only "new anonymous class" is unsupported.
In the RFC there is one example:
function test(
$b = new class {}, // anonymous class
) {}
What is the reason behind this decision? Unclear order of evaluation when using a reflection?
For static $var = ... (in code, not as property) the order of evaluation is defined by:
Static variable initializers are evaluated when control flow reaches the static variable declaration.
so the usecase from this issue description should be supported and probably no RFC should be required, IMHO there is no ambiguity, as it is more or less syntactic sugar to https://3v4l.org/G1EiN.
Making static support arbitrary expressions should be fine -- this should largely be an implementation problem, as the current initialization approach will not work.
I expect the largest complication would be the existence of ReflectionFunction::getStaticVariables(), because static variables with arbitrary (context-dependent) initializers cannot be evaluated in isolation. The semantics of the reflection method would likely have to change towards only returning those static variables that have already been dynamically reached.
Activity
cmb69 commentedon Jul 9, 2022
No. That has been explicitly excluded from the "new in initializers" RFC:
See the "Order of evaluation" section to get some insight why supporting arbitrary expressions might not be a good idea, or at the very least needs careful consideration.
mvorisek commentedon Jul 9, 2022
Thank you for pointing to the RFC. It seems the RFC actually claims it will be allowed :), citing:
It seems you meant "new expressions in (static and non-static) property initializers and class constant initializers". But this issue is about "static variable initializers".
The "Order of evaluation" section clearly discuss when "static variable initializers" will be evaluated:
So I belive this does not require a new RFC and could be maybe even considered as a bug.
cmb69 commentedon Jul 9, 2022
mvorisek commentedon Jul 9, 2022
I see. The issue is not that a
newis unsupported in static variable initializers, but only "new anonymous class" is unsupported.In the RFC there is one example:
What is the reason behind this decision? Unclear order of evaluation when using a reflection?
For
static $var = ...(in code, not as property) the order of evaluation is defined by:so the usecase from this issue description should be supported and probably no RFC should be required, IMHO there is no ambiguity, as it is more or less syntactic sugar to https://3v4l.org/G1EiN.
nikic commentedon Jul 24, 2022
Making
staticsupport arbitrary expressions should be fine -- this should largely be an implementation problem, as the current initialization approach will not work.I expect the largest complication would be the existence of
ReflectionFunction::getStaticVariables(), because static variables with arbitrary (context-dependent) initializers cannot be evaluated in isolation. The semantics of the reflection method would likely have to change towards only returning those static variables that have already been dynamically reached.github-actions commentedon Oct 23, 2022
There has not been any recent activity in this feature request. It will automatically be closed in 14 days if no further action is taken. Please see https://github.com/probot/stale#is-closing-stale-issues-really-a-good-idea to understand why we auto-close stale feature requests.
mvorisek commentedon Nov 10, 2022
dear stale bot, it will be fixed by #9301 :)
ndossche commentedon Jul 6, 2023
This wasn't closed automatically because of the manual merging. I'll close it now.