Sobes.tech
Middle

Ποια μαγικά μέθοδοι υπάρχουν στο PHP και πώς χρησιμοποιούνται;

sobes.tech AI

Απάντηση από AI

Οι μαγικές μέθοδοι στο PHP είναι ειδικές μέθοδοι που ξεκινούν με διπλή κάτω παύλα (π.χ., __construct) και καλούνται αυτόματα σε συγκεκριμένες καταστάσεις.

Οι βασικές μαγικές μέθοδοι και η χρήση τους:

  • __construct(): Καλείται κατά τη δημιουργία ενός αντικειμένου κλάσης. Χρησιμοποιείται για την αρχικοποίηση των ιδιοτήτων του αντικειμένου και την εκτέλεση αρχικών ενεργειών.

    <?php
    class MyClass {
        public function __construct() {
            echo "Το αντικείμενο δημιουργήθηκε!";
        }
    }
    $obj = new MyClass(); // Θα εμφανίσει "Το αντικείμενο δημιουργήθηκε!"
    
  • __destruct(): Καλείται κατά την καταστροφή του αντικειμένου (π.χ., όταν ολοκληρώνεται το σενάριο ή διαγράφεται το αντικείμενο από τη μνήμη). Χρησιμοποιείται για την απελευθέρωση πόρων (κλείσιμο αρχείων, συνδέσεις βάσεων δεδομένων).

    <?php
    class MyClass {
        public function __destruct() {
            echo "Το αντικείμενο καταστράφηκε!";
        }
    }
    $obj = new MyClass();
    unset($obj); // Θα εμφανίσει "Το αντικείμενο καταστράφηκε!"
    
  • __call(string $name, array $arguments): Καλείται όταν προσπαθείτε να καλέσετε μια μη διαθέσιμη ή μη υπάρχουσα μέθοδο στο πλαίσιο του αντικειμένου. $name περιέχει το όνομα της μεθόδου και $arguments έναν πίνακα με τα επιχειρήματα.

    <?php
    class MyClass {
        public function __call($name, $arguments) {
            echo "Κάλεσε μη διαθέσιμη μέθοδο '{$name}' με επιχειρήματα: " . implode(', ', $arguments);
        }
    }
    $obj = new MyClass();
    $obj->nonExistentMethod('arg1', 'arg2'); // Θα εμφανίσει "Κάλεσε μη διαθέσιμη μέθοδο 'nonExistentMethod' με επιχειρήματα: arg1, arg2"
    
  • __callStatic(string $name, array $arguments): Καλείται όταν προσπαθείτε να καλέσετε μια μη διαθέσιμη ή μη υπάρχουσα στατική μέθοδο στο πλαίσιο της κλάσης. Παρόμοια με το __call, αλλά για στατικές κλήσεις.

    <?php
    class MyClass {
        public static function __callStatic($name, $arguments) {
            echo "Κάλεσε μη διαθέσιμη στατική μέθοδο '{$name}' με επιχειρήματα: " . implode(', ', $arguments);
        }
    }
    MyClass::nonExistentStaticMethod('static_arg'); // Θα εμφανίσει "Κάλεσε μη διαθέσιμη στατική μέθοδο 'nonExistentStaticMethod' με επιχειρήματα: static_arg"
    
  • __get(string $name): Καλείται όταν προσπαθείτε να λάβετε την τιμή μιας μη διαθέσιμης ή μη υπάρχουσας ιδιότητας στο πλαίσιο του αντικειμένου. $name περιέχει το όνομα της ιδιότητας.

    <?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; // Θα εμφανίσει "value"
    echo $obj->nonExistentKey; // Θα εμφανίσει κενή γραμμή (ανάλογα με την επιστρεφόμενη τιμή null)
    
  • __set(string $name, mixed $value): Καλείται όταν προσπαθείτε να ορίσετε την τιμή μιας μη διαθέσιμης ή μη υπάρχουσας ιδιότητας στο πλαίσιο του αντικειμένου. $name περιέχει το όνομα της ιδιότητας και $value την ορισμένη τιμή.

    <?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()); // Θα εμφανίσει Array ( [newKey] => newValue )
    
  • __isset(string $name): Καλείται κατά τον έλεγχο isset() ή empty() σε μια μη διαθέσιμη ή μη υπάρχουσα ιδιότητα στο πλαίσιο του αντικειμένου. Επιστρέφει 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));     // Θα εμφανίσει bool(true)
    var_dump(isset($obj->absent));      // Θα εμφανίσει bool(false)
    
  • __unset(string $name): Καλείται όταν καλείτε unset() σε μια μη διαθέσιμη ή μη υπάρχουσα ιδιότητα στο πλαίσιο του αντικειμένου.

    <?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 "Ιδιότητα '{$name}' διαγράφηκε.\n";
            }
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    print_r($obj->getData());
    unset($obj->remove_me); // Θα εμφανίσει "Ιδιότητα 'remove_me' διαγράφηκε." και θα διαγράψει το στοιχείο από το $data
    print_r($obj->getData());
    
  • __sleep(): Καλείται πριν από την σειριοποίηση του αντικειμένου με χρήση serialize(). Πρέπει να επιστρέφει έναν πίνακα με τα ονόματα των ιδιοτήτων που πρέπει να σειριοποιηθούν.

    <?php
    class MyClass {
        public $prop1 = 'value1';
        public $prop2 = 'value2';
        public function __sleep() {
            return ['prop1']; // Θα σειριοποιηθεί μόνο το prop1
        }
    }
    $obj = new MyClass();
    $serialized = serialize($obj); // Θα σειριοποιηθεί μόνο το prop1
    echo $serialized; // Θα εμφανίσει περίπου O:7:"MyClass":1:{s:5:"prop1";s:6:"value1";}
    
  • __wakeup(): Καλείται μετά την αποσειριοποίηση του αντικειμένου με χρήση unserialize(). Χρησιμοποιείται για την αποκατάσταση συνδέσεων με βάσεις δεδομένων ή άλλων ενεργειών που απαιτούνται μετά την αποκατάσταση του αντικειμένου.

    <?php
    class MyClass {
        public $prop1;
        public $resource; // Υποθέτουμε ότι είναι πόρος σύνδεσης
        public function __wakeup() {
            // Αποκατάσταση πόρου, π.χ., σύνδεση με βάση δεδομένων
            $this->resource = fopen('/tmp/my_file.txt', 'w'); // Παράδειγμα
            echo "Το αντικείμενο ξύπνησε και ο πόρος αποκαταστάθηκε!\n";
        }
        public function __sleep() {
            // Δεν σειριοποιούμε τον πόρο
            return ['prop1'];
        }
        public function __destruct() {
            if (is_resource($this->resource)) {
                fclose($this->resource);
                echo "Ο πόρος έκλεισε.\n";
            }
        }
    }
    $obj = new MyClass();
    $obj->prop1 = 'deserialized value';
    $serialized = serialize($obj);
    unset($obj);
    
    $deserialized_obj = unserialize($serialized); // Θα καλέσει __wakeup()
    var_dump($deserialized_obj->prop1);
    
  • __toString(): Καλείται όταν το αντικείμενο χρησιμοποιείται ως συμβολοσειρά (π.χ., κατά το echo ή την συνηθισμένη σύνδεση). Πρέπει να επιστρέφει μια συμβολοσειρά που αντιπροσωπεύει το αντικείμενο.

    <?php
    class MyClass {
        public $name = "MyObject";
        public function __toString() {
            return "Αντικείμενο τύπου MyClass με όνομα: " . $this->name;
        }
    }
    $obj = new MyClass();
    echo $obj; // Θα εμφανίσει "Αντικείμενο τύπου MyClass με όνομα: MyObject"
    
  • __invoke(...): Καλείται όταν προσπαθείτε να καλέσετε το αντικείμενο ως συνάρτηση. Μπορεί να δεχτεί οποιονδήποτε αριθμό επιχειρημάτων.

    <?php
    class MyCallableClass {
        public function __invoke(...$args) {
            echo "Το αντικείμενο καλείται ως συνάρτηση με επιχειρήματα: " . implode(', ', $args);
        }
    }
    $obj = new MyCallableClass();
    $obj('arg1', 123); // Θα εμφανίσει "Το αντικείμενο καλείται ως συνάρτηση με επιχειρήματα: arg1, 123"
    
  • __set_state(array $properties): Καλείται στατικά για τις κλάσεις που εξάγονται με var_export(). Λαμβάνει έναν πίνακα με τις εξαγόμενες ιδιότητες. Πρέπει να δημιουργήσει ένα νέο αντικείμενο κλάσης και να το επιστρέψει.

    <?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 = 'exported value';
    $exported = var_export($obj, true); // Εξαγωγή του αντικειμένου
    // Το $exported θα περιέχει κώδικα για τη δημιουργία του αντικειμένου, που χρησιμοποιεί το __set_state()
    eval('$restored_obj = ' . $exported . ';');
    var_dump($restored_obj); // Θα εμφανίσει το αντικείμενο MyClass με την ιδιότητα 'exported value'
    
  • __debugInfo(): Καλείται κατά την κλήση συναρτήσεων όπως το var_dump() για το αντικείμενο. Η μέθοδος πρέπει να επιστρέφει έναν πίνακα με τις πληροφορίες σχετικά με τις ιδιότητες του αντικειμένου που πρέπει να εμφανίζονται.

    <?php
    class MyClass {
        public $publicProp = 'public';
        private $privateProp = 'private';
        public function __debugInfo() {
            return ['publicProp' => $this->publicProp, 'private_info' => 'μερικές λεπτομέρειες για το private'];
        }
    }
    $obj = new MyClass();
    var_dump($obj); // Θα εμφανίσει τις πληροφορίες που επιστρέφει το __debugInfo()
    
  • __clone(): Καλείται μετά την εντολή κλωνοποίησης (clone) του αντικειμένου. Χρησιμοποιείται για βαθιά αντιγραφή εσωτερικών αντικειμένων ή δομών δεδομένων.

    <?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('αρχικό');
            $this->anotherProp = 'αρχικό';
        }
        public function __clone() {
            // Κλωνοποιούμε το εσωτερικό αντικείμενο για βαθιά αντιγραφή
            $this->object = clone $this->object;
        }
    }
    $obj = new MyClass();
    $cloned_obj = clone $obj;
    
    // Τώρα $obj->object και $cloned_obj->object είναι διαφορετικά αντικείμενα SubObject
    $cloned_obj->object->value = 'τροποποιήθηκε';
    
    var_dump($obj->object->value);       // Θα εμφανίσει "αρχικό"
    var_dump($cloned_obj->object->value); // Θα εμφανίσει "τροποποιήθηκε"
    

Πίνακας με σύντομη περιγραφή:

Μέθοδος Περιγραφή Καλείται όταν...
__construct() Ο κατασκευαστής της κλάσης. Δημιουργία νέου δείγματος της κλάσης.
__destruct() Ο καταστροφέας της κλάσης. Διαγραφή αντικειμένου ή ολοκλήρωση του σενάριου.
__call() Διαχείριση κλήσεων μη διαθέσιμων/μη υπαρχόντων μεθόδων. Προσπάθεια κλήσης μη διαθέσιμης ή μη υπαρκτής μεθόδου.
__callStatic() Διαχείριση κλήσεων μη διαθέσιμων/μη υπαρχόντων στατικών μεθόδων. Προσπάθεια κλήσης μη διαθέσιμης ή μη υπαρκτής στατικής μεθόδου.
__get() Διαχείριση λήψης τιμής μη διαθέσιμων/μη υπαρχόντων ιδιοτήτων. Προσπάθεια λήψης τιμής μη διαθέσιμης ή μη υπαρκτής ιδιότητας.
__set() Διαχείριση ορισμού τιμής μη διαθέσιμων/μη υπαρχόντων ιδιοτήτων. Προσπάθεια ορισμού τιμής σε μη διαθέσιμη ή μη υπαρκτή ιδιότητα.
__isset() Έλεγχος isset() ή empty() σε ιδιότητες. Κλήση isset() ή empty() σε μη διαθέσιμη ή μη υπαρκτή ιδιότητα.
__unset() Διαχείριση διαγραφής ιδιοτήτων με unset(). Κλήση unset() σε μη διαθέσιμη ή μη υπαρκτή ιδιότητα.
__sleep() Προετοιμασία για σειριοποίηση. Κλήση serialize() σε αντικείμενο.
__wakeup() Μετά την αποσειριοποίηση. Κλήση unserialize() σε αντικείμενο.
__toString() Παρουσίαση αντικειμένου ως συμβολοσειρά. Χρήση του αντικειμένου ως συμβολοσειρά (π.χ., echo).
__invoke() Κλήση αντικειμένου ως συνάρτηση. Προσπάθεια κλήσης του αντικειμένου ως συνάρτηση.
__set_state() Δημιουργία αντικειμένου μετά την εξαγωγή με var_export(). Αξιολόγηση κώδικα που δημιουργείται από το var_export().
__debugInfo() Πληροφορίες για αποσφαλμάτωση (var_dump()). Κλήση var_dump() σε αντικείμενο.
__clone() Μετά την κλωνοποίηση. Κλήση clone σε αντικείμενο.