Sobes.tech
Middle

Ce metode magice există în PHP și cum sunt utilizate?

sobes.tech AI

Răspuns de la AI

Metodele magice în PHP sunt metode speciale care încep cu dublu underscore (de exemplu, __construct), care sunt apelate automat în anumite situații.

Principalele metode magice și utilizarea lor:

  • __construct(): Este apelată la crearea unui obiect al clasei. Folosită pentru inițializarea proprietăților obiectului și efectuarea acțiunilor inițiale.

    <?php
    class MyClass {
        public function __construct() {
            echo "Obiect creat!";
        }
    }
    $obj = new MyClass(); // Va afișa "Obiect creat!"
    
  • __destruct(): Este apelată la distrugerea obiectului (de exemplu, când scriptul se încheie sau obiectul este șters din memorie). Folosită pentru eliberarea resurselor (închiderea fișierelor, conexiunilor la baze de date).

    <?php
    class MyClass {
        public function __destruct() {
            echo "Obiect distrus!";
        }
    }
    $obj = new MyClass();
    unset($obj); // Va afișa "Obiect distrus!"
    
  • __call(string $name, array $arguments): Este apelată când se încearcă apelarea unei metode inaccesibile sau inexistente în contextul obiectului. $name conține numele metodei, iar $arguments este un array de argumente.

    <?php
    class MyClass {
        public function __call($name, $arguments) {
            echo "Metodă inaccesibilă '{$name}' apelată cu argumente: " . implode(', ', $arguments);
        }
    }
    $obj = new MyClass();
    $obj->nonExistentMethod('arg1', 'arg2'); // Va afișa "Metodă inaccesibilă 'nonExistentMethod' apelată cu argumente: arg1, arg2"
    
  • __callStatic(string $name, array $arguments): Este apelată când se încearcă apelarea unei metode statice inaccesibile sau inexistente în contextul clasei. Similar cu __call, dar pentru apeluri statice.

    <?php
    class MyClass {
        public static function __callStatic($name, $arguments) {
            echo "Metodă statică inaccesibilă '{$name}' apelată cu argumente: " . implode(', ', $arguments);
        }
    }
    MyClass::nonExistentStaticMethod('static_arg'); // Va afișa "Metodă statică inaccesibilă 'nonExistentStaticMethod' apelată cu argumente: static_arg"
    
  • __get(string $name): Este apelată când se încearcă obținerea valorii unei proprietăți inaccesibile sau inexistente în contextul obiectului. $name conține numele proprietății.

    <?php
    class MyClass {
        private $data = ['key' => 'value'];
        public function __get($name) {
            if (array_key_exists($name, $this->data)) {
                return $this->data[$name];
            }
            return null;
        }
    }
    $obj = new MyClass();
    echo $obj->key; // Va afișa "value"
    echo $obj->nonExistentKey; // Va afișa un șir gol (în funcție de valoarea null returnată)
    
  • __set(string $name, mixed $value): Este apelată când se încearcă setarea unei valori pentru o proprietate inaccesibilă sau inexistenta în contextul obiectului. $name conține numele proprietății, iar $value este valoarea de setat.

    <?php
    class MyClass {
        private $data = [];
        public function __set($name, $value) {
            $this->data[$name] = $value;
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    $obj->newKey = 'newValue';
    print_r($obj->getData()); // Va afișa Array ( [newKey] => newValue )
    
  • __isset(string $name): Este apelată când se folosește isset() sau empty() pe o proprietate inaccesibilă sau inexistenta în contextul obiectului. Returnează o valoare booleană.

    <?php
    class MyClass {
        private $data = ['present' => 'value'];
        public function __isset($name) {
            return array_key_exists($name, $this->data);
        }
    }
    $obj = new MyClass();
    var_dump(isset($obj->present));     // Va afișa bool(true)
    var_dump(isset($obj->absent));      // Va afișa bool(false)
    
  • __unset(string $name): Este apelată când se folosește unset() pe o proprietate inaccesibilă sau inexistenta în contextul obiectului.

    <?php
    class MyClass {
        private $data = ['remove_me' => 'value_to_remove'];
        public function __unset($name) {
            if (array_key_exists($name, $this->data)) {
                unset($this->data[$name]);
                echo "Proprietate '{$name}' ștearsă.\n";
            }
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    print_r($obj->getData());
    unset($obj->remove_me); // Va afișa "Proprietate 'remove_me' ștearsă." și va șterge elementul din $data
    print_r($obj->getData());
    
  • __sleep(): Este apelată înainte de serializarea obiectului cu serialize(). Trebuie să returneze un array cu numele proprietăților care trebuie serializate.

    <?php
    class MyClass {
        public $prop1 = 'value1';
        public $prop2 = 'value2';
        public function __sleep() {
            return ['prop1']; // Serializăm doar prop1
        }
    }
    $obj = new MyClass();
    $serialized = serialize($obj); // Va serializa doar prop1
    echo $serialized; // Va afișa aproximativ O:7:"MyClass":1:{s:5:"prop1";s:6:"value1";}
    
  • __wakeup(): Este apelată după deserializarea obiectului cu unserialize(). Este folosită pentru refacerea conexiunilor cu bazele de date sau alte acțiuni necesare după restaurarea obiectului.

    <?php
    class MyClass {
        public $prop1;
        public $resource; // Presupunem că este o resursă de conexiune
        public function __wakeup() {
            // Refacerea resursei, de exemplu, o conexiune la bazele de date
            $this->resource = fopen('/tmp/my_file.txt', 'w'); // Exemplu
            echo "Obiect trezit și resursă restaurată!\n";
        }
        public function __sleep() {
            // În __sleep nu serializăm resursa
            return ['prop1'];
        }
        public function __destruct() {
            if (is_resource($this->resource)) {
                fclose($this->resource);
                echo "Resursa închisă.\n";
            }
        }
    }
    $obj = new MyClass();
    $obj->prop1 = 'valoare deserializată';
    $serialized = serialize($obj);
    unset($obj);
    
    $deserialized_obj = unserialize($serialized); // Va apela __wakeup()
    var_dump($deserialized_obj->prop1);
    
  • __toString(): Este apelată când obiectul este folosit ca șir de caractere (de exemplu, la echo sau concatenare). Trebuie să returneze o reprezentare de șir a obiectului.

    <?php
    class MyClass {
        public $name = "MyObject";
        public function __toString() {
            return "Obiect de tip MyClass cu numele: " . $this->name;
        }
    }
    $obj = new MyClass();
    echo $obj; // Va afișa "Obiect de tip MyClass cu numele: MyObject"
    
  • __invoke(...): Este apelată când se încearcă apelarea obiectului ca funcție. Poate accepta orice număr de argumente.

    <?php
    class MyCallableClass {
        public function __invoke(...$args) {
            echo "Obiectul a fost apelat ca funcție cu argumente: " . implode(', ', $args);
        }
    }
    $obj = new MyCallableClass();
    $obj('arg1', 123); // Va afișa "Obiectul a fost apelat ca funcție cu argumente: arg1, 123"
    
  • __set_state(array $properties): Este apelată static pentru clasele exportate cu var_export(). Primește un array cu proprietățile exportate. Trebuie să creeze un nou obiect al clasei și să îl returneze.

    <?php
    class MyClass {
        public $prop;
        public static function __set_state(array $properties) {
            $obj = new MyClass();
            $obj->prop = $properties['prop'];
            return $obj;
        }
    }
    $obj = new MyClass();
    $obj->prop = 'valoare exportată';
    $exported = var_export($obj, true); // Exportă obiectul
    // $exported va conține codul pentru crearea obiectului, folosind __set_state()
    eval('$restored_obj = ' . $exported . ';');
    var_dump($restored_obj); // Va afișa obiectul MyClass cu proprietatea 'valoare exportată'
    
  • __debugInfo(): Este apelată la apelarea funcțiilor precum var_dump() pentru obiect. Metoda trebuie să returneze un array cu informații despre proprietățile obiectului, care trebuie afișate.

    <?php
    class MyClass {
        public $publicProp = 'public';
        private $privateProp = 'private';
        public function __debugInfo() {
            return ['publicProp' => $this->publicProp, 'private_info' => 'anumite detalii despre privateProp'];
        }
    }
    $obj = new MyClass();
    var_dump($obj); // Va afișa informațiile returnate de __debugInfo()
    
  • __clone(): Este apelată după operația de clonare (clone) a unui obiect. Este folosită pentru copierea profundă a obiectelor sau structurilor de date interne.

    <?php
    class SubObject {
        public $value;
        public function __construct($value) {
            $this->value = $value;
        }
    }
    class MyClass {
        public $object;
        public $anotherProp;
        public function __construct() {
            $this->object = new SubObject('initial');
            $this->anotherProp = 'original';
        }
        public function __clone() {
            // Clonarea obiectului intern pentru copiere profundă
            $this->object = clone $this->object;
        }
    }
    $obj = new MyClass();
    $cloned_obj = clone $obj;
    
    // Acum $obj->object și $cloned_obj->object sunt instanțe diferite ale SubObject
    $cloned_obj->object->value = 'modificat';
    
    var_dump($obj->object->value);       // Va afișa "initial"
    var_dump($cloned_obj->object->value); // Va afișa "modificat"
    

Tabel cu scurte descrieri:

Metoda Descriere Este apelată când...
__construct() Constructorul clasei. Când se creează o nouă instanță a clasei.
__destruct() Destructorul clasei. La ștergerea obiectului sau la încheierea scriptului.
__call() Tratarea apelurilor către metode inaccesibile sau inexistente ale obiectului. La încercarea de a apela o metodă inaccesibilă sau inexistentă a obiectului.
__callStatic() Tratarea apelurilor către metode statice inaccesibile sau inexistente. La încercarea de a apela o metodă statică inaccesibilă sau inexistentă a clasei.
__get() Tratarea accesului la proprietăți inaccesibile sau inexistente. La încercarea de a obține valoarea unei proprietăți inaccesibile sau inexistente.
__set() Tratarea setării valorii pentru proprietăți inaccesibile sau inexistente. La încercarea de a seta o valoare pentru o proprietate inaccesibilă sau inexistentă.
__isset() Tratarea verificării dacă o proprietate este setată sau goală. La utilizarea isset() sau empty() pe o proprietate inaccesibilă sau inexistentă.
__unset() Tratarea ștergerii unei proprietăți inaccesibile sau inexistente. La utilizarea unset() pe o proprietate inaccesibilă sau inexistentă.
__sleep() Pregătirea pentru serializare. La apelarea serialize() pe obiect.
__wakeup() Post-procesare după deserializare. La apelarea unserialize() pe obiect.
__toString() Reprezentarea obiectului ca șir de caractere. La utilizarea obiectului ca șir (de exemplu, la echo).
__invoke() Apelarea obiectului ca funcție. La încercarea de a apela obiectul ca funcție.
__set_state() Crearea unui obiect după export cu var_export(). La evaluarea codului exportat cu var_export().
__debugInfo() Informații pentru funcții de depanare (var_dump()). La apelarea var_dump() pe obiect.
__clone() Post-clonare. La apelarea clone pe obiect.