Magia w PHP

Każdy język programowania ma swoje smaczki. W przypadku PHP smaczkiem tym są magiczne metody – znienawidzone przez jednych, nadużywane przez innych. Zastosowane z rozwagą i dobrze użyte mogą znacząco wpłynąć na rozwój kodu. Każda magiczna metoda rozpoczyna się dwoma znakami podkreślenia ( __ ). Twórcy języka wyraźnie zaznaczyli, że konwencja ta jest zarezerwowana wyłącznie dla magicznych metod i nie powinna być stosowana w innych przypadkach.


Konstruktor

Najczęściej używaną przez programistów PHP magią jest konstruktor. Oznaczony jako __construct odpowiada za inicjalizację obiektu. Konstruktor może przyjąć dowolną liczbę argumentów i wbrew pozorom nic nie zwraca.

class Foo
{
    protected $_zmienna;

    public function __construct($arg1 = null)
    {
        $this->_zmienna = $arg1;
    }
}

Jeśli zwrócimy coś w konstruktorze, dopiero jego jawne wywołanie spowoduje, że wartość ta będzie dostęna.

class Foo
{
    public function __construct()
    {
        return null;
    }
}

$foo = new Foo();
var_dump($foo->__construct()); // wyswieli NULL

Konstruktory mogą być podstępne, zwłaszcza jeśli korzystamy z dziedziczenia. Należy pamiętać, iż nadpisanie konstruktora spowoduje, że wykona się konstruktor zadeklarowany najniżej w hierarchii. Pozostałe musimy sami wywołać.

class Foo
{
    public function __construct()
    {
        echo 'Konstruktor Foo';
    }
}

class Bar extends Foo
{
    public function __construct()
    {
        echo 'Konstruktor Bar';
    }
}

class Baz extends Bar
{
    public function __construct()
    {
        echo 'Konstruktor Baz';
    }
}

$baz = new Baz();

Powyższy kod wyświetli tylko jeden tekst – Konstruktor Baz. Dopiero jawne wskazanie, że konstruktor rodzica też ma się wykonać, spowoduje wyświetlenie pozostałych tekstów.

class Foo
{
    public function __construct()
    {
        echo 'Konstruktor Foo';
    }
}

class Bar extends Foo
{
    public function __construct()
    {
        parent::__construct();
        echo 'Konstruktor Bar';
    }
}

class Baz extends Bar
{
    public function __construct()
    {
        parent::__construct();
        echo 'Konstruktor Baz';
    }
}

$baz = new Baz();

Powyższy kod wyświetli

Konstruktor Foo
Konstruktor Bar
Konstruktor Baz

Jak widać konstruktory wykonują się po kolei. Dzieje się tak dlatego, że wywołanie konstruktora rodzica jest pierwszą instrukcją. Dzięki możliwości sterowania momentem wywołania konstruktora rodzica mamy wpływ na proces inicjalizacji obiektów.

Destruktor

Przeciwieństwem konstruktora jest destruktor, który służy do sprzątania bałaganu po obiekcie. Metoda ta zostanie wywołana w momencie, gdy na dany obiekt nie wskazuje żadna referencja. Podobnie jak w przypadku konstruktorów, destruktory klas nadrzędnych należy wywołać samemu.

class Foo
{
    public function __destruct()
    {
        echo 'Destruktor Foo';
    }
}

class Bar extends Foo
{
    public function __destruct()
    {
        parent::__destruct();
        echo 'Destruktor Bar';
    }
}

class Baz extends Bar
{
    public function __destruct()
    {
        parent::__destruct();
        echo 'Destruktor Baz';
    }
}

$baz = new Baz();

Przeciążanie metod

W PHP nie ma możliwości zdefiniowania dowolnej ilości takich samych metod z różnymi parametrami. Jeśli ktoś spróbuje takie coś zrobić, niemiło się rozczaruje. Z pomocą przychodzi kolejna magia w postaci dwóch metod: __call oraz __callStatic. Obie metody działają w taki sam sposób, przy czym __call działa z poziomu obiektu, a __callStatic z poziomu klasy. Obie metody zostaną wywołane w przypadku gdy na obiekcie (__call) lub klasie (__callStatic) wywołana zostanie niezdefiniowana metoda.

Zarówno metoda __call jak i __callStatic przyjmują dwa argumenty. Pierwszym z nich jest nazwa wywołanej (nieistniejącej) metody, drugim tablica przekazanych do niej argumentów.

class Foo
{
	public function bar()
	{
		return 'jestem metoda bar';
	}

	public static function baz()
	{
		return 'jestem statyczna metoda baz';
	}

	public function __call($name, $args)
	{
		return 'wywolano nieistniejaca metode ' . $name . ' z argumentami: '
			. print_r($args, true);
	}

	public static function __callStatic($name, $args)
	{
		return 'wywolano nieistniejaca statyczna metode ' . $name . ' z argumentami: '
			. print_r($args, true);
	}
}

$foo = new Foo();
echo $foo->bar();
echo $foo->nieistniejaca_metoda('abc', 123);

echo Foo::baz();
echo Foo::nieistniejaca_metoda_statyczna('abc', 123);

Powyższy kod wyświetli:

jestem metoda bar
wywolano nieistniejaca metode nieistniejaca_metoda z argumentami:
Array
(
    [0] => abc
    [1] => 123
)

jestem statyczna metoda baz
wywolano nieistniejaca statyczna metode nieistniejaca_metoda_statyczna z argumentami:
Array
(
    [0] => abc
    [1] => 123
)

Do czego jest to potrzebne? Po pierwsze do zastąpienia setek zbędnych metod wykonujących tą samą czynność, różniącą się jednym parametrem. Dobrym przykładem będzie tutaj metoda pobierająca dane z bazy na podstawie nazwy kolumny – getUsersByName. Magiczna metoda jest w stanie rozpoznać nazwę tabeli (Users) oraz nazwę kolumny (Name) i na tej podstawie pobrać dane. Dzięki zastosowaniu magii nie musimy pisać metod dla wszystkich tabel i wszystkich kolumn w bazie.

Innym zastosowaniem opisanych wyżej metod jest przechwytywanie niepoprawnych wywołań metod i eleganckie zgłaszanie wyjątków.

Przeciążanie właściwości

Podobnie jak metody, przeciążać można również właściwości. PHP oferuje cztery magiczne metody to umożliwiające. Są to:

  • __set – wywoływana w momencie zapisywania nieistniejącej lub niedostępnej publicznie właściwości
  • __get – wywoływana w momencie pobierania nieistniejącej lub niedostępnej publicznie właściwości
  • __isset – wywoływana w momencie sprawdzania nieistniejącej właściwość
  • __unset – wywoływana w momencie usuwania nieistniejącej lub niedostępnej publicznie właściwości
class Foo
{
	protected $_data = array();

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

	public function __get($name)
	{
		return $this->_data[$name];
	}

	public function __isset($name)
	{
		return isset($this->_data[$name]);
	}

	public function __unset($name)
	{
		unset($this->_data[$name]);
	}}

$foo = new Foo();
var_dump($foo);

$foo->bar = 123;
$foo->baz = 'abc';
var_dump($foo);
var_dump(isset($foo->baz));
var_dump(isset($foo->baaz));

unset($foo->bar);
var_dump($foo);

Powyższy kod wyświetli

object(Foo)#1 (1) {
  ["_data":protected]=>
  array(0) {
  }
}
object(Foo)#1 (1) {
  ["_data":protected]=>
  array(2) {
    ["bar"]=>
    int(123)
    ["baz"]=>
    string(3) "abc"
  }
}
bool(true)
bool(false)
object(Foo)#1 (1) {
  ["_data":protected]=>
  array(1) {
    ["baz"]=>
    string(3) "abc"
  }
}

O ile robienie obiektowej nakładki na tablicę mija się z celem, tak wykorzystanie przeciążania właściwości w przypadku obiektów operujących na danych pochodzących z różnych źródeł pozwala na znaczne zmniejszenie ilości kodu oraz wprowadzenie spójnego interfejsu dostępu do tych danych. Przeciążanie właściwości połączone z przeciążaniem metod daje ogromne możliwości pozwalające na tworzenie jednorodnych obiektów, będących swoistą czarną skrzynką. Co więcej, skrzynka ta nie będzie przeładowana zbędnym kodem.

Serializacja obiektów

Co robimy jeśli chcemy zachować stan jakiegoś obiektu na później? Serializujemy go. PHP oferuje dwie magiczne metody związane z serializacją. Są to __sleep, wywoływana w momencie użycia funkcji serialize na obiekcie oraz __wakeup, wywoływana w momencie deserializacji obiektu przy pomocy funkcji unserialize.

class Foo
{
	public function __sleep()
	{
		echo 'zaspiam';
		return array();
	}

	public function __wakeup()
	{
		echo 'budze sie';
	}
}

$foo = new Foo();

echo 'przed serializacja';
$serialized = serialize($foo);
echo 'po serializacji';

echo 'przed deserializacja';
unserialize($serialized);
echo 'po deserializacji';

W wyniku działania powyższego skryptu uzyskamy następujący efekt

przed serializacja
zaspiam
po serializacji

przed deserializacja
budze sie
po deserializacji

W serializacji nie chodzi o wyświetlanie tekstu, a o zapisywanie aktualnego stanu obiektu. Tylko co to oznacza? Oznacza to ni mniej ni więcej jak zapamiętanie tych właściwości, na podstawie których będziemy mogli przywrócić obiekt do stanu sprzed serializacji. Czyli jeśli nasz obiekt przed serializacją łączył się do bazy lub otwierał jakiś plik, po deserializacji musi do tej bazy już być połączony a plik mieć już otwarty. I do tego właśnie służą metody __sleep i __wakeup. Pierwsza z nich musi zwrócić tablicę nazw właściwości, które chcemy zapamiętać. Druga w momencie deserializacji będzie w stanie wywołać wszystkie niezbędne metody, które przywrócą obiekt do właściwego stanu na podstawie zapamiętanych właściwości.

class Foo
{
	protected $_fileName = '';
	protected $_fh;

	public function __construct($fileName)
	{
		$this->_fileName = $fileName;
	}

	public function openFile()
	{
		$this->_fh = fopen($this->_fileName, 'r');
	}

	public function test()
	{
		var_dump($this->_fh);
	}

	public function __sleep()
	{
		return array('_fileName');
	}

	public function __wakeup()
	{
		$this->openFile();
	}
}

$foo = new Foo(__FILE__);
$foo->openFile();
$foo->test();
$serialized = serialize($foo);

$bar = unserialize($serialized);
$bar->test();

 

Obiekty jako ciągi

Czasami zachodzi potrzeba “wyświetlenia” obiektu. Zdarza się to w przypadku obiektów reprezentujących jakiś ciąg znaków, np. zapytanie SQL. Zamiast tworzyć metodę, którą następnie będziemy musieli wywołać, wystarczy użyć magicznej metody __toString. Jeśli obiekt jest w nią wyposażony, to w momencie “echowania” obiektu lub zrzutowania go na typ string, zostanie ona wywołana. Zgodnie ze swoją nazwą metoda ta musi zwracać string.

class Foo
{
	public function __toString()
	{
		return 'ciag reprezentujacy obiekt';
	}
}

$foo = new Foo();
echo $foo;

 

Obiekty jako funkcje

Obiekty można wywoływać jako funkcje. Wprawdzie brzmi to absurdalnie, ale jest to możliwe. W zasadzie dzięki tej funkcjonalności w PHP można korzystać z funkcji anonimowych. Jak to działa? Bardzo prosto – podczas użycia obiektu jako funkcji, wywołana zostanie magiczna metoda __invoke.

class Foo
{
	public function __invoke($arg1, $arg2)
	{
		echo $arg1;
		echo $arg2;
	}
}

$foo = new Foo();
$foo('abc', 123);

Metoda ta poza wspomnianymi funkcjami anonimowymi nie ma żadnego praktycznego zastosowania.

Klonowanie obiektów

Ostatnią magią dostępną w PHP jest metoda __clone, uruchamiana po sklonowaniu obiektu. Klonowanie obiektu polega na wykonaniu kopii klonowanego obiektu, a nie kopii referencji do niego. Dzięki temu uzyskujemy dwa niezależne od siebie obiekty. Metoda __clone ma zadanie umożliwić przeprowadzenie dodatkowych operacji na nowym obiekcie.

class Foo
{
	public $a = 'abc';

	public function __clone()
	{
		$this->a = 123;
	}
}

$foo = new Foo();
$bar = clone $foo;

echo $foo->a; // wyswietli abc
echo $bar->a; // wyswietli 123

Metoda ta bardzo często wykorzystywana jest razem z singletonem w celu zapobiegnięcia stworzenia kolejnej instancji klasy. Najczęściej w metodzie __clone klasy będącej singletonem rzucany jest wyjątek, który skutecznie zniechęca do klonowania takiego obiektu.

Podsumowanie

Uff. Dotarliśmy do końca pehapowej magii. Jak widać jest jej całkiem sporo. Zanim jednak zaczniecie z niej korzystać w każdym możliwym miejscu, musicie wiedzieć, że zbyt dużo magii oznacza “not enough mana”, czyli mułowaty projekt, przy którym poci się najlepszy serwer. Nie można również zapominać o wygodzie programowania, która praktycznie zanika przy zbyt intensywnym czarowaniu. Za przykład niech posłuży tutaj magiczny Zend Framework, który jest praktycznie nieużywalny bez IDE oraz sporej wiedzy encyklopedycznej.

Jedyną radą jaką jestem w stanie wam udzielić będzie – “use the force”, ale z głową.

Leave a comment ?

27 Comments.

  1. To są właśnie rzeczy za które lubię PHP i języki dynamiczne. Ale tak jak zaznaczyłeś – z drugiej strony nadużywanie może prowadzić do różnych dziwnych zjawisk w kodzie :>. Przy korzystaniu z magii przydaje się obsługa phpdoc w różnych IDE.

  2. Świetny wpis, będę linkował tym, nie znają metod magicznych i nie lubią czytać "nieponaszemu".

    Jednakże odnośnie "przeciążania metod" chciałbym dodać, że jest możliwa emulacja przeciążania metod w PHP: http://pastebin.com/tmnuHjax (wsparcie dla rozpoznawania typów argumentów też można dodać).

    Wiadomo – przeciążanie nie jest natywnie obsługiwane przez sam język i kod wyżej to kombinacja, aczkolwiek z punktu widzenia osoby używającej danej klasy jest to możliwe.

  3. @sokzzuka
    Jakiś czas popełniłem podobny wpis o podpowiadaniu składni magicznych metod w Eclipsie.

    @singles
    Sposób z pobieraniem ilości parametrów przy pomocy func_num_args rzeczywiście pozwala na emulowanie przeciążania metod. Niestety podobnie jak w przypadku magicznych metod może to spowodować zaciemnienie kodu.

  4. @singles, można by zrobić dużo przyjemniejszą, uniwersalną implementację za pomocą magicznego __call…

  5. @sokzzuka Ciekawe podejście. Jeśli dobrze rozumiem, jego cechą jest fakt, że metody muszą nazywać się w określony sposób [nazwaMetodyWywolywanej][liczbaparametrow]. Trochę by się komplikowało przy sprawdzaniu jeszcze typu parametru (string, int, object), aczkolwiek wykonalne.
    Dzięki za ten kawałek kodu, nie wpadłem na takie rozwiązanie :)

  6. @singles, tak dobrze to rozumiesz, jeżeli chodzi o sprawdzanie typu, wystarczyło by dołożyć phpDoc-a, następnie przy pomocy refleksji odczytać nazwy parametrów wywoływanej funkcji, po nazwach je skojarzyć i wykonać odpowiednie sprawdzenia, 10 linii kodu tak na oko :)

  7. Tomasz Kowalczyk

    Jakiś czas temu napisałem stosowne narzędzie do przeciążania metod i funkcji – obsługuje wszystkie wskazane przez Was funkcje. Jak będę miał trochę więcej czasu, to doszlifuję je i dokładnie przetestuję, a potem opiszę na blogu.

    Jedna uwaga co do artykułu – konstruktor zwraca wartość, jest nią $this. Nie próbowałem nigdy zwracać niczego z konstruktora samodzielnie i jeśli jest to możliwe w PHP [a podejrzewałem, że jest, bo konstruktor to tylko zwykła metoda], to mam nadzieję, że ktoś to naprawi.

  8. @singles: szybka implementacja ale w wariancie sprawdzania typów parametrów zamiast przeciążania po typie: http://pastebin.com/ZgMwSFMd do przeciążania po typie parametru wystarczyłoby kilak modyfikacji

  9. @Tomasz Kowalczyk
    Tak wygląda opis konstruktora
    void __construct ([ mixed $args [, $... ]] )

    Jawne wywołanie metody __construct nie zwróci obiektu. Zwróci null.

  10. Tomasz Kowalczyk

    Bardziej od samej deklaracji metody __construct() miałem na myśli "logiczne" wyjaśnienie całego tematu. Jeśli nie zwraca on "nic", to co podstawiamy pod zmienną w wywołaniu $foo = new Foo(); ? Jeśli chodzi o jawne wywołanie metody konstruktora bez użycia new, to jasne – wtedy działa to jak zwykła metoda, co moim zdaniem nie jest zbyt szczęśliwym pomysłem.

  11. @tomasz, tak po prostu jest język skonstruowany, w php wszystkie funkcje magiczne są pewnego rodzaju "hookami" i __construct jest funkcją inicjalizującą wywoływaną przy instantacji obiektu, obiekt jest konstruowany przez operator "new" natomiast __construct inicjalizuje te zmienne, które nie mogą być zadeklarowane w ciele klasy z różnych powodów. W Rubym czy w Pythonie konstruktor zwraca instancję obiektu stworzonego bodajże, ale to całkiem inna bajka…

  12. Lepiej bym tego nie wyjaśnił.
    __construct działa podobnie do metody __clone, która również wywoływana jest po zakończeniu jakiejś czynności (w tym przypadku klonowania obiektu).

  13. Moim zdaniem bardzo fajnie napisany artykuł. Lekko, z sensownymi i prostymi przykładami. Tylko popraw przy "Przeciążaniu właściwości" opisy magii. Sam chyba przyznasz, że "__unset – wywoływana w momencie usuwania nieistniejącej właściwości" czy "__get – wywoływana w momencie pobierania danych z nieistniejącej właściwości" brzmi nieco dziwnie, żeby nie powiedzieć myląco. Bo jak można pobrać wartość nieistniejącej właściwości? Lepiej to przeredagować na coś w stylu: "__get – wywołanie funkcji obsługującej odwołanie do nieistniejącej z nazwy właściwości". Należy pamiętać też o tym, że zostać tu także podczepiona może istniejąca zmienna, ale o innym niż publiczny dostępie i ją także obsłuży __get, choćbyśmy nie chcieli(!). Podrzucę kod
    class Foo {
    protected $data_prot = 1;
    private $data_priv = 2;
    public $data_pub = 3;

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

    $foo = new Foo();
    var_dump($foo);
    echo $foo->data_pub;
    echo $foo->data_priv;
    echo $foo->data_prot;
    $foo->data_prot = 5;
    echo $foo->data_prot;

    Jego wykonanie wyświetli:
    object(Foo)#1 (3) { ["data_prot":protected]=> int(1) ["data_priv":"Foo":private]=> int(2) ["data_pub"]=> int(3) }
    3215
    Czyli najpierw ładnie po kolei wyświetli dane ignorując widocznośc własciwości, a na koniec sobie pozwoli na zmianę prywatnej i ją też wyświetli bez przeszkód. Tak więc należy uważać na co się pozwala metodom magicznym ;)

  14. Przepraszam… Nie prywatnej tylko chronionej :) Można powiedzieć, że do pewnego stopnia są metody magiczne podobne do funkcji szablonowych z C++. Język ma pewien szablon w silniku i na podstawie kodu usera tworzy własne warianty. Tylko że w C++ były one na etapie kompilatora tworzone jeśli dobrze kojarzę dla wszystkich znanych mu typów, zaś w PHP chyba są tworzone "w locie" w razie potrzeby.

  15. @thek
    Długo zastanawiałem się jak to napisać, aby miało ręce i nogi i niestety nie udało mi się znaleźć złotego środka. Albo tekst był za długi (i powtarzał się 4 razy) albo nie do końca oddawał istotę sprawy. Jak tylko wpadnę na coś lepszego, zmienię.

    Pokazałeś ciekawy przykład, udowadniający, że należy się pilnować na każdym kroku.

  16. To może nieco modyfikując Twoje i moje określenia coś w deseń…
    __set – wywoływana w momencie zapisywania nie istniejącej lub niedostępnej publicznie właściwości
    __get – wywoływana w momencie pobierania nie istniejącej lub niedostępnej publicznie właściwości
    __isset – wywoływana w momencie sprawdzania czy właściwość nie istniejąca lub niedostępna publicznie jest ustawiona
    __unset – wywoływana w momencie usuwania nie istniejącej lub niedostępnej publicznie właściwości

    Zwróć uwagę, że wszędzie użyłem słowa "publicznie", ponieważ dla danych publicznych dostęp jest bezpośredni i magia nie ruszy. Dzieje się to jedynie gdy nazwa właściwości jest klasie nieznana lub ma ona dostęp inny niż public :) Toby chyba wyczerpywało możliwe powody wywołania tych metod.

  17. Co do __isset to chyba bardziej po polsku byłoby:
    __isset – wywoływana w momencie sprawdzania czy jest ustawiona właściwość nie istniejąca w definicji klasy lub gdy jest ona niedostępna publicznie.

  18. Zmiany naniesione.

  19. Świetny artykuł. Magia w pigułce. Sama się do czegoś takiego przymierzałam, ale teraz to już nie ma potrzeby :)

  20. Wpisów, artykułów itd. o magii w PHP jest w polskim Internecie od groma, natomiast brakuje wyraźnie tekstów poświęconych konsekwencjom jej stosowania. Tak jak wszędzie, jest tu o tym zaledwie kilka zdań na końcu i nic poza tym. Tymczasem w największych projektach PHP obserwuje się obecnie odchodzenie od zachowań magicznych, pozostawiając tylko nieliczne, naprawdę niezbędne. Nic dziwnego – magia często była przedstawiana jako jedyny sposób wykonania czegoś (!!!) i wielu programistów dało się omamić, nie próbując nawet pomyśleć, jak można to zrobić jednocześnie jawnie i czytelnie. Odkąd zobaczyłem sobie kod Symfony 2 i Doctrine 2, zrozumiałem, jak wielki syf może wtedy powstać nawet w najlepszych projektach. W sekcji o przeciążaniu metod czytamy: „Do czego jest to potrzebne? Po pierwsze do zastąpienia setek zbędnych metod wykonujących tą samą czynność, różniącą się jednym parametrem. Dobrym przykładem będzie tutaj metoda pobierająca dane z bazy na podstawie nazwy kolumny – getUsersByName” – zamiast tego można przecież zrobić ogólną metodę, gdzie takie dane podaje się jako argumenty wywołania: getDataBy('users', 'name', ...).

  21. Masz rację, nieco zbyt entuzjastycznie podszedłem do tematu. Jednak zamiarem moim było nie namawianie do magii, lecz zaprezentowanie jej rzeczywistych możliwości bez żadnego narzuconego z góry kontekstu. W końcu magia jest wepchnięta do każdego większego projektu i dobrze wiedzieć jak działa. Cieszy fakt, że najwięksi się z niej wycofują. Z drugiej jednak strony, taki Fabien Potencier napisał przy jej użyciu (oraz anonimowych funkcji) bardzo fajny kawałek kodu – klasę DIContainer.

  22. Dobre opisy techniczne są jak najbardziej potrzebne, tym bardziej że aby naprawdę dobrze poznać wroga, trzeba mieć choćby minimalne pojęcie o tym, jak on właściwie działa. Bardziej filozoficzno-użytkowe rozwinięcie tych rozważań pozwoliłem sobie umieścić u siebie na blogu, bo faktycznie patrząc nawet po forum PHP widać, że bardzo czegoś takiego brakuje. Jeśli miałbyś coś ciekawego do napisania także na ten temat, chętnie poczytam.

  23. Magia w PHP - develway.pl - pingback on 16 stycznia 2011 at 20:37
  24. A ja sobie Zyx pozwoliłem skomentować, także nieco filozoficznie, podejście do metod magicznych bazujące na moim wpisie tutaj, będącym ciut wyżej. A także kilka innych uwag jeszcze odnośnie magii i moim zdaniem jego obecnego powolnego przemijania. Nie kryjmy się z tym: magia to „moda” i prędzej czy później będzie potraktowana jak register_globals czy magic_quotes. Fajna do czasu gdy zaczyna ona irytować swoimi minusami. Potem zacznie się moda na coś innego a używanie metod magicznych (nie wszystkich) zostanie uznane za przestarzałe oraz odejdzie w niepamięć jak $HTTP_GET_VARS ;)

  25. W przypadku __construct i __destruct nie jest prawdą, że to magia – a już na pewno nie jest słusznym stwierdzenie, że czarna :)

    Dzięki takiej nomenklaturze nie ma problemu ze zmianami w kodzie w przypadku refaktoryzacji nazwy klasy.

    AFAIK można też nadal nazywać konstruktor tak jak klasę, choć to dawne podejście.

    Jeśli komuś bardzo przeszkadza __construct możliwy do wywołania jako funkcja, to kiedyś pisałem o możliwym rozwiązaniu:
    http://www.yarpo.pl/2010/12/12/przeciazanie-konstruktora/

  26. PHP vs Ruby – klasy | Hello World! - pingback on 4 lipca 2011 at 08:01

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackbacks and Pingbacks:

Subscribe without commenting