Klassenerweiterung per trait

Traits sind Codebausteine, mit denen man den Quellcode von Klassen erweitern kann. Es geht also nicht um Erweiterungen während der Laufzeit.

Beispiel eines Traits

<?php

trait FormatAusgabe
{
  protected $ergebnis = '';
  protected function Format()
  {
    return "*** ".$this->ergebnis." ***".PHP_EOL;
  }
}
...
Dieser Trait hat den Namen FormatAusgabe und enthält eine Klasseneigenschaft sowie eine Methode. Ein Trait ist selbst keine Klasse, eben nur ein Codebaustein.
Die Methode Format() im Trait kleidet einen Text in Sternchen und fügt ein Zeilenende an. Statt dieses einfachen Beispiels kann man sich eine sinnvollere und/oder komplexere Textformatierung vorstellen.

Anwendung des Traits

...

class DatumUndZeit
{
  use FormatAusgabe; # keine Klammern, 

  public function Datum()
  {
    $this->ergebnis = date('d.m.Y');
    print $this->Format();
  }
}

class Pythagoras
{
  use FormatAusgabe;

  protected $a,$b = 0;

  public function __construct($a, $b)
  {
    $this->a= $a;
    $this->b = $b;
  }

  public function Hypotenuse()
  {
    $this->ergebnis = sqrt( pow($this->a,2) + pow($this->b,2) );
    print $this->Format();
  }
}

$d = new DatumUndZeit();
$d->Datum(); // *** das aktuelle Datum ***

$p = new Pythagoras(4, 3);
$p->Hypotenuse(); // *** 5 ***

unset ($d);

?>
Hier gibt es zwei Klassen, die unabhängig voneinander sind, aber jede benötigt die gleiche Formatierung für die Ergebnisausgabe. Mithilfe des Schlüsselworts use kann jede Klasse den gleichen Trait, also den gleichen Codebaustein, bei sich einbauen.
Man kann ohne weiteres mehrere verschiedene Traits in eine Klasse einbauen, wobei man die Namen der Traits mit Komma getrennt hinter use auflistet.
Es gibt ein use()-Konstrukt bei anonymen Funktionen. Das hat dem use hier nichts zu tun.

Traits in der Praxis

Im Handbuch findet man vor allem viele Sonderfälle beim Verwenden von Traits, die man dort nachlesen kann, wen man sie wirklich mal braucht.
Die wichtigste Anwendung ist mit dem obigen Beispiel demonstriert: statt kleinere Codestücke, die man immer wieder in verschiedenen Klassen braucht, bindet man diese per Trait ein. Man erspart sich ein ständiges Neuschreiben oder Code-Kopieren.
Mitunter hat man selbstdefinierte Lieblings-Funktionen, die man vielleicht auch als Traits bereitstellen kann. Auch ein Set von Debug-Funktionen kann man sich so vorstellen.
Oder ein Projekt, dass mit einer modernen PHP-Version arbeitet, muss auf eine niedere Version downgradet werden. Per Trait könnte man Polyfills (Ersatzcode) bereitstellen, um fehlende oder anders funktionieren Features bereitzustellen. Traits gibt es seit Version 5.4.0. Noch tiefer downgraden wird natürlich schwierig...
Der Phantasie sollten keine Grenzen gesetzt sein.