[Problema]
A pesar de tener experiencia previa en programación, un novato en PHP está perplejo por un error de atributo predeterminado. El código:
class Foo {
public $path = array(
realpath(".")
);
}
produce un error de sintaxis. Sin embargo, lo siguiente funciona perfectamente:
$path = array(
realpath(".")
);
Surge la pregunta: ¿por qué no se pueden invocar funciones en los valores predeterminados de los atributos? ¿Es esto intencional o una falla en la implementación?
[Respuesta]
El código del compilador PHP indica que esta restricción es intencional, aunque no hay ninguna justificación oficial disponible. La implementación confiable de esta funcionalidad plantea ciertos desafíos, como lo demuestran las limitaciones en la implementación actual de PHP.
La gramática del compilador define una declaración de variable de clase como:
class_variable_declaration: //... | T_VARIABLE '=' static_scalar //... ;
Por lo tanto, para asignar valores de variables como $path, el valor esperado debe alinearse con un escalar estático. Esto abarca matrices con valores que también son escalares estáticos:
static_scalar: /* compile-time evaluated scalars */ //... | T_ARRAY '(' static_array_pair_list ')' // ... //... ;
Si la gramática permitiera la siguiente sintaxis, que se alinea con el ejemplo de código, el script encontraría un error de "Tipo de enlace no válido":
class_variable_declaration: //... | T_VARIABLE '=' T_ARRAY '(' array_pair_list ')' // ... ;
El análisis del ejemplo de código proporcionado revela los siguientes pasos:
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
Si el código de operación no es el esperado (por ejemplo, relacionado con funciones o métodos), se genera un error.
Permitir matrices no estáticas genera un código de operación INIT_ARRAY, que interrumpe zend_do_early_binding():
DECLARE_CLASS 'Foo' SEND_VAL '.' DO_FCALL 'realpath' INIT_ARRAY
Para acomodar las llamadas a funciones en los valores predeterminados de los atributos, se necesitaría una nueva matriz de código de operación con alcance para la declaración de la variable de clase, similar a las definiciones de métodos. Sin embargo, determinar el momento de dicha evaluación presenta desafíos adicionales.
Otros lenguajes dinámicos han logrado resolver este problema, pero sigue siendo una característica ausente en PHP, potencialmente debido a su complejidad y su percepción de baja prioridad.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3