Diskuze: Problém se <select>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 19 zpráv z 19.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Problém na první pohled nevidím.
Zkus u elementů select odmazat vlastnost form, přece jenom, ty select se
pod formem nachází, není potřeba tuto vlastnost definovat.
Opačný případ by nastal, pokud by daný vstup byl mimo element form.
Můžu taky vidět PHP kód, pokud v něm není uber nic tajného?
Můžeš jen tak zkusit funkci var_dump pro vypsání jakékoliv proměnné s jakoukoliv strukturou; tento kód:
var_dump($_POST);
...by měl vypsat veškerá odeslaná data metodou POST (prvky v poli $_POST).
<?php
session_start();
require('Db.php');
Db::connect('127.0.0.1', 'uzivatele', 'root', '');
if ($_POST)
{
$pohlavi = $_POST['pohlavi'];
$darek = $_POST['darek'];
if ($_POST['heslo'] != $_POST['heslo_znovu'])
{
$hlaska = 'Hesla se neshodují.';
}
elseif ($_POST['antispam'] != date('d'))
{
$hlaska = 'Nesprávně vyplněný antispam';
}
elseif ($pohlavi == 'X')
{
$hlaska = 'Zvolte pohlaví!';
}
elseif ($pohlavi == 'X')
{
$hlaska = 'Zvolte dárek!';
}
else
$existuje = Db::querySingle('
SELECT COUNT(*)
FROM uzivatele
WHERE jmeno=?
LIMIT 1
', $_POST['jmeno']);
if ($existuje) {
$hlaska = 'Uživatel s touto přezdívkou již existuje, zvolte prosím jinou.';
}
else
{
$ip = $_SERVER['REMOTE_ADDR'];
$pohlavi = $_POST['pohlavi'];
$posledni_prihlaseni = date('Y-m-d');
Db::query('
INSERT INTO uzivatele(jmeno, email, heslo, vek, pohlavi, zasilat_novinky, ip, posledni_prihlaseni)
VALUES(?, ?, SHA1(?), ?, ?, ?, ?, ?)
', $_POST['jmeno'], $_POST['email'], $_POST['heslo'] . "123789", $_POST['vek'], $pohlavi, $_POST['novinky'], $ip, $posledni_prihlaseni);
header('Location: administrace/administrace.php');
exit();
}
}
?>
Zde je tedy php.
Ahoj,
není problém v tom, že máš v PHP kódu 2x definovanou proměnou $pohlavi (i
když nabývá stejné hodnoty $_POST['pohlavi'])? (máš ji hned nahoře a v
posledním else). Zkus tu poslední odmazat.
Má ji 2x definovanou, ale v oddělených blocích (jiná scope).
Ty proměnné jsou platné v rozsahu těch bloků, nikoli ven (pokud je mi
známo).
To mi připadá celkem divný.
Zkus se mrknout na to pole $_POST pomocí funkce var_dump (jak jsem psal),
uvidíš co se na server odesílá, ať můžeme vyloučit, jestli se jedná o
problém na frontendu nebo backendu.
Provedl jsem var_dump. Select to skutečně neodesílalo. Změnil jsem value v selectech na idčka (čísla)
<option value="1">Option 1</option>
<option value="2">Option 2</option>
a už se to odesílá
Jo, to je pravda, akorát nešlo by to udělat nějak, že tam nebudou IDčka ?
právě, že to nemá oddělené.... první proměnná je platná po provedení $_POST a druhá je platná až při posledním else... a jak se provede poslední else, tak se vyskytne podruhé (i když nabude stejné hodnoty).
Ještě jednou jsem si to pořádně prohlédl a problém bude v tom, že máš ve value diakritiku (muž/žena). To samé i v tom druhém selectu.
Udělej si to spíše nějak takto:
HTML
<select name="pohlavi">
<option value="">Zvolte pohlaví</option>
<option value="m">Muž</option>
<option value="z">Muž</option>
</select>
a PHP kontrolu nějak takto:
if ($_POST['pohlavi'] == "m") {$pohlavi = "Muž" ;}
elseif($_POST['pohlavi'] == "z") {$pohlavi = "Žena" ;}
else {$hlaska = "Zvolte pohlaví!" ;}
Spíš bys měl se zaměřit ještě na to, abys nevypisoval chybové hlášky po jedné, ale zkontrolovat údaje (Případně vypsat všechny chyby) a pak uložit do DB.
//Varování, goin' off-topic
Vždycky to tak bylo.
Jestliže se proměnná definuje v bloku, který je zapsaný složenými závorkami (funkce, podmínka, switch), není přístupná mimo ten blok.
Navíc... je to podmínka, jeden blok kódu se spustí v jednom případě,
druhý v případě opačném.
Jestliže definici proměnné odmaže v jednom z bloků, a používá ji tam,
nezáleže na okolnostech mu tam bude chybět (ledaže by ji definoval před
podmínkou).
Spusť si tento kód:
<?php
$condition = true;
if($condition){
echo "var_dump before definition, condition=true:";
var_dump($var);
$var = "test";
echo "var_dump after definition, condition=true:";
var_dump($var);
}
else{
echo "var_dump before definition, condition=false:";
var_dump($var);
$var = "test";
echo "var_dump after definition, condition=false:";
var_dump($var);
}
?>
Proměnná $var bude před její definicí VŽDY null, nezáleží na podmínce!
ANO... ty to máš dobře, ale koukni se tedy důkladně na jeho kód...
<?php
if ($_POST) {
$pohlavi = $_POST['pohlavi'] ;
if (...) {
...
}
else
if (...) {
...
}
else {
$pohlavi = $_POST['pohlavi'];
}
}
?>
Odmazal jsem ostatní kód, abys viděl jak to tam má špatně napsané.
Máte pravdu vlastně oba. Děkuji za pomoc. Ještě se mám, co učit.
Tak když si to tak hezky přiznal, zkusím ti napsat funkční řešení (jak to dělám já):
Tvé HTML kapku poupravené:
<form class="form-control-static col-lg-offset-4" method="post" name="registrovat" action="administrace/scripty/registracescr.php">
<div class="form-group">
<label for="jmeno">Jméno</label><br />
<input name="jmeno" type="text" class="form-control-static col-sm-5" id="jmeno" required="required"><br /><br />
</div>
<div class="form-group">
<label for="email">Email</label><br />
<input name="email" type="email" class="form-control-static col-sm-5" id="email" required="required"><br /><br />
</div>
<div class="form-group">
<label for="heslo">Heslo</label><br />
<input name="heslo" type="password" class="form-control-static col-sm-5" id="heslo" required="required"><br /><br />
</div>
<div class="form-group">
<label for="heslo_znovu">Heslo znovu</label><br />
<input name="heslo_znovu" type="password" class="form-control-static col-sm-5" id="heslo_znovu" required="required"><br /><br />
</div>
<div class="form-group">
<label for="vek">Věk</label><br />
<input name="vek" type="number" min="1" max="100" class="form-control-static col-sm-5" id="vek" required=required><br /><br />
</div>
<div class="form-group">
<select name="pohlavi" form="registrovat" class="bg-warning form-control-static col-sm-5">
<option value="">Zvolte pohlaví!</option>
<option value="m">Muž</option>
<option value="z">Žena</option>
</select><br /><br />
</div>
<div class="form-group">
<select name="darek" form="registrovat" class="bg-warning form-control-static col-sm-5">
<option value="">Zvolte dárek na uvítanou</option>
<option value="body">50 bodů</option>
<option value="vip">VIP na den zdarma</option>
</select><br /><br />
</div>
<div class="form-group">
<label for="antispam">Kolikátého dnes je? - den(Antispam)</label><br />
<input name="antispam" type="text" class="form-control-static col-sm-5" id="antispam" required="required"><br /><br />
</div>
<label for="novinky">Zasílat novinky</label>
<input name="novinky" type="checkbox" value="Ano" checked="checked"><br /><br />
<input type="submit" name="registrovat" value="Registrovat se" class="btn btn-default btn-warning col-sm-5" style="outline: none;">
</form>
Pak tedy PHP kód nad stránkou s HTML
<?php
$chyby = array() ;
if (isset($_POST['registrovat'])) {
if (empty($_POST['jmeno'])) {$chyby[] = 'Pole jméno je prázdné! Zadejte jméno.' ;}
$existuje = Db::querySingle('SELECT COUNT(jmeno) FROM uzivatele WHERE jmeno = ? LIMIT 1', $_POST['jmeno']) ;
if ($existuje) {$chyby[] = 'Uživatel s tímto jménem již existuje! Zadejte jiné jméno.' ;}
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {$chyby[] = 'Email nemá správný tvar! Zadejte správný email.' ;}
if ($_POST['heslo'] != $_POST['heslo_znovu']) {$chyby[] = 'Hesla se neshodují! Zadejte heslo a heslo znovu.' ;}
if (empty($_POST['vek'])) {$chyby[] = 'Pole věk je prázdné! Zadejte Váš věk.' ;}
if ($_POST['vek'] < 1 || $_POST['vek'] > 100) {$chyby[] = 'Věk musí být v rozsahu od 1 do 100. Zadejte Váš věk.' ;}
if ($_POST['pohlavi'] == 'm') {$pohlavi = 'Muž' ;}
elseif ($_POST['pohlavi'] == 'z') {$pohlavi = 'Žena' ;}
else {$chyby[] = 'Nebylo zvoleno pohlaví! Zvolte Vaše pohlaví.' ;}
if ($_POST['darek'] == 'body') {$darek = '50 bodů' ;}
elseif ($_POST['darek'] == 'vip') {$darek = 'VIP na den zdarma' ;}
else {$chyby[] = 'Nebyl zvolen dárek! Zvolte dárek na uvítanou.' ;}
if ($_POST['antispam'] != date('d')) {$chyby[] = 'Nevyplnil/a jste správně antispamovou otázku! Zadejte antispamovou otázku (Kolíkáteho dnes je? - den)'}
if (count($chyby) == 0) {
Db::query('INSERT INTO uzivatele (jmeno, email, heslo, vek, pohlavi, zasilat_novinky, ip, posledni_prihlaseni) VALUES (?, ?, SHA1(?), ?, ?, ?, ?, ?)',
$_POST['jmeno'], $_POST['email'], $_POST['heslo']."123789", $_POST['vek'], $pohlavi, $_POST['novinky'], $_SERVER['REMOTE_ADDR'], date('Y-m-d')) ;
header('Location: administrace/administrace.php');
exit() ;
}
}
?>
A nakonec někam do stránky umístit výpis případných chyb (já je dávám do odrážkového seznamu):
<?php
if (isset($chyby) && count($chyby) > 0) {
echo '<ul>' ;
foreach ($chyby as $chyba) {
echo '<li>'.$chyba.'</li>'
}
echo '</ul>' ;
}
?>
Nevím jak tam máš řešen ten dárek, ale ten předpokládám, že jsi schopen si tam už dodělat.
Psal jsem to narychlo, tak snad tam nejsou nějaké veliké chyby. Kdyby náhodou, tak dej vědět a kouknu na to.
Jak píšeš v tom php to, co se stane, když není pole vyplněno - není náhodou lepší použít v html to required ?
V HTML to máš také, ale nemůžeš na to spoléhat... přes F12 v prohlížeči to required můžu smazat a tím pádem odešlu formulář i s nevyplněnou hodnotou. Musíš to ošetřovat i v PHP.
Ještě jsem si vzpomněl na jednu vychytávku... aby při chybové hlášce
uživatel nemusel vyplňovat znovu všechny údaje, tak je dobré udělat k tomu
inputu následující value:
Příklad na jméno:
<label for="jmeno">Jméno</label><br />
<input name="jmeno" type="text" value="<?php if(isset($_POST[jmeno])) {echo $_POST['jmeno'] ;} ?>" class="form-control-static col-sm-5" id="jmeno" required="required"><br /><br />
Mimochodem podle původního kódu by hláška o dárku nikdy nepřišla
elseif ($pohlavi == 'X')
{
$hlaska = 'Zvolte pohlaví!';
}
elseif ($pohlavi == 'X')
{
$hlaska = 'Zvolte dárek!';
}
Zobrazeno 19 zpráv z 19.