7. díl - Podmínky v PHP podruhé - přetypování, skládání a switch

PHP Základní konstrukce Podmínky v PHP podruhé - přetypování, skládání a switch American English version English version

V minulém dílu seriálu tutoriálů se základy PHP jsme si představili konstrukci if a else. Také jsem si ukázali relační operátory a rozšířili naši kalkulačku. Okolo podmínek je ještě nějaká teorie, která by vám do budoucna chyběla. Nezbývá, než se do ní pustit.

Datový typ boolean

S podmínkami úzce souvisí datový typ boolean. Ten nabývá pouze dvou hodnot a to true (pravda) a false (nepravda). Někdy bývají tyto konstanty 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, vypíše pozdrav. Hodnoty true a false se opravdu často používají u nějakého nastavení programu.

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

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

Pokud výraz v závorce podmínky vrátí ve výsledku true nebo false, možná vás napadlo, zda jde výsledek podmínky uložit do proměnné typu boolean a použít ho 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 je PHP 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 funguje. Jinak vás chování PHP může překvapit nebo dokonce způsobíte 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:

$s = 'devbook';
if ($s)
        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é, tam si ušetříme count($cisla) > 0. Řetězec zas splní podmínku jen tehdy, když je 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:

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 dojde při porovnávání 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 to samé číslo jako číslo a jako řetězec, bude podmínka platit:

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

PHP zjistí, že je na levé straně číslo a pokusí se na číslo převést i stranu pravou. Zde se mu to podaří. Ve finále porovnává číslo 2 a číslo 2, které jsou stejné.

Možná si vzpomínáte, že PHP je poměrně aktivní (až moc) a snaží se převést typy za každou cenu. Podmínka v příkladu níže stále platí, i když by to už mohlo někoho zaskočit:

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

PHP vydoluje z řetězce dvojku a ve finále tedy porovnává zas dvě dvojky. Aby toto fungovalo, musí číslem řetězec začínat.

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

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

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

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

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

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

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

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

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

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 ||

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ý z formuláře. To již umíme. Operátory se pomocí závorek samozřejmě dají kombinovat. 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

Abychom podmínky dobrali, představme si ještě konstrukci switch. Jedná se vlastně o alternativní zápis sekvence if...else. 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 if...else použijeme právě switch:

switch ($operace)
{
        case 'scitani':
                $vysledek = $a + $b;
                break;
        case 'odcitani':
                $vysledek = $a - $b;
                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 switche 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 je nutné vždy uvést příkaz break. Můžeme také použít případ default:, který se provede tehdy, když neplatí ani jedna možnost.

Osobně switch příliš nepoužívám. Nepřijde mi, že něco zjednodušuje a správný programátor ho příliš často nepotřebuje. Ono se takové bezduché větvení v programech většinou nepoužívá, jelikož jsou elegantnější a mnohem kratší zápisy, jak danou situaci řešit (třeba polymorfismem, reflexí nebo anonymními funkcemi, ale na to máme ještě hodně času :) ). Určitě na switch ale narazíte v cizích programech a dobrý seriál by ho měl zmínit. Příště budeme zas dělat něco praktického a to kontaktní emailový formulář.


 

  Aktivity (4)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (16 hlasů) :
4.93754.93754.93754.93754.9375


 


Miniatura
Předchozí článek
Cvičení k 6. lekci PHP
Miniatura
Všechny články v sekci
Základní konstrukce jazyka PHP
Miniatura
Následující článek
Kontaktní emailový formulář v PHP

 

 

Komentáře
Zobrazit starší komentáře (2)

Avatar
Petr Nymsa
Redaktor
Avatar
Petr Nymsa:

myslím že hledáš is_numeric / is_string

Odpovědět  +1 16.11.2013 17:04
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
relycanx
Člen
Avatar
Odpovídá na Petr Nymsa
relycanx:

jojo, to je ono, děkuju :) už jsem se dogooglil

 
Odpovědět 17.11.2013 2:03
Avatar
Jan Demel
Redaktor
Avatar
Jan Demel:

Čus lidi. Mám takový problém. Řekl jsem si, že se vrhnu do PHPčka no ale v momentě, kdy tohle otevřu v mém prohlížeči a ukáže se mi konečné echo s výsledkem, tak tam je špatné kódování a ukáže se mi "VĂ˝sledek" ... Prosímvás pomohli by jste mi, co s tím mám dělat ? V editoru (Notepad++) mám nastevené kódování na UTF-8 v prohlížeči také a na HTML taky ... Tak vážně nevím, kde je problém.

index.php

<!DOCTYPE html>
<html>
        <head>
                <title>První test</title>
                <meta charset="UTF-8">
        </head>
        <body>
                <form method="POST" action="odesli.php">
                        <input type="text" name="cislo1"><br>
                        <input type="text" name="cislo2"><br>
                        <select name="moznost">
                                <option>Sečti</option>
                                <option>Odečti</option>
                                <option>Vynásob</option>
                                <option>Vyděl</option>
                        </select>
                        <input type="submit" value="Odešli">
                </form>
        </body>
</html>

odesli.php

<?php
mb_http_output( "UTF-8" );
$cislo1 = $_POST["cislo1"];
$cislo2 = $_POST["cislo2"];
$moznost = $_POST["moznost"];


$vysledek = 0;

switch($moznost)
{
        case 'Sečti':
                $vysledek = $cislo1 + $cislo2;
                break;
        case 'Odečti':
                $vysledek = $cislo1 - $cislo2;
                break;
        case 'Vynásob':
                $vysledek = $cislo1 * $cislo2;
                break;
        case 'Vyděl':
                $vysledek = $cislo1 / $cislo2;
}

echo("<h3>Výsledek je: $vysledek</h3>");
?>
Odpovědět 27.12.2013 14:53
To co se zdá být nemožné, je vždy možné.
Avatar
Kit
Redaktor
Avatar
Odpovídá na Jan Demel
Kit:

Zkus to tomu prohlížeči říct:

<?php
header('Content-Type: text/html; charset=UTF-8');
Odpovědět  +1 27.12.2013 15:05
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Jan Demel
Redaktor
Avatar
Odpovědět 27.12.2013 15:11
To co se zdá být nemožné, je vždy možné.
Avatar
asanos
Člen
Avatar
asanos:

Chtěl bych upozornit na problém s && a AND ... Kdy jak už bylo zmíněno, každá má jinou prioritu.
Nedávno jsem řešil problém s menší úlohou a pokoušel jsem se o co nejrychlejší zápis (úloha byla časově omezená).

Velmi zjednodušeně jsem se dostal k:

$a=true;
$b=false;
// $c=$a AND $b;
$c=$a && $b;

Kdy při operátoru AND se provedlo přiřazení a výsledek byl tudíž TRUE,
zatímco && fungoval dle očekávání a vrátil se mi výsledek porovnání => FALSE.
_____________
Tento kód slouží jako ukázka takhle proboha neprogramujte!!! :D

Editováno 8.10.2014 14:25
Odpovědět 8.10.2014 14:25
Na světě je 10 typů lidí. Ti, kteří rozumí binárce a ti co nerozumí.
Avatar
Rasťo Suchovský:

asanos, trošku som testoval (asi 5 minút), a dospel som k tomuto:

$e = true and false;
$f = true && false;
echo("<br />E = $e<br />F = $f");
$g = false and true;
$h = false && true;
echo("<br />G = $g<br />H = $h");

E = 1
F =
G =
H =

 
Odpovědět 25. ledna 23:54
Avatar
Rasťo Suchovský:

asanos, už som to pochopil.

$a = true && false;    //false
$b = true and false;   //true

Je to preto, lebo operátor 'and' má nižšiu prioritu ako operátor '=' (a '=' má nižšiu prioritu ako '&&')

Takže druhý riadok môžeme zapísať takto:

($b = true) and false;

To znamená, že do $b sa uloží hodnota 'true' a potom sa vykoná "($b = true) and false", ktoré sa už neukladá nikam (teda aspoň som to tak pochopil).

To isté funguje aj pri '||' a 'or', keďže operátor 'or' má nižšiu prioritu ako operátor '=' (a '=' má nižšiu prioritu ako '||')

$a = false || true;    //true
$b = false or true;   //false

lebo

($b = false) or true;   //false

;)
Toto som sa práve naučil. :)

 
Odpovědět 26. ledna 0:19
Avatar
1Pupik1989
Člen
Avatar
Odpovídá na Rasťo Suchovský
1Pupik1989:

http://php.net/…ecedence.php

Jen pro doplnění přehled priorit. Já nikdy nepřišel k čemu by mě "and" a "or" byly. :D

 
Odpovědět 26. ledna 12:01
Avatar
Rasťo Suchovský:

No ja som nováčik, ktorý sa práve chystá na 8. diel. :)
Tiež vždy používam && a ||.
C# ovládam základy trochu, takže odtiaľ čerpám, keďže jazyky sú si podobné. :)
A potom google, samozrejme.

 
Odpovědět 26. ledna 14:35
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 12. Zobrazit vše