This post comes from the first version of this blog.
Please send me an email if anything needs an update. Thanks!

PHP jest językiem programowania, w którym znajduje się wciąż sporo magii, niezależnie od tego, jak czysty kod chcielibyśmy pisać. Czasem jest to magia wprowadzona przez samych twórców interpretera, czasem jednak jej źródło wypływa z innego niż zwykle wykorzystania prostych mechanizmów języka. W dzisiejszym wpisie chciałbym wyjaśnić działanie jednego z przypadków, z jakim styka się praktycznie każdy początkujący programista PHP, a każdy zaawansowany na pewno kilka razy widział jego wykorzystanie w “profesjonalnie” napisanej aplikacji internetowej.

Logika: Short-circuit evaluation.

Na początku chciałbym przypomnieć nieco podstawowe informacje dotyczące operacji logicznych i łączenia warunków. Otóż, w przypadku kiedy chcemy połączyć dwa warunki wykorzystując operator OR ("||"), tablica prawdy dla takiego wyrażenia będzie wyglądała następująco:
1
2
3
4
5
6
7
A || B

A B =
0 0 0
0 1 1
1 0 1
1 1 1

Widzimy, że dla każdej (poza dwoma fałszami) kombinacji wartości operacja zwraca wartość 1, czyli prawdę. Nas w tym przypadku interesują dwa najniżej położone wiersze, a więc te, w których element “A” jest ewaluowany do wartości 1.

W tym miejscu widać już wyraźnie, że wartość całego wyrażenia jest prawdziwa niezależnie od tego, jaki jest wynik drugiego elementu. I tu jest zawarta cała sztuczka - kompilatory i interpretery różnych języków programowania optymalizują działanie takiego wyrażenia, pomijając sprawdzenie wartości logicznej drugiego elementu, jeśli pierwszy zwróci “prawdę”. Tego typu interpretacja wyrażeń logicznych ma swoją nazwę, jest to tzw. “Short-circuit evaluation” lub “McCarthy evaluation”.

Być może nie jest to wiele, ale zawsze jedna instrukcja do przetworzenia mniej. A co, jeśli drugim elementem byłaby bardzo “ciężka” obliczeniowo funkcja zwracająca wartość typu logicznego? Dostajemy w prezencie całkiem niezły zysk wydajnościowy. ;]

PHP: Konstrukcja "or die()".

Mając na uwadze powyższe wyjaśnienie teoretyczne można domyślić się już, na jakiej zasadzie działa opisywana konstrukcja. Najpopularniejszy (pod względem pojawiania się w różnego typu poradnikach dla początkujących) sposób jej wykorzystania to połączenie z funkcją mysql_query():
1
2
$query = "SELECT field1, field2 FROM table WHERE id = 3";
$resource = mysql_query($query) or die("Cannot execute SELECT query.");

W tym przypadku funkcja mysql_query() będzie próbowała wykonać przekazane do niej zapytanie. Jeśli uda się jej poprawnie wykonać, zwróci wartość typu resource, która zostanie potraktowana jako logiczna prawda. W przeciwnym przypadku zostanie zwrócona wartość false.

Jeśli wartością wynikową funkcji będzie prawda, dalszy kod za operatorem “or” zostanie zignorowany. Jeśli zaś będzie to fałsz, skrypt zakończy działanie, wypisując na ekran ciąg znaków wprowadzony w jej parametrze.

Podsumowanie.

W tym miejscu należy też wspomnieć, że używanie konstrukcji "or die()" do sygnalizowania błędu wykonania naszego kodu jest złym pomysłem. Najpoważniejszy i bezpośredni skutek zastosowania tego rozwiązania jest to, że zakończy on działanie w sposób natychmiastowy (nie ma możliwości "złapania" zakończenia działania skryptu, poza bardzo "eksperymentalnym" register_shutdown_function()). O wiele lepiej jest rzucić wyjątek, który w łatwy sposób możemy "złapać" i poprawnie obsłużyć, nawet, jeśli jego obsługa ma polegać na zakończeniu skryptu. ;]

Mam nadzieję, że powyższe wyjaśnienia wyklarowały znaczenie konstrukcji “operacja or operacja”, dzięki czemu przy kolejnym spotkaniu z nią nie będziecie mieli problemów z intencjami autora kodu.