Ce face __get / __set / __toString / __call / __invoke
Metodele magice nu se apelează direct: PHP le rulează singur. __toString() rulează când obiectul este folosit ca text (de exemplu cu echo). __invoke() rulează când obiectul este apelat ca o funcție: $obiect().
__get($nume) și __set($nume, $valoare) rulează când citești sau scrii o proprietate care nu există sau nu este accesibilă. __isset și __unset acoperă isset() și unset(). __call($nume, $argumente) rulează când apelezi o metodă inexistentă, iar __callStatic face același lucru pentru metode statice.
Alte metode magice: __construct, __destruct (la distrugerea obiectului), __clone, __serialize / __unserialize, __debugInfo (ce afișează var_dump).
Exemple
Exemplul 1: __toString și __invoke
<?php
class Bani
{
public function __construct(private float $suma)
{
}
public function __toString(): string
{
return number_format($this->suma, 2, ",", ".") . " lei";
}
}
class Tva
{
public function __invoke(float $pret): float
{
return $pret * 1.21;
}
}
echo new Bani(1299.5) . "\n";
$tva = new Tva();
echo $tva(100) . "\n";
print_r(array_map($tva, [10, 20]));
Rezultat
1.299,50 lei
121
Array
(
[0] => 12.1
[1] => 24.2
)
Exemplul 2: __get și __set pentru setări
<?php
class Setari
{
private array $date = ["tema" => "light"];
public function __get(string $nume): mixed
{
return $this->date[$nume] ?? "(nesetat)";
}
public function __set(string $nume, mixed $valoare): void
{
echo "Salvez $nume = $valoare\n";
$this->date[$nume] = $valoare;
}
public function __isset(string $nume): bool
{
return isset($this->date[$nume]);
}
}
$s = new Setari();
$s->limba = "ro";
echo $s->tema . ", " . $s->limba . ", " . $s->font . "\n";
var_dump(isset($s->font));
Rezultat
Salvez limba = ro
light, ro, (nesetat)
bool(false)
Exemplul 3: __call pentru metode generate
<?php
class Utilizator
{
private array $date = ["nume" => "Ana", "oras" => "Iași"];
public function __call(string $metoda, array $argumente): mixed
{
if (str_starts_with($metoda, "get")) {
$camp = strtolower(substr($metoda, 3));
return $this->date[$camp] ?? null;
}
throw new BadMethodCallException("Metoda $metoda nu există");
}
}
$u = new Utilizator();
echo $u->getNume() . " din " . $u->getOras() . "\n";
try {
$u->sterge();
} catch (BadMethodCallException $e) {
echo $e->getMessage();
}
Rezultat
Ana din Iași
Metoda sterge nu există
Greșeli frecvente
- Folosești
__getși__setpentru tot. Editorul nu mai poate sugera proprietățile, iar greșelile de scriere în nume trec neobservate. Folosește-le doar când chiar ai date dinamice. __toStringnu returnează text. Din PHP 8, metoda trebuie să returnezestring; altfel primeștiTypeError.
Comenzi înrudite
class / new / $this: Definește o clasă: un șablon pentru obiecte care au date (proprietăți) și funcții proprii (metode).__construct: Constructorul este metoda rulată automat la new. Pregătește obiectul cu datele de pornire.clone: Creează o copie a unui obiect. Fără clone, atribuirea unui obiect copiază doar referința către același obiect.method_exists: Verifică dacă o clasă sau un obiect are o metodă cu un anumit nume.