"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Why Can\'t Attribute Defaults Function Calls in PHP?

Why Can\'t Attribute Defaults Function Calls in PHP?

Published on 2024-11-06
Browse:309

Why Can\'t Attribute Defaults Function Calls in PHP?

Can't Call Functions in PHP Attribute Defaults

[Problem]

Despite having previous programming experience, a novice in PHP is perplexed by an attribute default error. The code:

class Foo {
    public $path = array(
        realpath(".")
    );
}

yields a syntax error. However, the following works seamlessly:

$path = array(
    realpath(".")
);

The question arises: why can't functions be invoked in attribute defaults? Is this intentional or a flaw in implementation?

[Answer]

The PHP compiler code indicates this restriction is intentional, although no official rationale is available. Implementing this functionality reliably poses certain challenges, as evidenced by limitations in PHP's current implementation.

The compiler's grammar defines a class variable declaration as:

class_variable_declaration:
      //...
      | T_VARIABLE '=' static_scalar //...
;

Therefore, to assign variable values like $path, the expected value must align with a static scalar. This encompasses arrays with values that are also static scalars:

static_scalar: /* compile-time evaluated scalars */
      //...
      | T_ARRAY '(' static_array_pair_list ')' // ...
      //...
;

If the grammar allowed the following syntax, which aligns with the code sample, the script would encounter a "Invalid binding type" error:

class_variable_declaration:
      //...
      | T_VARIABLE '=' T_ARRAY '(' array_pair_list ')' // ...
;

Parsing the given code sample reveals the following steps:

zend_do_begin_class_declaration() // Adds an opcode
array_init(), zend_do_add_static_array_element() // Do not create new opcodes, add array to class properties
zend_do_declare_property() // Declares the property
zend_do_early_binding() // Consumes the last opcode and evaluates it

If the opcode is not expected (e.g., related to functions or methods), an error is thrown.

Allowing non-static arrays generates an INIT_ARRAY opcode, which disrupts zend_do_early_binding():

DECLARE_CLASS   'Foo'
SEND_VAL        '.'
DO_FCALL        'realpath'
INIT_ARRAY

To accommodate function calls in attribute defaults, a new opcode array scoped to the class variable declaration would be needed, similar to method definitions. However, determining the timing of such evaluation presents additional challenges.

Other dynamic languages have managed to resolve this, but it remains a feature absent in PHP, potentially due to its complexity and perceived low priority.

Release Statement This article is reprinted at: 1729168219 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3