"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Por que não é possível atribuir chamadas de função padrão em PHP?

Por que não é possível atribuir chamadas de função padrão em PHP?

Publicado em 2024-11-06
Navegar:485

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

Não é possível chamar funções em padrões de atributos PHP

[Problema]

Apesar de ter experiência anterior em programação, um novato em PHP fica perplexo com um erro padrão de atributo. O código:

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

gera um erro de sintaxe. No entanto, o seguinte funciona perfeitamente:

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

Surge a pergunta: por que funções não podem ser invocadas em atributos padrão? Isso é intencional ou uma falha na implementação?

[Resposta]

O código do compilador PHP indica que esta restrição é intencional, embora nenhuma justificativa oficial esteja disponível. A implementação confiável desta funcionalidade apresenta certos desafios, conforme evidenciado pelas limitações na implementação atual do PHP.

A gramática do compilador define uma declaração de variável de classe como:

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

Portanto, para atribuir valores de variáveis ​​como $path, o valor esperado deve estar alinhado com um escalar estático. Isso abrange matrizes com valores que também são escalares estáticos:

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

Se a gramática permitisse a seguinte sintaxe, que se alinha com o exemplo de código, o script encontraria um erro de "Tipo de ligação inválido":

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

A análise do exemplo de código fornecido revela as seguintes etapas:

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

Se o opcode não for esperado (por exemplo, relacionado a funções ou métodos), um erro será gerado.

Permitindo matrizes não estáticas gera um opcode INIT_ARRAY, que interrompe zend_do_early_binding():

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

Para acomodar chamadas de função em padrões de atributos, seria necessária uma nova matriz de opcode com escopo definido para a declaração da variável de classe, semelhante às definições de método. No entanto, determinar o momento de tal avaliação apresenta desafios adicionais.

Outras linguagens dinâmicas conseguiram resolver isso, mas continua sendo um recurso ausente no PHP, potencialmente devido à sua complexidade e baixa prioridade percebida.

Declaração de lançamento Este artigo foi reimpresso em: 1729168219 Se houver alguma violação, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3