Autor | Zpráva | ||
---|---|---|---|
Jcas Profil |
Doufám, že se na mě nebude nikdo zlobit, když si založím tyto poznámky. Samozřejmě se jedná o chyby, které vznikly nedostatečným, nebo nepozorným čtením manuálu, či návodu (opomenutí či vynechání jedné důležité věty). Nicméně jsem je udělal a tak je možné, že je udělá i někdo jiný. Třeba mu to poslouží. A třeba to poslouží jako zpětná vazba tvůrcům návodů.
Špatně zpracované data z formuláře.- chyba může vzniknout díky existenci-neexistenci$_POST
<form method="post"> <select name="test"> <option>jedna</option> <option>dva</option> <option>jiná</option> </select> <input type="submit" value="odeslat" name="enter"> </form> $_POST['test'] bude mít vždy nějakou hodnotu.
Výchozí hodnota je první volba. isset($_POST['test']); // true empty($_POST['test']); //false // zpracování // kontroluje jak odeslání, tak i jestli byla vybrána hodnota 'jiná' if($_POST['test'] != 'jiná') {....} else {.....} Pokud ovšem obalíme <option> do <optgroup> , Tak tato kontrola je nedostatečná.
Při <optgroup> není vybrána výchozí položka. A pokud nevybereme - hodnota se neodešle. Nyní jsou tedy možné 3 možnosti. - uživatel nevybere nic a odešle form - uživatel vybere 'jiná' - uživatel vybere jinou položku, než je 'jiná' <form method="post"> <select name="test" size="5"> <optgroup> <option>jedna</option> <option>dva</option> </optgroup> </select> <input type="submit" value="odeslat"> // pokud nevybere nic isset($_POST['test']); // false empty($_POST['test']); //true // toto zpracování neodhalí situaci, kdy uživatel nic nevybral a odeslal formulář. if($_POST['test'] != 'jiná') {....} // zde bude i situace, kdy nevybral nic. else {.....} var_dump() - vypsání proměnnéPotřeba pozorně číst návody. Je pravda, že uvar_dump jsem učebnici php nečetl a četl jsem se svou lámavou angličtinou pouze manuál. O hodnotě NULL jsem tam nic nepřečetl. (nebo přešel, nebo přehlédl)
Výše zmíněný problém jsem nemohl odhalit, protože jsem si vypsal: var_dump($_POST['test']); // vrátilo NULL a já žil v přesvědčení, že $_POST['test'] == null;
Takže pozor. Pokud není inicializovaná proměnná, tak var_dump vrací NULL!!! Ovšem totéž platí, pokud nepřiřadíme aspoň něco. $x; var_dump($x); // NULL |
||
jenikkozak Profil |
#2 · Zasláno: 22. 6. 2014, 12:41:21
Jcas:
„Pokud ovšem obalíme <option> do <optgroup> “
Problém není způsobený použitím značkou <optgroup> , ale atributem size prvku <select> ve druhém uvedeném příkladu. Dá se vyřešit použitím atributu selected u výchozí položky.
PHP je v tomto nevinně. Záleží na prohlížeči, které položky odešle. |
||
Jcas Profil |
#3 · Zasláno: 22. 6. 2014, 12:52:13
jenikkozak:
Lze se na to spolehnout? Lze se spolehnout na to, že když nepoužiju selected, tak se při 'nevybrání položky' $_POST['test'] neodešle? |
||
Jan Tvrdík Profil |
#4 · Zasláno: 22. 6. 2014, 12:53:39
Jcas:
V selectu je vždy nějaká položka vybraná. |
||
Jcas Profil |
#5 · Zasláno: 22. 6. 2014, 12:58:51
Jan Tvrdík:
[#1] Jcas Tohle mi ukázalo, že to není pravda. |
||
Jan Tvrdík Profil |
#6 · Zasláno: 22. 6. 2014, 13:06:36
Jcas:
Špatně jsem si to přečetl. Nicméně <select> se size jinou než 1 stejně nikdy nepoužívej. Je to pro uživatele děsně matoucí. Nelze vizuálně poznat, jestli je to multiple nebo ne. Po označení nějaké položky nejde vybrat nic.
|
||
jenikkozak Profil |
#7 · Zasláno: 22. 6. 2014, 13:13:17
Co se týká toho druhého příkladu, je v něm zřejmě chyba v měření - prohlížeče (pokud vím) posílají prvky
hidden i text stejně, a proto je PHP stejně vyhodnocuje.
|
||
Jcas Profil |
#8 · Zasláno: 22. 6. 2014, 13:21:53 · Upravil/a: Jcas
jenikkozak:
jj, máš pravdu. Znova jsem testoval. Musel jsem někde udělat chybu. I skryté pole bez value odešle "". jenikkozak: [#3] Jcas. Odpověď na toto? Asi ne. Závěr - použití <select> Vždy pomocí selected nastavit výchozí hodnotu. Potom není třeba testovat existenci $_POST['select'] , ale pouze vybranou hodnotu.
|
||
Jan Tvrdík Profil |
#9 · Zasláno: 22. 6. 2014, 16:57:17
Jcas:
„Potom není třeba testovat existenci $_POST['select'] “
Tak testovat existenci je potřeba vždy, zlý uživatel ti může poslat libovolný HTTP požadavek, tedy libovolné položky mohou chybět, nebo můžou mít hodnotu, kterou nelze normálně vybrat. |
||
Jcas Profil |
#10 · Zasláno: 22. 6. 2014, 20:05:51
Pozn. II: empty vz issetNeexistují proměnou vnímáempty jako prázdnou. Je to logické. Když něco neexistuje, tak to nemůže obsahovat nějakou hodnotu.
1. existuje && je prázdná: isset==true, empty==true 2. existuje && není prázdná: isset==true, empty==false 3. neexistuje && je prázdná: isset==false, empty==true 4. neexistuje && není prázdná: isset==false, empty==true Situace 3. a 4. je blbost. Pokud něco neexistuje, nemůže to nabývat hodnot "prázdná-plná" Nicméně vypsání všech 4 možností mi ukázalo jednu jedinou situaci, kdy empty je schopna identifikovat situaci. Proto lze v jednom případě použít empty i pro kontrolu existence. if(isset($_POST['něco']) && !empty($_POST['něco'])) {...příkazy...} // lze zkrátit if(!empty($_POST['něco'])) {...příkazy...} |
||
rafej Profil |
#11 · Zasláno: 23. 6. 2014, 03:22:51
Jcas:
> Proto lze v jednom případě použít empty i pro kontrolu existence. > > > > if(isset($_POST['něco']) && !empty($_POST['něco'])) {...příkazy...} > // lze zkrátit > if(!empty($_POST['něco'])) {...příkazy...} Nebude ti to fungovat, pokud má kontrolované pole hodnotu false nebo 0. |
||
Jcas Profil |
#12 · Zasláno: 24. 6. 2014, 06:43:49
rafej:
Musím říct, že jsem ještě nezažil situaci, kdy bych chtěl zpracovávat z odeslaného formuláře 0 nebo false. Spíš absolutně nemám zkušenosti s podstrčením něčeho zákeřným uživatelem a proto se mi těžko odhalují tyto bezpečnostní chyby. Druhá ukázka, kdy vynechávám testování existence (isset) a nechám to celé na empty .
if(isset($_POST['enter')) { //testuji pouze zda byl formulář odeslán, nebo ne // odhalí jak situaci, kdy nějaká $_POST neexistuje, tak i jestli je prázdná if(empty($_POST['new_zvire']) || empty($_POST['new_skupina']) || empty($_POST['new_plemeno'])) { $hlaska[] = 'Vyplňte prosím všechna pole pro nové zvíře!'; } else { // všechna tři existují && jsou vyplněna ...příkazy... } } |
||
anonymníí Profil * |
#13 · Zasláno: 24. 6. 2014, 09:38:08
Jcas:
„Musím říct, že jsem ještě nezažil situaci, kdy bych chtěl zpracovávat z odeslaného formuláře 0 nebo false.“ Ne? To jsi toho zažil málo :-) Počet dětí: 0. Dopravné: 0. Třeba. „Spíš absolutně nemám zkušenosti s podstrčením něčeho“ Nepotřebuješ vědět, jak se podstrkává, důelžité je vědět, že kde čekáš jedničku (nebo v horším případě číslo), můžeš dostat cokoliv. |
||
Jcas Profil |
Poznámka III. Podmínka if vs vrácené hodnoty z funkcí.Dřív mi některé souvislosti nedocházeli moc rychle. Většinou jsem je odhaloval chybami. Kupodivu dnes (při častém opakováním všeho) už mi něco docvakne hned. Dnes jsem po dlouhé době koukal na použití strpos() v podmínce if .
Prakticky hned mi došlo, že když strpos() vrací false , nebo číslo (int) , tak že by se podmínce to int nemuselo líbit a také, že vrácenou 0 (výskyt na prvním místě) bude chápat jako false . Řešení jsem nehledal a měl jsem ho hned.
if(is_int(strpos($str, '-'))) Ale protože jsem si chtěl ověřit, jak to s tou podmínkou je, tak jsem znova začal pátrat. A ejhle - opět se mi potvrdilo, že vím houby. Potvrdil se můj předpoklad, že if očekává hodnoty true-false .
viz: "Očekává se, že hodnota nebo výsledek výrazu určující splnění podmínky bude typu boolean (logická hodnota)." Očekával bych od PC chování ve stylu: if('string') If('string') ??? a co jako? Je roven něčemu? Nebo existuje? Nebo co? Trhni si nohou - podmínka nesplněna.
Jenže ono to tak není. A php mi to hned ukázalo, když si samo proměnnou přetypovalo. Konec konců, je to napsané zde Takže jsem si udělal testík: $str = '-string'; $vys = strpos($str, '-'); //int(0) $vys2 = strpos($str, 's'); //int(1) $vys3 = strpos($str, 't'); //int(2) // int 1 a větší se sám přetypuje na true. if($vys) {echo '$vys prošlo<br>';} //false if($vys2) {echo '$vys2 prošlo<br>';} //true if($vys3) {echo '$vys3 prošlo<br>';} //true // String se přetypuje také if('0') {echo '"0" prošlo<br>';} //false if('str') {echo 'str prošlo<br>';} //true if($vys==0) {echo '== 0 prošlo<br>';} //true if($vys===0) {echo '=== 0 prošlo<br>';} //true if($vys=='0') {echo '== "0" prošlo<br>';} //true if($vys==='0') {echo '=== "0" prošlo<br>';} //false if(is_int($vys)) {echo 'is_int prošlo<br>';} //true if(is_int(strpos($str, ':'))) {echo 'is_int neprošlo<br>';} //false Trochu mě ale trápí ten "warning" v manuálu na použití === . Chápu rodíl mezi == a === a chápu, že tím varováním chcou upozornit na to, že i když očekávám vrácenou hodnotu, tak může být vyhodnocena jako false, protože je vrácena 0.
Ale nechápu, proč je řešení ve === . Když budu chtít zjistit, jestli je vráceno "něco", nebo false, tak mi to nepomůže a použiju něco jak is_int() .
A pokud chci testovat, jestli je vrácena nula, tak projde jak if($vys==0) , tak i if($vys===0) .
A proč bych vrácený int testoval jak řetězec, abych musel testovat i typ?
|
||
juriad Profil |
#15 · Zasláno: 24. 6. 2014, 22:39:39
Jcas:
Podmínkou s rovností == nejsi schopen odlišit nulu od false: $x = false; if ($x == 0) { echo "False == 0\n"; } $y = 0; if ($y == false) { echo "0 == False\n"; } Funkce is_int ti bude fungovat, ale je to takové přes ruku. Když chceš testovat, že je něco false, tak se přece neptáš, zda to není celé číslo. |
||
Jcas Profil |
juriad:
Když chceš testovat, že je něco false,... AHA. Zatím co když funkce vrací bool: true a false a já jsem zvyklí, že mohu testovat obojí: if(true), if(!true), if(false), if(!false) $str = '-string'; $vys[] = strpos($str, '-'); //int(0) $vys[] = strpos($str, 's'); //int(1) $vys[] = strpos($str, 'b'); //false foreach($vys as $var) { if($var==false) { echo $var.' == false<br>';} if($var===false) { echo $var.' === false<br>';} if($var!=false) { echo $var.' != false<br>';} if($var!==false) { echo $var.' !== false<br>';} } /* 0 == false 0 !== false 1 != false 1 !== false == false === false */ |
||
Časová prodleva: 7 dní
|
|||
Jcas Profil |
#17 · Zasláno: 2. 7. 2014, 00:43:11
Poznámka IV - moduloPoprvé jsem na to narazil zde.Zbytek po dělení je ještě snadné pochopit. 4/2=2 a zbytek není žádný. 4/3=(zaokr.)1. Trojka se do čtyřky vleze pouze jednou a zbude 1. 3+1=4 7/3=(zaokr.)1. Trojka se vleze do sedmičky 2* a zbude jedna. 7-3*2=1 a 3*2+1=7 Aplikovat vzorec je také snadné. Co byl trochu můj problém (než jsem si udělal ukázku) bylo pochopit. Jak se to chová. Jak a kdy to aplikovat. K čemu takový výledek je a co nám vlastně takový výsledek prozradí. A předevčírem mě dostalo toto. [pre] <img src="http://fakeimg.pl/200x130/282828/eae0d0/?text=Slon" id="obrazek2"> <br> <a href="#" onclick="return zmena('obrazek2',[');">Zaměnit</a]http://fakeimg.pl/200x130/282828/eae0d0/?text=Slon','http://fakeimg.pl/200x130/282828/eae0d0/?text=Pes','http://fakeimg.pl/200x130/282828/eae0d0/?text=Potkan']);">Zaměnit</a> function zmena(id, obrazky) { var obrazek = document.getElementById(id); var index = obrazky.indexOf(obrazek.src); index = (index + 1) % obrazky.length; obrazek.src = obrazky[index]; return false; } Takže mi to nedalo a udělal jsem si tabulku, abych vlastně viděl, co nám takový zbytek po dělení dokáže ukázat. To co jsem nemohl pochopit je najednou krásně vidět. Jak se nám krásně opakují cykly 0.1.2.3 a 0.1.2.3 (jak 4 prvky pole) https://docs.google.com/spreadsheets/d/1T3o06T8mOJjTA5g0pBVT-uboD_5cHUYnD8Z29FIVaZ0/edit?usp=sharing |
||
juriad Profil |
Modulo se používá v několika situacích:
1) Při posunech skrz pole - pokud jsi na konci a jdeš doprava, chceš se objevit na začátku a to samé na opak. To se obvykle zapisuje jako: $novyIndex = ($staryIndex + $posun + $delka) % $delka „When either a or n is negative, the naive definition breaks down and programming languages differ in how these values are defined.“ (wiki) To přičtení nevadí neboť (A+B)%C = (A%C + B%C)%C a pokud B=C , pak B%C=0 , a tedy je to celé rovné (A%C)%C = A%C .
2) Při periodickém provádění nějaké úlohy, třeba výpis třídy ke každému n-tému prvku tabulky. Pak stačí podmínka if ($x % $n == 0) {...} for ($i = 0; $i < 1000000; $i++) { do_something_hard(); if ($i % 1000 == 0) { # výpis jednou za 1000 iterací, aby to nezaplavilo log. echo "zpracováno $i prvků\n"; } } 3) Občas máš k dispozici generátor náhodných čísel, který generuje náhodné číslo v rozsahu 0 až 2^64 - 1. Ale ty chceš náhodné číslo v rozsahu 1 až 6 pro simulaci kostky. Jak na to? Napřed chceme náhodné číslo v rozsahu 0 až 5 a to si následně posuneme přičtením jedničky. $kostka = random() % 6 + 1 4) Některé celočíselné datové struktury využívají toho, že libovolné celé číslo lze vhodně rozložit. V případě van Emde Boasova stromu s kapacitou N se vyjádří každý prvek jako A = B * sqrt(N) + C , kde C < sqrt(N) ; tento rozklad lze spočítat takto: B = A / sqrt(N) a C = A % sqrt(N) .
Je to základem struktury, která umožňuje extrémně rychlé operace s množinou: přidej prvek, smaž prvek, existuje prvek?, předchůdce, následník prvku vše v čase log log N (zlogaritmuj kapacitu a pak ji zlogaritmuj znovu). Toto v praxi asi nikdy nepotkáš :-)
Lepší než říkat zaokrouhlit je říct zakrouhlit dolů nebo říct celá část. |
||
Jcas Profil |
#19 · Zasláno: 2. 7. 2014, 19:10:09
Super vysvětlivky, to nemá chybu.
|
||
Časová prodleva: 9 let
|
0