PHP POO Intermediário
Traits
Em PHP, uma trait é um mecanismo de reuso de código que permite compartilhar métodos entre classes sem herança. Diferente de interfaces, traits podem conter implementação concreta; diferente de classes abstratas, uma classe pode usar várias traits ao mesmo tempo. Isso resolve o problema da herança simples do PHP: você pode compor comportamentos de várias fontes.
A palavra-chave use importa uma trait para dentro de uma classe. Se duas traits trouxerem métodos com o mesmo nome, o PHP gera um erro fatal a menos que você resolva o conflito com insteadof (para escolher qual método usar) e as (para criar um alias). Traits também podem declarar métodos abstratos, obrigando a classe que as usa a implementá-los.
Use traits quando precisar compartilhar um conjunto coeso de métodos entre classes não relacionadas hierarquicamente. Evite usá-las como "colcha de retalhos": se o comportamento pertence a uma família de classes, prefira herança ou interfaces. Traits são ideais para funcionalidades transversais como logging, validação ou formatação.
Pontos-chave
use NomeDaTrait;dentro da classe importa todos os métodos da trait.- Conflitos de nomes entre traits são resolvidos com
insteadof(escolhe um) eas(cria alias). - Traits podem declarar métodos abstratos, forçando a classe a implementá-los.
- Uma classe pode usar múltiplas traits, contornando a herança simples do PHP.
- Prefira traits para comportamentos reutilizáveis e independentes de hierarquia.
<?php
// Trait com método concreto
trait Loggable {
public function log(string $msg): void {
echo "[LOG] $msg\n";
}
}
// Trait com método abstrato
trait Validatable {
abstract public function rules(): array;
public function validate(array $data): bool {
foreach ($this->rules() as $field => $rule) {
if ($rule === 'required' && empty($data[$field])) {
return false;
}
}
return true;
}
}
// Trait com método que conflita
trait JsonExport {
public function export(): string {
return json_encode(get_object_vars($this));
}
}
trait XmlExport {
public function export(): string {
return '<user>' . htmlspecialchars($this->name) . '</user>';
}
}
class User {
use Loggable, Validatable, JsonExport, XmlExport {
// Resolve conflito: usa export do JsonExport e cria alias do Xml
JsonExport::export insteadof XmlExport;
XmlExport::export as exportXml;
}
public function __construct(public string $name) {}
public function rules(): array {
return ['name' => 'required'];
}
}
$user = new User('Ana');
$user->log('Usuário criado');
echo $user->export() . "\n";
echo $user->exportXml() . "\n";
var_dump($user->validate(['name' => 'Ana']));
var_dump($user->validate(['name' => '']));