Práce s čísly
Školení, která pořádám
V PHP je několik funkcí pro práci s čísly. Pro převod řetězce na číslo se používá funkce intval, použít se dá i přetypování, já mám ale raději standardní používání funkcí.
Pokud chceme zjistit, jestli je proměnná typu int, dá se použít funkce is_int. Mnohem častěji ale chceme zjistit, jestli je hodnota zadaná uživatelem do formuláře číselná – to zajišťuje funkce is_numeric. Od lidí, kteří tuto funkci neznají, jsem viděl už několik zběsilých pokusů o kontrolu čísla:
<?php
(strval(intval($_GET["plat"])) === $_GET["plat"]);
(ereg('[0-9]+', $_GET["plat"])); // to je navíc špatně, masce odpovídá např. i "a123"
(!ereg('[^0-9]', $_GET["plat"])); // podmínku splní i prázdný řetězec
(intval($_GET["plat"]) == $_GET["plat"]); // opět špatně, podmínce odpovídá např. i "12a"
?>
Jedinou rozumnou alternativou k funkci is_numeric tak zůstává méně obvyklá funkce ctype_digit, která dělá prakticky totéž (funkce is_numeric ale akceptuje i znaménko, desetinnou tečku, exponent a hexadecimální zápis). Funkce z rodiny CType tak využijeme spíše při složitějších testech, např. při testu alfanumerických znaků.
Diskuse
Michal Molhanec:
No na celá čísla není is_numeric moc dobrý, on vrátí TRUE i pro "1.1" nebo "1e2", což většinou není žádoucí, ten bych spíš používal na floaty. Na celá nezáporná pak ctype_digit. A před použitím potřepat, totiž otrimovat :-) z obou stran. Ale v reálu jsem zatím potřeboval jenom kladná (tzn. bez nuly) čísla a na ty to přetypování/intval bohatě stačí.
Leo:
Na kontrolu formularu pouzivat regexp uz jen proto, ze nemusim pro kazdy policko pouzivat jinou fci, a navic je muzu beze zmeny pouzit i v klientske kontrole v JS. A napsat regexp pro cele cislo mi opravdu uz nedela problem. Navic se regulary chovaji vsude stejne, zatimco kontrola na cislo je uplne jin v PHP a JS.
Tomáš Pokorný:
Pokud nechci z kontroly vyvozovat nejaké závěry, tak používám např.
$num=abs((int)$_POST["number"]);
U formulářů je třeba myslet na více záludnoustí:
- v našich končinách je zvykem používat desetinou čárku, zatímco PHP očekává tečku
- v čísle se může objevit mezera jako oddělovač tisíců (když třeba uživatel číslo zkopíruje z Wordu)
- a taková mezera může být i pevná (znak #160) nebo tabulátor (znak #9)
atd..
Jakub Podhorský:
to s dou desetinou čárkou a tečkou by se mělo dát nastavit pomocí setlocale() nebo se mýlím?
Leo:
Kdysi jsem s nastavenim localniho prostredi v PHP expetrimentoval, ale je to naprosta cerna magie.
Jakub Podhorský:
jen k těm regulárním výrazům:
/^[\d]$/
tohle zajistí že v tom mají být jenom čísla :) to jenom tak pro některý šílence :)
no ovsem zapis je velice nestandardni: /^\d+$/
Jakub Podhorský:
pravda...nekontroloval jsem si to :)
Diskuse je zrušena z důvodu spamu.