PHP 8.0.24 Released!

Sintaxe de Callable de Primeira Classe

A sintaxe de callable de primeira classe é introduzida a partir do PHP 8.1.0, como uma maneira de criar funções anônimas a partir de callable. Ela substitui a sintaxe de callable existente usando strings e arrays. A vantagem dessa sintaxe é que ela é acessível à análise estática, e usa o escopo no ponto onde o callable é adquirido.

A sintaxe ExprCallable(...) é usada para criar um objeto Closure a partir de callable. ExprCallable aceita qualquer expressão que possa ser diretamente chamada na gramática do PHP:

Exemplo #1 Sintaxe de callable de primeira classe simples

<?php

class Foo {
   public function 
metodo() {}
   public static function 
metodoestatico() {}
   public function 
__invoke() {}
}

$obj = new Foo();
$strClasse 'Foo';
$strMetodo 'metodo';
$strMetodoestatico 'metodoestatico';


$f1 strlen(...);
$f2 $obj(...);  // objeto invocável
$f3 $obj->metodo(...);
$f4 $obj->$strMetodo(...);
$f5 Foo::metodoestatico(...);
$f6 $strClasse::$strMetodoestatico(...);

// Callable tradicional usando string, array
$f7 'strlen'(...);
$f8 = [$obj'metodo'](...);
$f9 = [Foo::class, 'metodoestatico'](...);
?>

Nota:

As ... são parte da sintáxe, e não uma omissão.

ExprCallable tem a mesma semântica que Closure::fromCallable(). Isto é, That is, ao contrário de callable usando string e array, ExprCallable(...) respeita o escopo no ponto onde ela é criada:

Exemplo #2 Comparação de escopo de ExprCallable(...) e callable tradicional

<?php

class Foo {
    public function 
obterMetodoPrivado() {
        return [
$this'metodoPrivado'];
    }

    private function 
metodoPrivado() {
        echo 
__METHOD__"\n";
    }
}

$foo = new Foo;
$metodoPrivado $foo->obterMetodoPrivado();
$metodoPrivado();
// Fatal error: Call to private method Foo::metodoPrivado() from global scope
// Isso acontece porque a chamada é realizada fora de Foo e a visibilidade será verificada a partir desse ponto.

class Foo1 {
    public function 
obterMetodoPrivado() {
        
// Usa o escopo onde o callable é adquirido.
        
return $this->metodoPrivado(...); // Idêntico a Closure::fromCallable([$this, 'metodoPrivado']);
    
}

    private function 
metodoPrivado() {
        echo 
__METHOD__"\n";
    }
}

$foo1 = new Foo1;
$metodoPrivado $foo1->obterMetodoPrivado();
$metodoPrivado();  // Foo1::metodoPrivado
?>

Nota:

Criação de objetos por essa sintaxe (por exemplo new Foo(...)) não é suportada, porque a sintaxe new Foo() não é considerada uma chamada.

Nota:

A sintaxe de callable de primeira classe não pode ser combinada com o operador nullsafe. Ambos os resultados a seguir reultam em um erro de tempo de compilação:

<?php
$obj
?->metodo(...);
$obj?->prop->metodo(...);
?>

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top