Skip to content

static $var = xxx should support any expression #8959

Closed

Description

@mvorisek

Description

https://3v4l.org/gTufh

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:

int(1)
int(2)
int(1)
int(2)
int(3)
int(3)

Activity

  1. cmb69 commented on Jul 9, 2022

    @cmb69
    Member

    It seems like some historical php limitation...

    No. That has been explicitly excluded from the "new in initializers" RFC:

    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.

  2. mvorisek commented on Jul 9, 2022

    @mvorisek
    ContributorAuthor

    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.

  3. cmb69 commented on Jul 9, 2022

    @cmb69
    Member

    The use of a dynamic or non-string class name or an anonymous class is not allowed.

  4. mvorisek commented on Jul 9, 2022

    @mvorisek
    ContributorAuthor

    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.

  5. nikic commented on Jul 24, 2022

    @nikic
    Member

    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.

  6. github-actions commented on Oct 23, 2022

    @github-actions

    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.

  7. mvorisek commented on Nov 10, 2022

    @mvorisek
    ContributorAuthor

    dear stale bot, it will be fixed by #9301 :)

  8. ndossche commented on Jul 6, 2023

    @ndossche
    Member

    This wasn't closed automatically because of the manual merging. I'll close it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions