Metode magice __get, __set, __call, __toString

In Programarea Orientata pe Obiecte (OOP) din PHP exista cateva metode mai speciale, care incep cu "__" (doua caractere '_'), precum __construct(). Acestea sunt numite generic Metode Magice (Magic Methods) si se executa automat in situatii mai speciale, cum ar fi de exemplu __get() pentru accesari de proprietati inexistente.
In aceasta lectie sunt prezentate cateva din cele mai folosite astfel de metode: __get(), __set(), __call() si __toString().
- Toate aceste metode magice trebuie sa fie definite cu atribut public.

1. Metode __get si __set

Metodele magice: __get() si __set() se folosesc de obicei impreuna si sunt create pentru lucru cu proprietati care nu sunt definite.

Iata un exemplu din care se intelege mai bine rolul lor. O clasa in care sunt folosite aceste metode, se creaza o instanta de obiect la ea apoi e accesata o proprietate inexistenta.
<?php
// Definire clasa AClas
class AClas {
  // Proprietate care va retine valori atribuite unor proprietati nedeclarate
  public $prop = array();

  // Metoda magica __get() (pt. accesari proprietati nedefinite)
  public function __get($name) {
    // Daca exista element cu cheia '$name' in $prop, afiseaza valoarea lui
    // Altfel, mesaj ca proprietatea nu exista
    if(array_key_exists($name, $this->prop)) echo $this->prop[$name]. '<br />';
    else echo 'Proprietatea <b>'. $name. '</b> nu exista.<br />';
  }

  // Metoda magica __set() (pt. cand se atribuie valori unor proprietati nedefinite)
  public function __set($name, $value) {
    // Adauga in $prop element cu cheia $name si valoarea value
    $this->prop[$name] = $value;
    echo 'Proprietatea <b>'. $name. '</b> nu exista. S-a atribuit valoarea <i>'. $value. "</i> la proprietatea: <b>prop['$name']</b><br />";
  }
}

// Creare instanta de obiect la clasa AClas
$obj = new AClas();

// Apelare proprietate neexistenta
$obj->noprop;           // Va determina executia metodei __get()

// Atribuire valoare la proprietate inexistenta
$obj->noprop = 'Valoare pt. noprop - PHP OOP';           // Va determina executia metodei __set()

// Apelare din nou a aceleiasi proprietati neexistente
$obj->noprop;           // Va determina executia metodei __get()

// Se verifica direct si elementul pe care-l creaza __set()
echo 'Verificare: '. $obj->prop['noprop'];
?>
- $prop e definita ca tip Array ca sa stocheze, prin metoda __set(), valorile atribuite unor proprietati nedefinite.
- Cand prin instanta de obiect la clasa e accesata o proprietate care nu exista ($obj->noprop;), se executa automat metoda __get(). Aici e definita sa verifice in $prop daca are element cu cheia $name (numele proprietatii accesate), daca exista acel element, afiseaza valoarea lui, altfel, afiseaza un mesaj.
- Cand se atribuie o valoare la proprietatea nedefinita ($obj->noprop = '...';), se executa automat metoda __set(). Aici e definita sa adauge in $prop un element cu numele proprietatii (cheie) si valoarea transmisa.
Vedeti si explicatiile din cod.
- Acest script va afisa urmatorul rezultat:
Proprietatea noprop nu exista.
Proprietatea noprop nu exista. S-a atribuit valoarea Valoare pt. noprop - PHP OOP la proprietatea: prop['noprop']
Valoare pt. noprop - PHP OOP
Verificare: Valoare pt. noprop - PHP OOP

2. Metoda __call

Metoda magica __call() e creata pentru cazuri cand sunt apelate metode inexistente. Sintaxa ei este:
                __call($nume, $array_argumente)
- $nume reprezinta numele metodei apelate
- in $array_argumente sunt retinute intr-un Array argumentele adaugate la apelarea metodei.


In urmatorul exemplu e definita o astfel de metoda "__call()" care afiseaza un mesaj cu numele metodei inexistente care a fost apelata si argumentele transmise.
<?php
// Definire clasa AClas
class AClas {
  // Metoda magica __call() (pt. apelari metode nedefinite)
  public function __call($name, $args) {
    // Afiseaza un mesaj cu numele metodei apelate si argumentele transmise
    echo 'Metoda <b>'. $name. '</b> nu exista. Argumente: <i>'. implode(', ', $args). '</i>';
  }
}

// Creare instanta de obiect la clasa AClas
$obj = new AClas();

// Apelare metoda inexistenta
$obj->site('cursuri', 'tutoriale');           // Va determina executia metodei __call()
?>
- In browser va afisa:
Metoda site nu exista. Argumente: cursuri, tutoriale

Incepand cu PHP 3.0 e adaugata o metoda similara, __callStatic(), aceasta se executa automat cand e apelata o metoda statica nedeclarata, prin formula:   NumeClasa::metodaStatica()

3. Metoda __toString

Cu metoda __toString() se determina modul de reactie a clasei cand instanta de obiect la ea este folosita ca o variabila de tip sir (String), de exemplu cu "echo".


In urmatorul exemplu e definita o clasa cu o metoda __construct() si una "__toString()" care afiseaza valoarea unei proprietati "mesaj".
<?php
// Definire clasa AClas
class AClas {
  private $mesaj;       // Proprietate

  // Metoda Constructor
  public function __construct($mesaj) {
    // Atribuie valoarea din parametru la proprietatea "mesaj"
    $this->mesaj = $mesaj;
  }

  // Metoda magica __toString()
  public function __toString() {
    return $this->mesaj;        // Returneaza valoarea proprietatii "mesaj"
  }
}

// Creare instanta de obiect la clasa AClas
$obj = new AClas('Fii bine primit');

// Apelare instanta, ca pe o variabila de tip String
echo $obj;           // Va determina executia metodei __toString()
?>
- In browser va afisa:
Fii bine primit
- Fara metoda __toString() adaugata in clasa, accesarea instantei de obiect simpla, cu "echo" sau "print" genereaza o eroare de genul:
Catchable fatal error: Object of class AClas could not be converted to string in ...

• Mai sunt si alte metode magice, mai putin folosite, cum ar fi: __isset (se apeleaza cand e verificata cu "isset()" o proprietate inexistenta), __invoke (se executa cand instanta de obiect e apelata ca o functie), si altele; le puteti gasi la pagina oficiala PHP.net Metode Magice
PHP OOP - Clase ... <<-- Anterior --- Urmator -->> OOP - Clase abstract ...

Un Test simplu in fiecare zi

HTML
CSS
JavaScript
PHP-MySQL
Engleza
Spaniola
Ce tag adauga imagine in pagina web?
<div> <img> <span>
<img src="http://coursesweb.net/imgs/webcourses.gif" width="191" height="63" alt="Courses-Web" />
Care din aceste coduri CSS afiseaza textul inclinat?
font-style: italic; text-decoration: underline; font-weight: 500;
#id {
  font-style: italic;
}
Clic pe functia jQuery care ascunde animat un element HTML.
click() hide() show()
$(document).ready(function() {
  $(".a_class").click(function(){ $(this).hide("slow"); });
});
Clic pe functia definita corect in PHP.
fname function() {} function fname() {} function $fname() {};
function fname($a, $b) {
  echo $a * $b;
}
Indicati forma pentru Prezent Perfect Continuu a verbului "to walk" (a merge).
have walked have been walking be walking
I have been walking for 5 hours.
- Merg pe jos de 5 ore.
Indicati Trecutul Nedefinit pentru verbul "ser" (a fi) la forma Yo.
será sería fui
Yo fui entrenador.
- Am fost antrenor.
Metode magice __get, __set, __call, __toString - Tutoriale PHP