PHP7: Classi anonime

PHP7 Classi Anonime

Oltre alle funzioni, con PHP7 possiamo definire delle classi anonime. In questo ultimo appuntamento della serie, vediamo come farlo e quali sono le potenzialità ed i rischi di questo approccio.

Esempio: implementazione di un Logger

Partiamo subito con un esempio utile, perché spesso usato nel debug di un’applicazione. La situazione è questa: abbiamo una classe che richiede un’istanza di un’interfaccia Logger. Qualcosa non funziona e vogliamo circostanziare il problema: se è nel logger è un conto, se è nella classe un altro. Andiamo intanto a definire le nostre entità di base: una classe Application ed un’interfaccia Logger.

<?php

interface Logger {
  public function log($message);
}

class Application {
  protected $logger;

  public function setLogger(Logger $logger) {
    $this->logger = $logger;
    return $this;
  }

  public function run() {
    $this->logger->log('doing things');
  }
}

Ora, come ci comportiamo con PHP5?

Esempio con PHP5

L’unica strada che abbiamo in PHP5 è creare una nuova classe ed instanziarla al momento opportuno. Possiamo infatti fare solo questo:

class DebugLogger implements Logger {
  public function log($message) {
    var_dump($message);
  }
}

$app = new Application;
$app->setLogger(new DebugLogger);
$app->run();

Metti anche questo blocco di codice nello stesso file in cui hai creato l’interfaccia Logger e la classe Application ed eseguilo. L’output è il seguente:

string(12) "doing things"

Se l’applicazione è più strutturata, con buone probabilità devi creare un nuovo file per mettere la classe DebugLogger che ti serve solo provvisoriamente. Una perdita di tempo.

Esempio con PHP7

Con PHP7 le cose sono più semplici. Invece di creare una vera e propria classe per il nostro DebugLogger possiamo infatti creare una classe anonima.

$app = new Application;
$app->setLogger(new class {
  public function log($message) {
    var_dump($message);
  }
});
$app->run();

Come puoi vedere, è necessario meno codice e, come dicevo prima, se lavori con un’applicazione strutturata in un certo modo non hai la necessità di creare un nuovo file. Se però esegui questo codice, vedi un errore. Perché?

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Application::setLogger() must implement interface Logger, instance of class@anonymous given

Naturalmente la classe anonima non implementa l’interfaccia Logger, che invece è richiesta da Application::setLogger(). Il bello delle classi anonime è che si possono definire esattamente come classi normali. Possono infatti implementare interfacce, estendere altre classi, ecc. Sistema quindi il codice per risolvere l’errore e avrai il seguente snippet.

$app = new Application;
$app->setLogger(new class implements Logger {
  public function log($message) {
    var_dump($message);
  }
});
$app->run();

Ora l’output è proprio come quello nell’esempio che usa PHP5:

string(12) "doing things"

Attenzione!

Non abusare delle classi anonime. Usale solo quando sei sicuro di ciò che fai. Sono comode per mockare oggetti, per il debug, nei test di unità, ma in altri contesti potrebbero dare più problemi che benefici. Usa questa caratteristica con la testa!

Conclusioni

Con questa puntata diciamo addio alla rubrica dedicata alle novità portate da PHP7. Se non li hai ancora letti, di seguito trovi i link agli altri tutorial della serie. Non smettere di seguirci! Ti aspettano molti altri tutorial e informazioni sullo sviluppo in PHP, Laravel, WordPress e molto altro!

Non perderti i nostri tutorial!
Iscriverti per ricevere gratuitamente i nostri tutorial via e-mail.

Mattia Migliorini

Full Stack Web Developer e Consulente di Digital Marketing con formazione specifica in ambito e-commerce. Ama tenersi al passo con le tecnologie più recenti per offrire soluzioni sempre più semplici e potenti. È sempre pronto a mettere in discussione le proprie posizioni per ricercare nuove strategie creative.

Potrebbero interessarti anche...

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *