PHPDevs

Projekt obiektowy z Composerem i Twigiem? Czytaj!

Programowanie obiektowe > Lekcja 5

Metody magiczne

Przed nami kolejne dość ciekawe zagadnienie, co prawda z magią ma niewiele wspólnego. Są to w zasadzie normalne metody, ale nazywane magicznymi, ponieważ wywoływane są automatycznie w momencie wykonania danych akcji. Mamy w PHP kilka takich metod i zaraz sobie je omówimy. Występują tylko w kontekście klas, a ich nazwy zaczynają się od __.

__construct i __destruct

Najczęściej używana i spotykana to __construct - konstruktor. Metoda ta wywoływana jest w momencie utworzenia obiektu. Możemy też przekazywać przy jej pomocy dowolną ilość argumentów. Do czego się przydaje w praktyce? Na przykład do przesłania jakichś wartości do nowo tworzonego obiektu.

Destruktor działa odwrotnie, czyli wykonuje się gdy obiekt jest niszczony. Samemu przeważnie się tego nie robi (chociaż teoretycznie można), więc z chwilą zakończenia wykonywania kodu wszystko jest niszczone.

<?php

class Person
{
    private $name;
    private $city;

    public function __construct(string $name, string $city)
    {
        $this->name = $name;
        $this->city = $city;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getCity(): string
    {
        return $this->city;
    }

    public function __destruct()
    {
        echo 'Person removed!';
    }
}

$person = new Person('Jan Kowalski', 'Warszawa');
echo 'Name: ' . $person->getName() . ', city: ' . $person->getCity(); // result: Name: Jan Kowalski, city: Warszawa

unset($person); // remove object, result: Person removed!

__get i __set

Metody te wykonują się, gdy odwołujemy się do nieistniejącej właściwości obiektu. __get przy próbie odczytania wartości (przyjmuje jeden argument, którym jest nazwa tejże właściwości), a __set w momencie zmiany nieistniejącej właściwości (przyjmuje dwa argumenty - nazwę i wartość).

<?php
class Person
{
    public function __get($name)
    {
        return false;
    }

    public function __set($name, $value)
    {
        $this->$name = $value;
    }
}

$person = new Person();
$person->city = 'Poznań';
echo 'Name: ' . $person->name . ', city: ' . $person->city; // result: Name: , city: Poznań

Dzięki tym metodom możemy na przykład dynamicznie tworzyć nowe właściwości dla naszego obiektu (patrz przykład powyżej). Brzmi jak fajne ułatwienie, ale w praktyce nie do końca tak jest. Przez takie automatyczne tworzenie właściwości możemy utracić kontrolę nad tym co właściwie będzie działo się z obiektem, bo każdy może do niego dopisać co tylko chce. Z tego też powodu należy tych metod używać z rozwagą. Powiedziałbym nawet, że powinny być używane tylko tam gdzie to naprawdę konieczne, a i są teorie, że w ogóle nie powinny być używane. Wiedzieć, że istnieją z pewnością warto.

__call i __callStatic

Powyżej było coś do nieistniejących właściwości, to może i coś do metod by się przydało? Oto jest. __call uruchamia się w momencie odwołania do nieistniejącej metody. Dostajemy do dyspozycji dwa argumenty: pierwszy z jej nazwą, drugi z tablicą zawierającą przesłane do wywoływanej metody argumenty.

__callStatic działa identycznie, z tym że obsługuje nieistniejące metody statyczne.

W przypadku tych magicznych metod również należy mieć na uwadze słowa, które padły kilka linii wyżej: automatyczne wywoływanie pewnych akcji, gdy metoda nie istnieje, może być przydatne, ale rodzi też niebezpieczeństwo przypadkowego wykonania pewnych rzeczy w niezamierzonym miejscu.

<?php
class Person
{
    public function __call($name, $argunents)
    {
        return 'Method: ' . $name;
    }

    public static function __callStatic($name, $argunents)
    {
        return 'Static method: ' . $name;
    }
}

$person = new Person();
echo $person->getName(); // result: Method: getMethod
echo $person::getName(); // result: Static method: getMethod

__toString

Tej metody możemy użyć, aby w momencie próby wyświetlania całego obiektu został zwrócony jakiś string. Standardowo oczywiście taka próba zakończyła by się błędem, a dzięki __toString możemy tego w razie potrzeby dokonać.

<?php
class Person
{
    public function __toString()
    {
        return 'person';
    }
}

echo new Person(); // result: person

Ważna uwaga

Metody magiczne muszą być publiczne (modyfikator public). W innym przypadku kod po prostu nie zadziała i dostaniemy odpowiedni błąd.

Oprócz wymienionych powyżej istnieją jeszcze następujące magiczne metody:

Nie będę na razie więcej wyjaśniał. Poznałeś podstawowe metody magiczne, w razie czego więcej w manualu. No i pamiętaj o ich rozważnym używaniu ;)

Poprzednia lekcja Następna lekcja

Udostępnij

  • Facebook
  • Twitter
  • Google+

Komentarze