Ce face trait / use
Pentru că o clasă poate extinde o singură clasă, codul comun pentru clase fără legătură între ele se pune într-un trait. Scrii use NumeTrait; în interiorul clasei și metodele din trait devin metodele clasei.
Un trait nu poate fi instanțiat singur. O clasă poate folosi mai multe trait-uri: use A, B;. Funcția class_uses arată ce trait-uri folosește o clasă.
Exemple
Exemplul 1: Același cod în două clase
<?php
trait AreSlug
{
public function slug(): string
{
$text = strtolower(trim($this->titlu));
return preg_replace('/[^a-z0-9]+/', '-', $text);
}
}
class Articol
{
use AreSlug;
public function __construct(public string $titlu)
{
}
}
class Categorie
{
use AreSlug;
public function __construct(public string $titlu)
{
}
}
echo (new Articol("Cum instalezi PHP 8"))->slug() . "\n";
echo (new Categorie("Baze de date"))->slug();
Rezultat
cum-instalezi-php-8
baze-de-date
Exemplul 2: Trait cu proprietate și class_uses
<?php
trait Jurnal
{
private array $mesaje = [];
public function noteaza(string $mesaj): void
{
$this->mesaje[] = $mesaj;
}
public function jurnal(): array
{
return $this->mesaje;
}
}
class Comanda
{
use Jurnal;
}
$c = new Comanda();
$c->noteaza("Creată");
$c->noteaza("Plătită");
print_r($c->jurnal());
print_r(class_uses($c));
Rezultat
Array
(
[0] => Creată
[1] => Plătită
)
Array
(
[Jurnal] => Jurnal
)
Greșeli frecvente
- Confunzi
usedin clasă (care adaugă un trait) cuusede la începutul fișierului (care importă un nume dintr-unnamespace). Sunt lucruri diferite. - Două trait-uri au o metodă cu același nume. PHP dă eroare fatală până rezolvi conflictul cu
insteadof:use A, B { A::salut insteadof B; }.
Comenzi înrudite
class / new / $this: Definește o clasă: un șablon pentru obiecte care au date (proprietăți) și funcții proprii (metode).extends / parent::: Creează o clasă nouă pornind de la una existentă (moștenire). Clasa copil primește tot ce are părintele.interface / implements: O interfață este o listă de metode pe care o clasă promite să le aibă. Clasa le scrie cu implements.