← Lekcje
PHP · lekcja 04

Instrukcje warunkowe 1/2: if, else, elseif

Jak skrypt podejmuje decyzję?

  1. Decyzja jako rozjazd: if i if … else
  2. Drabinka elseif i warunki złożone z &&, ||
  3. Dwie pułapki: = zamiast == i wartości „fałszywe”
  4. Ćwiczenie: ocena z procentów w grade.php
Rozgrzewka · 3 minuty

Rozgrzewka: operatory

  1. Co da "7" == 7, a co "7" === 7? Dlaczego inaczej?
  2. Jak jednym działaniem sprawdzić, czy $number jest parzyste?
  3. $age = 16; $hasTicket = true; Co da $age >= 18 && $hasTicket, a co z ||?
Warunki · if

Decyzja to rozjazd: instrukcja if

kod idzie z góry warunek $age >= 18 true echo "Wchodzisz"; false: blok pominięty dalej
$age = 20;
if ($age >= 18) {
    echo "Wchodzisz na mecz.";
}
echo "Koniec.";   // wykona się zawsze

Bramka na stadionie sprawdza bilet. Jeśli jest ważny, wchodzicie. Jeśli go nie macie, idziecie dalej, obok wejścia. if działa tak samo: w nawiasie stoi warunek, a w klamrach { } kod, który wykona się tylko przy true.

Warunkiem może być każde wyrażenie z wynikiem true albo false, na przykład porównania z poprzedniej lekcji.

PHP Manual: if · php.net/manual/en/control-structures.if.php
Warunki · if … else

Dwie drogi: if … else

$age = 16;
if ($age >= 18) {
    echo "Wchodzisz na mecz.";
} else {
    echo "Tylko z opiekunem.";
}
// wypisze: Tylko z opiekunem.
  • else to „w przeciwnym razie”: wykona się tylko wtedy, gdy warunek dał false.
  • Zawsze wykona się dokładnie jeden z dwu bloków. Nigdy oba, nigdy żaden.
  • else nie ma własnego warunku. Zapis else ($age < 18) to błąd składni.

Klamry { } piszcie zawsze, nawet przy jednej linii. PHP pozwala je pominąć, ale wtedy pod if podlega tylko pierwsza instrukcja, a druga wykona się zawsze. Kto dopisze linię do bloku bez klamer, dostaje błąd, którego nie widać.

Ciekawostka z PHP Manual: if i else mają też zapis alternatywny: zamiast { } piszecie dwukropek i kończycie słowem endif;, na przykład if ($a == 5): echo "równa się 5"; endif;. Ten zapis ułatwia mieszanie kodu PHP ze zwykłym HTML w jednym pliku.

PHP Manual: else · php.net/manual/en/control-structures.else.php · ciekawostka: PHP Manual, control-structures.alternative-syntax.php
Warunki · elseif

Drabinka: elseif

$temp > 30 ? $temp > 20 ? $temp > 10 ? else "gorąco" "ciepło" "chłodno" "zimno" falsepominiętepominięte true
$temp = 25;
if ($temp > 30) {
    echo "gorąco";
} elseif ($temp > 20) {
    echo "ciepło";      // to się wykona
} elseif ($temp > 10) {
    echo "chłodno";
} else {
    echo "zimno";
}

PHP schodzi po drabince od góry. Pierwszy prawdziwy warunek wygrywa, reszty nie sprawdza. Dlatego kolejność ma znaczenie: od największej wartości w dół.

PHP Manual: elseif/else if · php.net/manual/en/control-structures.elseif.php
Warunki · &&, || i zagnieżdżanie

Warunki złożone i if w if

$age = 20; $hasTicket = true; $isStaff = false;
if ($age >= 18 && $hasTicket) {
    echo "Wchodzisz.";
}
if ($hasTicket || $isStaff) {
    echo "Brama otwarta.";
}
if (!$hasTicket) {
    echo "Kasa jest obok.";
}
// to samo co &&, tylko w dwu krokach
if ($age >= 18) {
    if ($hasTicket) {
        echo "Wchodzisz.";
    } else {
        echo "Kup bilet.";
    }
} else {
    echo "Tylko z opiekunem.";
}

if w if to zagnieżdżanie: każda gałąź ma własny komunikat. Żeby sprawdzić dwie rzeczy naraz, krótszy jest zapis z &&. Klamry i wcięcia (4 spacje) pokazują, który else należy do którego if.

PHP Manual: if (zagnieżdżanie) · php.net/manual/en/control-structures.if.php · else (przykład „dangling else”) · control-structures.else.php · Logical Operators · language.operators.logical.php
Warunki · pułapka 1

Pułapka: = zamiast ==

$isOpen = false;
if ($isOpen = true) {   // jeden =
    echo "Sklep otwarty";
}
// wypisze: Sklep otwarty
// zawsze, choć $isOpen było false
  • = to przypisanie: $isOpen dostaje true, a wynikiem wyrażenia jest ta wartość.
  • if (true) jest zawsze prawdziwe. PHP nie zgłosi błędu: kod jest poprawny, tylko robi co innego, niż myślicie.
  • Porównanie to == (dwa znaki) albo === (trzy: wartość i typ).

Nawyk na dziś: po if piszecie ===. Trzy znaki trudno pomylić z jednym, a typ też się zgadza. Ze stałą po lewej (if (true === $isOpen)) pomyłka z = od razu daje błąd składni: do true nic przypisać nie można.

PHP Manual: Assignment Operators („wartością wyrażenia przypisania jest przypisana wartość”) · php.net/manual/en/language.operators.assignment.php · Comparison Operators · language.operators.comparison.php
Warunki · pułapka 2

Co PHP uważa za fałsz?

if (…) → false if (…) → true false null 0 0.0 "" "0" [] (pusta tablica) true -1 "0.0" " " "Ala" "false" [0] (tablica z zerem) wszystko, czego nie ma po lewej, jest prawdą
$name = "0";
if ($name) {
    echo "Cześć, " . $name;
} else {
    echo "Brak imienia";   // to!
}

W nawiasie może stać sama zmienna. PHP zamienia ją na true albo false według tabeli. Tekst "0" to fałsz, choć ma jeden znak.

Bezpieczniej porównać wprost: if ($name !== ""). Wtedy "0" to imię, a pusty tekst to brak.

PHP Manual: Booleans, „Converting to boolean” · php.net/manual/en/language.types.boolean.php
Egzamin INF.03

Tak pytają na egzaminie

1. Który z komentarzy opisuje zadanie zdefiniowanej w języku PHP funkcji?

function fun1($a, $b) {
    if($a > $b) return $a;
    elseif($b > $a) return $b;
    else return -1;
}
  1. Funkcja zwraca wartość wyższą z dwóch podanych, gdy są równe zwraca wartość -1
  2. Funkcja zwraca wartość niższą z dwóch podanych, gdy są równe zwraca wartość -1
  3. Funkcja zwraca wartość wyższą z dwóch podanych, gdy są równe zwraca wartość $a
  4. Funkcja zwraca wartość niższą z dwóch podanych, gdy są równe zwraca wartość $a

2. Program zapisany w języku PHP ma za zadanie obliczyć średnią pozytywnych ocen ucznia od 2 do 6. Warunek wybierania ocen w pętli liczącej średnią powinien zawierać wyrażenie logiczne

  1. $grade > 2 or $grade < 6
  2. $grade > 2 and $grade < 6
  3. $grade >= 2 or $grade <= 6
  4. $grade >= 2 and $grade <= 6

CKE pisze and i or: znaczą to samo co && i ||, tylko wykonują się później niż =. W warunku if różnicy nie ma; w naszym kodzie zostają && i ||. function i return znacie z JavaScript.

CKE, EE.09 styczeń 2020, zad. 11 · CKE, EE.09 czerwiec 2021, zad. 3 (bank pytań, przedmiot strony, temat php)
Ćwiczenie przy komputerze · 10 minut

Ćwiczenie 1: grade.php

  1. W folderze kursu utwórz grade.php. Na górze zmienna $percent = 72; (procent punktów ze sprawdzianu).
  2. Drabinką if … elseif … else ustaw zmienną $grade na ocenę 1–6 według progów z tabeli. Zacznij od najwyższego progu.
  3. Wypisz jedną linię: Wynik: 72% to ocena 4.
  4. Zmień $percent na 95, 39 i 55, odśwież stronę, sprawdź wyniki. Plik zostaw w folderze kursu.

Dla szybkich: dopisz pod spodem drugi if, który dla oceny 1 wypisze zdanie o poprawie.

ProcentOcena
od 95 %6
od 85 %5
od 70 %4
od 55 %3
od 40 %2
poniżej 40 %1

Progi przykładowe, do ćwiczenia. Twoja szkoła może mieć inne.

PHP Manual, control-structures.elseif.php
Ćwiczenie na kartce · 5 minut

Ćwiczenie 2: co wypisze?

Bez komputera. Zapisz wynik każdego fragmentu, potem sprawdź uruchamiając kod.

// 1.
$age = 17;
if ($age >= 18) { echo "A"; } else { echo "B"; }

Co wypisze ten kod?

// 2.
$temp = 25;
if ($temp > 30) { echo "gorąco"; }
elseif ($temp > 20) { echo "ciepło"; }
else { echo "zimno"; }

Co wypisze ten kod?

// 3.
$name = "0";
if ($name) { echo "jest imię"; }
else { echo "brak imienia"; }

Co wypisze ten kod?

// 4.
$x = 10; $y = 3;
if ($x > 5 && $y > 5) { echo "oba"; }
elseif ($x > 5 || $y > 5) { echo "jedno"; }
else { echo "żadne"; }

Co wypisze ten kod?

Pułapka jest we fragmencie 3. Kto ma 4 na 4, tłumaczy sąsiadowi, dlaczego we fragmencie 2 nie wypisze się „ciepłozimno”.

Na koniec

Sprawdź się

  1. Czym różni się else od elseif?
  2. W drabince elseif dwa warunki są prawdziwe. Które bloki się wykonają?
  3. Co wypisze if ($count = 0) { echo "zero"; } else { echo "nie zero"; } i dlaczego?

Następna lekcja: switch, match i operator ? :, czyli krótsze zapisy tych samych decyzji.

Poza szkołą

A jak to wygląda w produkcji?

Na lekcjiW produkcjiStatus
if sprawdza zmienną wpisaną w kodzieTe same if sprawdzają dane z formularza na serwerze, zawsze. Sprawdzenie w przeglądarce (JavaScript) da się obejść, więc jest tylko wygodą dla użytkownika.nadal w użyciu
if ($name)Porównanie wprost: $name !== "", $id !== null. Login „0” uznany za brak loginu to prawdziwy błąd z produkcji.skrót if ($x): unikane
if ($a == $b)W zespole ===; narzędzia sprawdzające kod (PHPStan, PHP-CS-Fixer) zgłaszają == przed połączeniem zmian.==: unikane
if w if w ifNajpierw odrzuca się złe przypadki i kończy (return), potem idzie właściwy kod. Trzeci poziom zagnieżdżenia to sygnał do przepisania.głębokie zagnieżdżanie: unikane
Progi ocen wpisane w kodProgi, limity, ceny trzyma się w konfiguracji albo w bazie. Zmiana progu to edycja ustawienia, nie nowa wersja kodu.nadal w użyciu
MDN: Client-side form validation („Never trust data passed to your server from the client”) · developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation
← → slajdy · F pełny ekran · S spis