Przejdź do głównej treści
  1. Strona główna
  2. Technik informatyk
  3. INF.03
  4. Pytanie

Kwalifikacja: INF.03 - Tworzenie i administrowanie stronami i aplikacjami internetowymi oraz bazami danych

Zawód: Technik informatyk, Technik programista

Kategorie: Programowanie webowe Algorytmy i podstawy informatyki PHP

Efektem wykonania poniższego kodu PHP jest wyświetlenie komunikatu:

$a = $c = true;
$b = $d = false;

if(($a && $b) || ($c && $d))
    echo 'warunek1';
elseif(($a && $b) || ($c || $d))
    echo 'warunek2';
elseif(($c && $d) || (!$a))
    echo 'warunek3';
else
    echo 'warunek4';

Poprawna jest odpowiedź „warunek2”, bo właśnie ten blok warunkowy jako pierwszy spełnia się dla zadanych wartości zmiennych. Rozbijmy to spokojnie na czynniki pierwsze. Na początku mamy przypisania: `$a = $c = true;` oraz `$b = $d = false;`. To oznacza, że `$a` i `$c` są logicznie prawdziwe, a `$b` i `$d` logicznie fałszywe.

Pierwszy `if` sprawdza: `($a && $b) || ($c && $d)`. Część `$a && $b` to `true && false`, więc daje `false`. Druga część `$c && $d` to `true && false`, też `false`. Cały warunek to więc `false || false`, czyli `false`. Ten blok się nie wykona.

Następnie interpreter PHP przechodzi do `elseif`: `($a && $b) || ($c || $d)`. Znowu `$a && $b` to `false`, ale teraz mamy drugą część: `$c || $d` to `true || false`, czyli `true`. Czyli cały warunek to `false || true`, czyli `true`. W tym momencie PHP wykonuje `echo 'warunek2';` i kończy sprawdzanie dalszych `elseif`/`else` – to jest bardzo ważna cecha konstrukcji `if/elseif/else`: po pierwszym spełnionym warunku reszta jest ignorowana.

Praktycznie w PHP (i w innych językach C‑podobnych) takie logiczne łączenie warunków przydaje się np. przy sprawdzaniu uprawnień użytkownika: `if(($isAdmin && $isActive) || $isSuperAdmin)`. Warto pamiętać o priorytetach operatorów `&&` i `||` oraz zawsze dodawać nawiasy, kiedy chcemy jasno zaznaczyć kolejność. Z mojego doświadczenia wynika, że jawne nawiasowanie, nawet tam gdzie nie jest konieczne, zmniejsza liczbę bugów i ułatwia czytanie kodu zespołowi.

Dobrą praktyką jest też upraszczanie złożonych warunków, np. przez wyciąganie fragmentów do osobnych, dobrze nazwanych zmiennych: `$hasBasicAccess = $a && $b; $hasExtendedAccess = $c || $d; if($hasBasicAccess || $hasExtendedAccess) ...`. Kod jest wtedy bardziej samodokumentujący i łatwiejszy w utrzymaniu.
W tym zadaniu kluczowe jest zrozumienie, jak PHP ocenia wyrażenia logiczne z użyciem operatorów `&&` i `||` oraz jak działa sekwencja `if / elseif / else`. Sporo osób gubi się tutaj przez pobieżne liczenie w głowie albo przez mylenie operatora AND z OR, albo przez nieuwzględnianie tego, że kolejne gałęzie `elseif` są sprawdzane dopiero wtedy, gdy poprzednie warunki były fałszywe.

Najpierw warto zauważyć wartości zmiennych: `$a = $c = true;` oraz `$b = $d = false;`. To oznacza po prostu: `a = true`, `c = true`, `b = false`, `d = false`. W pierwszym warunku mamy `($a && $b) || ($c && $d)`. Zarówno `true && false`, jak i `true && false` dają `false`, więc całość to `false || false`, czyli `false`. Dlatego komunikat „warunek1” nie ma prawa się pojawić – ten blok w ogóle nie jest wykonywany.

Częsty błąd polega na tym, że ktoś widzi dwa `true` w warunku i z automatu zakłada, że „coś tam pewnie wyjdzie na true”. Niestety tak to nie działa – przy operatorze `&&` wystarczy jeden `false`, żeby całe wyrażenie było fałszywe. Z kolei przy `||` wystarczy jedno `true`, by wynik był prawdziwy. I to dokładnie widać w drugim warunku: `($a && $b) || ($c || $d)`. Tu pierwsza część znów jest fałszywa, ale druga to `true || false`, więc daje `true`. Cały warunek jest więc prawdziwy i dlatego wykonuje się tylko ten blok – „warunek2”.

Jeżeli ktoś zaznaczył „warunek3” lub „warunek4”, to zazwyczaj wynika to z niezrozumienia, że po pierwszym spełnionym `if`/`elseif` dalsze nie są już w ogóle analizowane. Trzeci warunek logicznie też warto policzyć: `($c && $d) || (!$a)` to `false || false`, bo `$c && $d` to `true && false = false`, a `!$a` to `!true = false`. On byłby fałszywy nawet gdyby do niego dotrzeć, więc „warunek3” i tak by się nie wydrukował. „warunek4” z kolei to blok domyślny, wykonywany tylko wtedy, gdy wszystkie wcześniejsze warunki są fałszywe – tutaj tak nie jest, bo drugi warunek jest prawdziwy.

Z mojego doświadczenia dobrym nawykiem jest zawsze rozpisywanie takich wyrażeń krok po kroku, szczególnie na początku nauki: najpierw obliczyć `&&` wewnątrz nawiasów, potem `||`, i dopiero wtedy patrzeć, która gałąź `if/elseif/else` zostanie wykonana. W realnym kodzie przy skomplikowanych warunkach lepiej je upraszczać albo rozbijać na kilka czytelnych zmiennych pomocniczych, zamiast liczyć wszystko „w głowie”, bo to prosta droga do subtelnych błędów logicznych.

Wymagane logowanie

Ocenianie trudności pytań jest dostępne tylko dla zalogowanych użytkowników. Zaloguj się, aby skorzystać z pełni możliwości platformy.

Twoja ocena pomoże innym uczniom w przygotowaniu do egzaminu, a Tobie pozwoli na dostęp do spersonalizowanych statystyk.

Zgłoś błąd w pytaniu

Rozwiń sekcję i zmień pole, którego dotyczy błąd. Wyślemy tylko zmienione sekcje.

Błędna kwalifikacja
Błąd w treści pytania
Błąd w treści odpowiedzi
Błąd w obrazie
Dane kontaktowe (opcjonalnie)
Podaj email, jeśli chcesz otrzymać informację o rozpatrzeniu zgłoszenia.