Předávání polí z formuláře

Školení, která pořádám

Dopsal jsem knihu

V HTML formulářích lze pomocí atributu <select multiple> vytvořit menu, ve kterém je možné vybrat více položek. Pokud však uživatel skutečně vybere víc položek, naplní PHP proměnnou odpovídající názvu menu pouze poslední vybranou hodnotu. Tento problém se dá řešit pomocí předávání polí z HTML formulářů. Je to velice jednoduché – za hodnotu názvu pole stačí doplnit [] (tedy např. <select name="volby[]">) a PHP z takovýchto formulářových prvků vytvoří pole.

Tento obrat se samozřejmě dá použít u libovolných formulářových prvků, výborně se hodí např. u přepínačů. S využitím vlastnosti, že hranaté závorky nemusí být prázdné, lze šikovně vytvořit i hromadnou editaci více položek v jednom formuláři:

<?php
if (is_array($_POST["nazev"])) {
    foreach ($_POST["nazev"] as $key => $val) {
        mysql_query("UPDATE tabulka SET nazev = '$val' WHERE id = '$key'");
    }
}

$result = mysql_query("SELECT id, nazev FROM tabulka");
while ($row = mysql_fetch_assoc($result)) {
    echo "<input name='nazev[$row[id]]' value=\"" . htmlspecialchars($row["nazev"]) . "\" /><br />\n";
}
mysql_free_result($result);
?>
Jakub Vrána, Výuka, 24.6.2005, diskuse: 28 (nové: 0)

Diskuse

ikona Milan Kryl:

Jen v RSS by to chtělo převádět < na &lt; atd., misto select multiple se mi ve FeedDemonu objevil inputbox ;)
# 24.6.2005 08:25:09 reagovat

ikona Jakub Vrána:

Já bych spíš řekl, že to je chyba čtečky. < na &lt; samozřejmě převedené je, ale čtečka se snaží vnitřek <description> interpretovat jako HTML, což by podle mého názoru neměla: "<description> - a plain text description of an item" (http://my.netscape.com/publish/formats/rss-…#description)
# 24.6.2005 08:33:40 reagovat

T3RMiX:

Škoda, že tenhle článek nevyšel před týdnem. Odhaloval jsem v kódu chybu a jediný co mě tam nedávalo smysl proč mam v name u selectu []. Čímž jsem si zavařil na další půlhodinu hledání, když jsem to elegantně odstranil :) Stejnak dík, mrzí mě že takových blogů není víc :(
# 24.6.2005 08:47:20 reagovat

Leo:

Problem je jinde - nejsem si jisty, jestli podle specifikace (X)HTML muze byt v hodnote name hranata zavorka, ale skoro urcite ne. Pak musite zpracovavat hruby vstup do PHP, co je u POSTu mirne slozitejsi nez u GETu, ale jde to. Vic manual PHP (promenne z formularu). Leos Ondra

# 24.6.2005 09:05:54 reagovat

ikona dgx:

doplním, že jde o parsování file_get_contents('php://input'), což je vychytávka od verze PHP 4.3.0 - http://www.php.net/wrappers.php

# 24.6.2005 10:18:41 reagovat

ikona dgx:

...a nebude fungovat při enctype="multipart/form-data"
# 24.6.2005 10:49:28 reagovat

ikona spaze:

zajimavy je, ze ale validator(.w3.org) nijak neprotestuje na name="foo[]" jak v HTML 4.01 trans, tak v XHTML 1.0 strict.
# 24.6.2005 10:39:35 reagovat

Leo:

Vychazel jsem z tohohle:

http://www.w3.org/TR/html4/types.html#type-cdata

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

Leo
# 24.6.2005 13:57:31 reagovat

Leo:

Mozna je to tak, ze validator to kontroluje jen proti DTD a pokud jsem to pochopil, tak DTD povolene znaky v name a id neresi. Leo
# 24.6.2005 15:37:29 reagovat

Leo:

Konkretne

http://www.php.net/manual/cs/language.variables.external.php

a zvlast komentare dole, Leo
# 24.6.2005 10:07:47 reagovat

ikona spaze:

ano, takze podle vseho [] je v poradku ;)
protoze name je CDATA, viz ty odkazy, ktere uvadis.
# 27.6.2005 14:34:56 reagovat

Gimli2:

Input se zjevil i v RSS ctecce v Opere 8.0. A chybel tam pote link primo na clanek. (bylo nutne zobrazit primo kod hlavicky prispevku v RSS)
# 24.6.2005 14:18:28 reagovat

ikona Jakub Vrána:

V tom případě to prosím nareportujte autorům Opery. To bych pravděpodobně musel vypisovat &amp;lt;, což nechci, protože ve slušných čtečkách by se to zobrazilo jako &lt;.
# 24.6.2005 14:27:01 reagovat

Andrew:

Abilon dělá to samé, tedy zobrazí prvek, ale nemá už problémy s dalšími věcmi (jako linky atd.)
# 25.6.2005 09:08:28 reagovat

Michal Molhanec:

ono u toho rss 0.9x neni uplne jednoznacny, jak je to s HTML v description, proto je IMHO mnohem lepsi pouzivat 2.0, kde je to jasne dany
# 26.6.2005 16:45:17 reagovat

ikona llook:

Validní to sice není (znaky [] v NMTOKEN), ale koho to zajímá, když to funguje.
Přesto si myslím, že multiple select by se neměl používat. Zkuste se optat několika běžných uživatelů, jak označí několik položek. Radši spoustu checkboxů ve scrollovacím boxíku.

Mimochodem ty entity si na značky převádí snad většina čteček, včetně těch webových. Jednou jsem do titulku napsal <table> a několika agregátorům jsem dočasně rozhodil layout :-)
# 24.6.2005 20:36:29 reagovat

ikona dgx:

používám to v admin. rozhraních, které obsluhují "poučení" uživatelé. Tam je to výhoda.
# 29.6.2005 17:53:02 reagovat

Leo:

"Validní to sice není (znaky [] v NMTOKEN), ale koho to zajímá, když to funguje."

Ja jenom nerad pro jednu technologii prznim jinou :-) Leo
# 24.6.2005 22:07:30 reagovat

Tomáš:

Já nevím, ale podle mě je u všech formulářových prvků atrbibut name typu CDATA a ten přece může pbsahovat [], ne?
# 27.6.2005 01:55:42 reagovat

Tomáš:

Jo a při každém odeslání přízpěvku mi zůstane Opera vyset a stránka se nenačte, i když přízpěvek se odešle, musím se ale ručně vrátit na článek. Nevíte, někdo v čem je problém?
# 27.6.2005 02:04:24 reagovat

ikona Jakub Vrána:

Problém se mi podařilo reprodukovat, ale nezjistil jsem příčinu. V Opeře je volba "Enable automatic redirection", ale ta je defaultně zapnutá a měl jsem ji zapnutou i já.

Možná to bude souviset s opravou chyby http://secunia.com/advisories/15423/?
# 27.6.2005 11:14:55 reagovat

ikona spaze:

me to dela taky. A delalo to i v 8.0, ve statusbaru zustane "Completed request to php.vrana.cz" a to je vse.
# 27.6.2005 14:24:25 reagovat

ikona dgx:

Už jsem na to asi přišel - odstraň z redirectu hash (tedy #a-text-za-nim)
# 29.6.2005 18:03:52 reagovat

ikona Jakub Vrána:

Díky za radu, v Opeře jsem to vypnul, ale smysl tohoto omezení mi moc jasný není.
# 29.6.2005 18:35:54 reagovat

ikona spaze:

pokud je to redirect pres Location: pak je smysl uveden v RFC, #anchor do teto hlavicky nepatri. Nicmene staci jej uvest do "puvodni" hlavicky, priklad:

form action="uloz.ext#sem"
uloz.ext: Location: stav.ext a klient by mel skocit na stav.ext#sem
# 30.6.2005 18:19:36 reagovat

ikona Jakub Vrána:

Díky za objasnění, zase jsem se něco nového dozvěděl.

Problém je v tom, že kotvu se dozvím, až když zprávu uložím, takže bych to musel vyřešit trochu jinak:

článek: <form action="diskuse.php#new">
diskuse.php: <?php header("Location: $url?new=$id"); ?>
článek: <?php if ($id == $_GET["new"]) echo "<a name='new'></a>"; ?>
# 30.6.2005 18:28:25 reagovat

Zdeněk Bouška:

Toto rešení však v Opeře nefunguje, pokud je URL v hlavičce Location stejné jako URL článku.
# 7.10.2005 13:19:24 reagovat

ikona spaze:

A nějakej nápad, jak to fixnout/obejít?
# 10.6.2006 02:16:03 reagovat

Vložit příspěvek

Používejte diakritiku. Nelze používat HTML značky, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

© 2005-2010 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.