Skip to content

PHP 8.3: Arbitrary static variable initializers #1986

@afilina

Description

@afilina

Related to #1589

Analysis

Summary of existing PHP 8.2 behavior based on the RFC:

// Constant expressions can be assigned in this context (exact meaning in Syntax Variations below).
function foo1() {
    static $i = 1;
}

// Can redeclare, with the last taking precedence.
function foo2() {
    static $i = 1;
    static $i = 2;
}

// getStaticVariables() is able to get the literal value.
var_dump((new ReflectionFunction('foo2'))->getStaticVariables()['i']); // int(2)

Updated behavior in PHP 8.3:

// Allows arbitrary expressions (exact meaning in Syntax Variations below).
function foo1() {
    static $i = min(1, 2);
}

// Re-declaring is now a fatal error.
function foo2() {
    static $i = min(1, 2);
    static $i = max(1, 2); // Fatal error: Duplicate declaration of static variable $i
}

// getStaticVariables() can get the expression's value or null if not initialized. However, since the above syntax
// is a fatal error in PHP 8.2, there is no observable difference, so we don't need to sniff getStaticVariables().
var_dump((new ReflectionFunction('foo2'))->getStaticVariables()['i']); // int(2)

Everything in the "Other semantics" section of the RFC has no impact on what we need to sniff. Either the syntax exists or it doesn't.

  • Exceptions during initialization
  • Destructor
  • Recursion

Top 2000 Packages

Found quite a few usages in the top 2000 packages ("static $" in a function). See results.

Detection in PHP 8.2

  • function () { static $i; } Without assignment: valid.
  • function () { static $i = 1; } Constant expression: valid.
  • function () { static $a = 1; static $a = 2; } Duplicate declaration: valid
  • function () { static $i = min(1, 2); } Arbitrary expression: error

Detection in PHP 8.3

  • function () { static $i; } Without assignment: valid.
  • function () { static $i = 1; } Constant expression: valid.
  • function () { static $a = 1; static $a = 2; } Duplicate declaration: error
  • function () { static $i = min(1, 2); } Arbitrary expression: valid

Syntax Variations & Detectability

References

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