PHP

Classes anônimas no PHP 7

Por em

Clases anônimas? É isso mesmo! Mais um recurso do PHP7 que você irá conferir aqui na School of Net. Vamos lá!

Uma classe anônima em suma, é uma classe que não possui nome, porém tem as mesmas funcionalidades de uma classe nomeada. Veja o exemplo abaixo:

<?php

var_dump(new class() {}); // object(class@anonymous)

Percebam que temos um objeto, que é uma classe anônima, mas vamos aprofundar um pouco mais, vamos para um outro exemplo:

<?php

new class() {
    public function __construct()
    {
        echo 'my construct of anonymous class';
    }
};

No exemplo acima, nós criamos uma classe anônima e também sobrescrevemos o seu método construtor para imprimir um texto.

Mas quando utilizo este recurso?

  • Quando uma classe não precisa ser documentada;
  • Quando uma classe será usada uma vez durante a execução;

Vamos para um exemplo mais prático e aplicado a vida real. Vamos supor que possuímos uma classe App com o método setLogger($logger) que irá receber uma instância de um objeto e chamar o método log() dentro de si. Anteriormente ao PHP 7, seria necessário declarar uma classe para instância-la e passa-la como parâmetro na chamada ao método setLogger($logger), porém, com o PHP 7 isso pode ser feito de uma forma mais “clean”. Abaixo demonstrarei como isso era feito antes do PHP 7 e como podemos fazer com o PHP 7.

<?php
// before PHP 7
class MyLog
{
    public function log($msg)
    {
        print_r($msg . "\n");
    }
}

class App
{
    public function setLogger($logger)
    {
        $logger->log('My log here...');
    }
}

$app = new App();
$app->setLogger(new MyLog());
<?php
// after PHP 7
class App
{
    public function setLogger($logger)
    {
        $logger->log('My log here...');
    }
}

$app = new App();
$app->setLogger(new class {
    public function log($msg)
    {
        print_r($msg . "\n");
    }
});

Percebam que em uma situação similar a essa do exemplo, não é necessário declarar uma classe nomeada para passar como parâmetro para a função setLogger($logger), basta eu chamar o método, e como parâmetro eu passar uma classe anônima com o método log($msg) e seu comportamento.

Mas podemos ir ainda mais além, pois como dito no inicio, classes anônimas possuem as mesmas funcionalidades de uma classe nomeada, ou seja, podemos passar argumentos através de seus métodos construtores, estender outras classes, implementar interfaces e usar traits. Incrível!

Vamos evoluir nosso exemplo, vejam abaixo:

<?php

interface LogInterface
{
    public function log(string $msg);
}

class App
{
    public function setLogger(LogInterface $logger)
    {
        $logger->log('My log here...');
    }
}

$app = new App();
$app->setLogger(new class implements LogInterface {
    public function log(string $msg)
    {
        print_r($msg . "\n");
    }
});

Adicionamos ao nosso exemplo, a interface LogInterface que está sendo implementada pela nossa classe anônima, e foi declarada como tipo de parâmetro no método setLogger(LogInterface $logger).

Além de implementar uma interface, vamos também extender uma classe qualquer, vejam abaixo:

<?php

interface LogInterface
{
    public function log(string $msg);
}

class AbstractLog
{
    protected $sufix = 'LOG: ';
}

class App
{
    public function setLogger(LogInterface $logger)
    {
        $logger->log('My log here...');
    }
}

$app = new App();
$app->setLogger(new class extends AbstractLog implements LogInterface {
    public function log(string $msg)
    {
        print_r($this->sufix . $msg . "\n");
    }
});

Muito bom! Agora estamos estendendo a classe AbstractLog e utilizando uma propriedade dela.

Percebam que o uso de classes anônimas é muito útil e torna mais fácil e elegante algumas implementações.

Agora lembre-se, tome muito cuidado para não ficar utilizando tal recursos inconsequentemente, pois na maioria das vezes, as classes precisam sim ser nomeadas para reaproveitamento.

Estamos chegando ao fim do artigo, espero que tenham gostado.

Um forte abraço e até a próxima!