> **Poznámka:** Tento článek může být pro některé začátečníky mírně chaotický, protože předpokládá základní znalosti o PHP. Pokud vás zajímá, jak podmínky fungují, přečtěte si o podmínkách v začátečnickém kurzu.
Podpora: | Všechny verze: PHP 4, PHP 5, PHP 7 |
---|---|
Stručný popis: | Kontrola platnosti jednoho nebo více výroků |
Typ: | Příkaz, konstrukt (není funkce) |
Často je potřeba zjistit, zda platí nějaká rovnost nebo zda je výrok pravdivý, k tomu slouží podmínky. PHP používá jako mnoho jiných jazyků (zejména jazyk C) následující syntaxi:
if (/* logický výrok */) {// konstrukt}
Každý logický výraz má hodnotu TRUE
(pravda) nebo FALSE
(nepravda), jiné možnosti nejsou.
Příklad porovnání, zda je proměnná $x
větší než proměnná $y
:
$x = 10;$y = 5;if ($x > $y) {// Tato část scriptu se spustí, pokud podmínka platí} else {// Tato část scriptu se spustí, pokud podmínka neplatí}
Konstrukt podmínky má povinný obsah v kulaté závorce, ve které se uvádí testovaný výraz, složený z operátorů (přehled níže), více výrazů lze propojit pomocí logických operátorů (přehled níže).
Dále podmínka obsahuje dva nepovinné bloky příkazů.
Z praktických důvodů se vždy uvádí minimálně první blok příkazů, kdy podmínka platí, jinak by totiž testování výrazu nedávalo smysl.
Všeobecně platí, že:
Jediný možný zápis se středníkem (vyjma použití konstruktu endif):
if ($x > $y);
Taková podmínka však nemá smysl, protože v obou případech bude výsledek porovnávání zahozen a nespustí se žádný příkaz patřící k podmínce.
Za určitých okolností lze využít konstrukt if
s vynecháním složených závorek. Toho můžeme dosáhnout jen v těchto případech:
Pro podrobnější informace vizte následující 3 kapitoly.
1. Jen jeden příkaz ~ zkrácená syntaxe
Pokud vytváříte podmínku, ve které chceme provést jen jeden konstrukt (příkaz), tak můžeme použít buď klasický zápis se složenou závorkou:
if ($x > 10) { $y = $x; }
Nebo můžeme závorky vynechat:
if ($x > 10) $y = $x;
Toto chování se však týká jen jednoho příkazu v bezprostřední blízkosti podmínky.
Lepší příklad (podmíněně se provede jen konstrukt $y = $x
, zbytek vždy):
$x = 5;$y = 3;$z = 10;if ($x > $y)$y = $x;$x = 3;
2. Dvojtečka a endif;
if (/* výraz */):konstrukt;konstrukt;konstrukt;endif;
Tento zápis je však dlouhodobě považován za zastaralý, protože snižuje v orientaci při zanoření více podmínek do sebe samotných.
Poznámka: Rád bych poznamenal, že tento styl mají rádi také někteří lidé, například Yuhů (více v jeho článku). Chraň vás ruka páně tohle někde použít.
3. Ternární výraz ~ jednořádkový "in-line" zápis
Občas se hodí provést jednoduché porovnání v rámci jednoho řádku s nějakou jinou akcí (například společně s definováním nové proměnné). Pokud chceme provést jen jeden příkaz, tak lze celý postup zkrátit na jeden jediný řádek i při zachování maximální jednoduchosti.
$x = 5;$isBiggerThanTwo = ($x > 2 ? true : false);// nebo ještě kratší:$isBiggerThanTwo = ($x > 2);// nebo bez závorek:$isBiggerThanTwo = $x > 2;
V rámci podmínky se používají dva typy operátorů:
Operátor | Význam |
---|---|
== |
Rovná se |
=== |
Rovná se a má stejný datový typ |
!= |
Nerovná se |
>= |
Rovná se nebo je větší |
<= |
Rovná se nebo je menší |
> |
Větší |
< |
Menší |
Příklad (platí, když $x není 5
):
if ($x != 5) { ... }
Operátor | Alternativa | Význam | Pravda, když: |
---|---|---|---|
&& |
AND | a zároveň | jsou obě hodnoty pravdivé |
` | ` | OR | |
^^ |
XOR | exlusive OR | je aspoň jedno pravda nebo nepravda, ale nikdy ne oboje |
! |
nemá | negace výrazu | true když bylo false a naopak |
() |
nemá | zanoření výrazů | záleží na okolnostech |
Složitější příklad:
$x = 5;$y = 3;$z = 8;if ($x > 0 && !($y != 2 && $z == $x) || $z > $y) { ... }
Často si můžeme dovolit vynechat některý z operátorů (nebo dokonce i oba), nikdy ale nesmíme zapomenout na pravidla správného použití, aby výsledný výraz fungoval.
Všeobecně platí, že při testování výrazu bez operátoru se zkouší, zda je jeho hodnota TRUE
, nebo je neprázdná (například obsahuje nenulové číslo, neprázdný řetězec, ...).
Příklady:
$x = 5;$y = 3;$z = 8;if ($x) { ... } // vyhoví, protože $x není prázdnéif ($x && $y) { ... } // vyhoví, protože $x a $y není prázdnéif (!$x) { ... } // nevyhoví, protože TRUE je negovánoif (isset($z)) { ... } // vyhoví, protože proměnná $z existuje
Mohou ale nastat zrádné situace, zejména když:
if ($x)
a proměnná $x
obsahuje nulu (0
), pak podmínka není splněna.$x
obsahuje řetězec '0'
(číslo nula), protože se přetypuje na nulu a výraz tedy není pravda.'false'
jako string, pak opět podmínka platí, protože řetězec není prázdný.Na toto doporučuji jedno jednoduché a účelné řešení - ptát se na počet znaků, které se vrací. Pokud je řetězec prázdný (nebo proměnná neexistuje), tak se vrátí nulový počet znaků a podmínka není splněna. Jednoduchý příklad:
$x = '0';if ($x) { ... } // podmínka za běžných okolností neplatíif (strlen($x)) { ... } // podmínka platí, protože $x obsahuje 1 znak
Dále můžeme testovat existenci proměnné funkcí isset()
.
Zjistit, že jsou řetězce shodné, je jednoduché:
$a = 'Kočka';$b = 'kočka';if ($a === $b) {// Pokud jsou řetězce stejné} else {// Pokud jsou řetězce různé}
Důležité je správně ohlídat datové typy v případě, že by mohl být zápis ekvivaletní k nějakému jinému.
Například prázdný řetězec $a = '';
je něco jiného, než řetězec NULL
: $b = NULL;
. Rozlišovat to musíme například kvůli databázím, kde je rozdíl mezi tím, že hodnota neexistuje, nebo je prázdná.
$a = '';$b = null;if ($a == $b) {// Bude vyhodnoceno jako TRUE, protože// dojde k převodu datového typu.}if ($a === $b) {// Provede mnohem přísnější validaci// a neprojde, protože jde o jiný// obsah a jiný datový typ, proto se// tento kód nikdy nespustí.}
Dále je při porovnávání řetězců dobré zanedbat bílé (neviditelné) znaky, jako jsou mezery, tabulátory a odřádkování. To se hodí například při zadávání hesla a předání do hashovací funkce:
$password = '81dc9bdb52d04dc20036dbd8313ed055'; // 1234$userPassword = ' 1234 ';if (md5(trim($userPassword)) === $password) {// Funkce trim() provede automatické odmazání mezer.}
Někdy se může stát, že hodnota neexistuje (není tedy TRUE
ani FALSE
), jde zejména o hodnotu získanou z databáze (například se ptáme na sloupec, který neexistuje), v takovém případě bude vrácen datový typ NULL
.
Obecně se NULL
vyhodnocuje jako FALSE
, tj. podmínka neplatí. Toto chování ovšem nemusí být vždy výhodné, protože neexistující hodnota ještě nemusí nutně znamenat, že neexistuje záznam.
Příklad z praxe: Máme uživatelský profil a ptáme se na webovou stránku uživatele. Ne všichni uživatelé musí mít webovou stránku, v takovém případě se tedy vrátí
NULL
, ale uživatel i přesto existuje. V tomto případě bychom tedy měli spíše použít funkciisset()
, abychom otestovali (ne)existenci proměnné a nedělali závěr na základě konkrétní hodnoty.
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Nabízím trénink vývojářů, konzultace, školení a analýzu návrhových vzorů. Osobně v Praze nebo online.
Napište mi, pokud si nevíte rady.
Lektor: Jan Barášek
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | cs