NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 8 - Podmínky v PHP podruhé - přetypování, skládání a switch

V předchozím kvízu, Kvíz - Textové řetězce, pole a podmínky v PHP, jsme si ověřili nabyté zkušenosti z předchozích lekcí.

Ohledně podmínek platí ještě další teorie, která by vám v budoucnu mohla chybět. Nezbývá tedy než se do ní v dnešním PHP tutoriálu pustit.

Datový typ boolean

S podmínkami úzce souvisí datový typ boolean. Ten nabývá pouze dvou hodnot, a sice true (pravda) a false (nepravda). Tyto konstanty někdy bývají psány velkými písmeny. Zkusme si takovou proměnnou vytvořit:

$pozdravit = true;
if ($pozdravit == true)
    echo('Ahoj');

Kód výše se ptá, zda je v proměnné $pozdravit hodnota true. Pokud ano, program vypíše pozdrav. Hodnoty true a false se opravdu často používají u nějakého nastavení programu.

Když se podrobněji zaměříme na relační operátory v podmínkách, uvědomíme si, že vždy vracejí výsledek typu boolean (např. 5 > 2 vrátí hodnotu true). Podmínka vždy skončí u toho, že buď platí, nebo neplatí. Do podmínky můžeme typ boolean vložit rovnou bez operátoru:

$pozdravit = true;
if ($pozdravit)
    echo('Ahoj');

To, že výraz v závorce podmínky ve výsledku vrátí true nebo false, vás možná vede k otázce, zda výsledek podmínky nelze uložit do proměnné typu boolean a použít k vyhodnocení až později. Ano, je to možné:

$podminka = (15 > 3);
if ($podminka) {
    // ...
}

Porovnávání a přetypování

Již víme, že operátor == slouží k porovnání hodnot. A také víme, že PHP je dynamickým jazykem a datové typy proměnných samo převádí podle toho, jak s nimi pracujeme. K tomuto přetypování dochází i při používání podmínek. Je opravdu velmi důležité, abyste věděli, jak přetypování funguje. Jinak vás chování PHP může překvapit, nebo dokonce můžete způsobit bezpečnostní díru ve své aplikaci.

Přetypování na boolean

Pokud do podmínky zadáme proměnnou jakéhokoli datového typu, bude automaticky převedena na boolean (tedy na pravdu nebo nepravdu). Pokud jako výraz zadáme nenulové číslo, podmínka bude vždy platit, a to i pro záporná čísla:

$a = 5;
if ($a)
    echo('Platí');

U řetězců bude podmínka platit v případě, že má nenulovou délku:

$retezec = 'itnetwork';
if ($retezec)
    echo('Platí');

U polí je to podobné. Pokud v poli něco je, bude podmínka platit:

$cisla = array(1, 2, 3);
if ($cisla)
    echo('Platí');

Toto může někdy zjednodušit práci. Podmínku s číslem využijeme v případě, že číslo označuje nějaký počet. Ušetříme si > 0. S polem je to podobné, v jeho případě si ušetříme count($cisla) > 0. Řetězec zase splní podmínku jen tehdy, je-li zadaný (můžeme tak zkontrolovat, zda uživatel např. vyplnil nějaké formulářové pole).

U všech výše uvedených zápisů můžeme samozřejmě použít i negaci, např. takto:

$jmeno = '';
if (!$jmeno)
    echo('Nemůžeš mít prázdné jméno.');

Porovnávání proměnných různých datových typů

Zajímavé to začne být zejména ve chvíli, kdy při porovnávání dojde k automatické (implicitní) konverzi datového typu. To se děje zejména u čísla a řetězce.

Asi vás nepřekvapí, že když porovnáme totéž číslo jako číslo a jako řetězec, bude podmínka platit:

$a = 2;
$b = "2";
if ($a == $b)
    echo('Platí');

PHP zjistí, že na pravé straně je řetězec, a pokusí se na řetězec převést i stranu levou. Ve finále porovnává řetězec "2" s řetězcem "2", které jsou stejné.

Před verzí PHP 8 by došlo k automatickému pokusu o převod řetězce na číslo. PHP by z řetězce vydolovalo dvojku a ve finále by tedy porovnávalo opět dvě dvojky. Toto však fungovalo pouze v případě, že řetězec číslem začínal.

Při programování ve starších verzích PHP si dávejte pozor na porovnávání různých datových typů a snažte se přetypování nechat na jazyku.

Vyhnete se tak následujícím chybám:

$a = 2;
$b = "2Ahoj, jak se máš?";
if ($a == $b)
    echo('Platí'); // Provede se ve verzi PHP 7 a starší
else
    echo('Neplatí'); // Provede se ve verzi PHP 8 a novější

Do třetice si ukažme něco, co byste asi nečekali. Asi tušíte, že ve starších verzích PHP bude podmínka platit i v tomto posledním případě:

$a = 0;
$b = "Ahoj, jak se máš?";
if ($a == $b)
    echo('Platí'); // Provede se pouze ve verzi PHP 7 a starší
else
    echo('Neplatí'); // Provede se ve verzi PHP 8 a novější

Proč tomu tak bývalo? PHP zjistilo, že porovnáváme číslo s něčím jiným, a pokusilo se převést řetězec na číslo. Když se mu to nepodařilo, místo chyby prohlásilo, že výsledek je 0. A nula se přece rovná nule :)

PHP 8 však převede číslo 0 na řetězec "0", který následně porovná s řetězcem "Ahoj, jak se máš?". Tyto dva řetězce se samozřejmě nerovnají, a tak PHP vyhodnotí podmínku jako false.

Porovnávání v závislosti na typu

Pokud vám výše zmíněné chování PHP připadá poněkud divoké, máte pravdu. Někdy sice ušetří práci, ale mnohdy je lepší porovnávat v závislosti na datovém typu. To platí zejména pro textové řetězce. Pokud místo dvou rovnítek == použijeme tři (===), výraz vrátí true jen v případě, jsou-li hodnoty v proměnných opravdu stejné a mají-li stejný datový typ:

$a = 0;
$b = "Ahoj, jak se máš?";
if ($a === $b)
    echo('Platí');
else
    echo('Neplatí');

Nyní se již podmínka nesplní. Totéž by platilo i pro číslo a řetězec:

$a = 2;
$b = "2";
if ($a === $b)
    echo('Platí');
else
    echo('Neplatí');

Textové řetězce bychom měli porovnávat spíše třemi ===.

Pokud chcete v PHP porovnávat dvě proměnné, téměř vždy chcete porovnávat i jejich datové typy. Kdykoli máte pocit, že potřebujete použít pouze dvě ==, zamyslete se, zda žádná z proměnných nemůže obsahovat hodnotu, která by mohla způsobit nečekané vyhodnocení podmínky.

Skládání podmínek

Podmínky je možné skládat, a to pomocí dvou základních logických operátorů:

Operátor C-like zápis
a zároveň &&
nebo ||

 Na české klávesnici můžeme znak & napsat pomocí klávesy pravý Alt a písmene C. Znak | napíšeme taktéž pomocí klávesy pravý Alt, ale s písmenem W:

AND a OR - Základní konstrukce jazyka PHP

Uveďme si příklad. Zkontrolujme, zda je dané číslo v rozmezí 10-20:

$a = 15;
if (($a >= 10) && ($a <= 20))
    echo("Zadal jsi správně");
else
    echo("Zadal jsi špatně");

Takto bychom mimochodem mohli validovat např. věk zadaný do formuláře. To již umíme. Operátory se samozřejmě dají kombinovat pomocí závorek. Zkontrolujme, zda je číslo v rozmezí 10-20 nebo 30-40:

$a = 35;
if ((($a >= 10) && ($a <= 20)) || (($a >=30) && ($a <= 40)))
    echo("Zadal jsi správně");
else
    echo("Zadal jsi špatně");

switch

Ohledně podmínek si představme ještě konstrukci switch. Jedná se vlastně o alternativní zápis sekvence ifelse. switch (česky přepínač) umožňuje jednoduše reagovat na různé hodnoty nějaké proměnné. Ukažme si náš skript pro zpracování výpočtu kalkulačky, kde místo sekvence ifelse použijeme právě switch:

switch ($operace) {
    case 'scitani':
        $vysledek = $a + $b;
        break;
    case 'odecitani':
    case 'odcitani':
        $vysledek = $a - $b; // Příkaz se provede pro hodnotu "odecitani" i "odcitani"
        break;
    case 'nasobeni':
        $vysledek = $a * $b;
        break;
    case 'deleni':
        if ($b != 0)
            $vysledek = $a / $b;
        else
            $vysledek = 'Chyba';
        break;
}

echo("Výsledek: $vysledek");

Za klíčovým slovem switch vložíme do závorky proměnnou, jejíž hodnoty chceme opodmínkovat. Tělo switch je v bloku ze složených závorek. Jednotlivé případy označíme slovem case a za ně vložíme dvojtečku. Dále normálně píšeme příkazy, které se mají stát. Nejsou zde žádné složené závorky a příkazů zde může být více. Za posledním příkazem je vždy nutné uvést příkaz break. Můžeme také použít případ default:, který se provede tehdy, když neplatí ani jedna možnost.

Osobně konstrukce switch příliš nepoužívám. Nepřipadá mi, že něco zjednodušují, a správný programátor switch příliš často nepotřebuje. Takové bezduché větvení se v programech většinou nepoužívá, jelikož existují elegantnější a mnohem kratší zápisy, jak danou situaci řešit (třeba polymorfismem, reflexí nebo anonymními funkcemi, na ty však máme ještě hodně času :) ). Na konstrukci switch však určitě narazíte v cizích programech a dobrý PHP kurz by ji měl zmínit.

match

Od verze PHP 8 je k dispozici také konstrukce match, která je konstrukci switch velmi podobná a kterou můžeme tímto způsobem také využít. Příklad níže ukazuje přepis konstrukce switch na match:

$vysledek = match($operace) {
    'scitani' => $a + $b,
    'odecitani','odcitani' => $a - $b,
    'nasobeni' => $a * $b,
    'deleni' => ($b != 0) ? $a / $b : 'Chyba'
};

echo "Výsledek: $vysledek";

Všimněme si, že match na základě vyhodnocování podmínek, které jsou uvedeny vlevo (podobně jako klíč v asociativních polích), vrací hodnotu vpravo a předává ji proměnné $vysledek. S využitím této konstrukce se nám kód rovněž zjednodušil. Konstrukce match porovnává hodnoty, které jsou striktními datovými typy. O těch si povíme více v lekci Tvorba vlastních funkcí v PHP.

V příští lekci, Kontaktní e-mailový formulář v PHP, budeme dělat kontaktní e-mailový formulář.


 

Předchozí článek
Kvíz - Textové řetězce, pole a podmínky v PHP
Všechny články v sekci
Základní konstrukce jazyka PHP
Přeskočit článek
(nedoporučujeme)
Kontaktní e-mailový formulář v PHP
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
334 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity