Utolsó frissítés: 2012.02.13.
Facebook Twitter iWiW MySpace Digg Delicious Google bookmarks Startlap Windows Live

Űrlapok feldolgozása II.

Szükséges előismeret: Alapok rész 1-18 lecke

Az űrlapelemek közül a nyomógomb (<input type="button"> és <button></button>) és a reset típusúakkal nem tudunk adatot továbbítani, így azokkal most nem is foglalkozunk, a fájlfeltöltő mezővel pedig csak akkor, ha már tudjuk kezelni a feltöltött fájlokat.

text, password és textarea

A maradék űrlapelemek közül az egysoros szövegbeviteli mező (text), a jelszóbeviteli mező (password) és a többsoros szövegmező (textarea) kezelése a legegyszerűbb. A text és a password esetén a $_POST asszociatív tömbnek az űrlapelem name paraméterével megegyező kulcsú elemébe kerül a beírt szöveg, vagyis az űrlapelem value értéke. Pl:

	<input type="text" name="cim" value="szöveg" />      =>  $_POST["cim"] = "szöveg"
	<input type="password" name="pwd" value="valami" />  =>  $_POST["pwd"] = "valami"

Az elem value paramétere az, ami bele van írva az űrlap elküldésekor. A textarea a PHP szempontjából teljesen azonos, itt a két teg közötti szöveg továbbítódik:

	<textarea name="megjegyzes">Ez egy hosszabb szöveg!</textarea>  =>
	$_POST["megjegyzes"] = "Ez egy hosszabb szöveg!"

A textarea-ban lévő sortörések "\n" karakterekként továbbítódnak, vagyis ha például azt írtuk bele, hogy Kiss Géza úgy, hogy a két szó közé egy sortörést raktunk, akkor

$_POST["megjegyzes"] = "Kiss\nGéza"

kerül a tömbbe. Ha a feldolgozó oldalon ki szeretnénk íratni például a textarea-ba írt szöveget, akkor a "\n" karaktereket <br /> tegekre kell cserélni, feltéve ha úgy szeretnénk kiíratni, ahogy a felhasználó beírta. Ekkor jól jöhet az str_replace() függvény.

str_replace()

A függvény egy karakterlánc belsejében egy adott részláncot (minden előfordulási helyén) lecserél egy másikra. Három paramétere van: a részlánc, amit le akarunk cserélni, amire le akarjuk cserélni, és a karakterlánc, amiben keressük a részláncot. Magát a karakterláncot a függvény változatlanul hagyja, a lecserélt változatot visszatérési értékként adja vissza. Példa:

$kiirando = str_replace("\n", "<br />", $_POST["megjegyzes"]);

Ez a fenti problémát oldja meg, a $_POST["megjegyzes"] karakterláncot adja vissza úgy, hogy minden \n helyén <br /> van.
Fontos megjegyezni, hogy a textarea által küldött karakterláncban csak azokon a helyeken vannak \n sortörések, ahova a felhasználó a begépeléskor szándékosan odarakta. Ugyanis a textarea szélessége miatt a szöveg automatikusan tördelve látszik, de a továbbított karakterláncra ez nincs hatással.

radio, select és submit

Egy rádiógomb-csoport (azonos name paraméterű radio elemek) és egy legördülő menü (select) a PHP szemszögéből teljesen egyenértékű. Mindkét elem esetében több lehetőségből legfeljebb egyet tudunk kiválasztani. Ha az egyik elem ki van választva, akkor az űrlapelem name paraméterével megegyező kulcsú $_POST tömbelembe kerül a kiválasztott űrlapelem value paramétere. Például:

	<input type="radio" name="allat" value="1" /> egér
	<input type="radio" name="allat" value="2" checked="checked" /> majom
	<input type="radio" name="allat" value="3" /> tetű
	=>
	$_POST["allat"] = "2"

	<select name="zoldsegek">
		<option value="zoldseg1">káposzta</option>
		<option value="zoldseg2">zeller</option>
		<option value="zoldseg3" selected="selected">retek</option>
	</select>
	=>
	$_POST["zoldsegek"] = "zoldseg3"

A checked és selected paraméterekkel az oldal betöltődésekor kiválasztott elemet tudjuk megadni, de természetesen annak a value értéke kerül a $_POST tömbbe, amelyiket a felhasználó kiválasztotta. Ha nem adunk meg alapértelmezetten kiválasztott elemet, akkor select esetén az első option elem van kiválasztva, rádiógomb esetén viszont egyik se. Utóbbi esetben nem jön létre a megfelelő $_POST változó, a fenti esetben például $_POST["allat"] = null lesz. Így ha rádiógombok esetén nem adunk meg alapértelmezett elemet, akkor érdemes a feldolgozó kódban egy isset($_POST["allat"]) vizsgálatot (vagy hasonlót) végezni.
Ha a submit gombot megnyomjuk, akkor (amennyiben adtunk neki name paramétert) a name paraméterével megegyező kulcsú $_POST tömbelembe bekerül a value paramétere. Ez azért jó, mert így egyetlen feltételvizsgálattal ellenőrizni tudjuk, hogy az űrlap el lett-e küldve vagy sem. Erre mindenképp szükség van akkor, ha a feldolgozó kód ugyanabban a fájlban van, mint az űrlap. Ha például a submit gomb ilyen:

<input type="submit" name="elkuldve" value="Küldés" />

akkor így tudjuk leellenőrizni, hogy az űrlap el lett-e küldve:

	if (isset($_POST["elkuldve"])){
		//feldolgozás
	}

Így az űrlapot csak akkor próbáljuk meg feldolgozni, ha a felhasználó már elküldte.

checkbox és multipleselect

A jelölőnégyzet (checkbox) és a többsoros legördülő menü (multipleselect) valamivel bonyolultabb mint az eddigi elemek, mivel itt azonos name paraméterű űrlapelemek közül többet is kiválaszthatunk. A multipleselect alatt most olyan select elemet kell érteni, aminek a size paramétere 1-nél nagyobb, és meg van adva a multiple paraméter is. Ez a két fajta űrlapelem egyébként a PHP kód szempontjából szintén egyenértékű. Nézzünk például egy checkbox-csoportot:

	<input type="checkbox" name="nyelv" value="html" /> HTML
	<input type="checkbox" name="nyelv" value="css" /> CSS
	<input type="checkbox" name="nyelv" value="php" /> PHP

Ha a másodikat és a harmadikat bepipáljuk (vagy adunk nekik checked="checked" paramétert) és elküldjük az űrlapot, akkor a $_POST["nyelv"] értéke "php" lesz, hiába jelöltük be a css-t is. Ha mindegyik adatot továbbítani akarjuk, akkor a name paraméterben jelezni kell, hogy tömbként kívánjuk továbbítani az értékeket. Ezt a legegyszerűbben így tehetjük meg:

	<input type="checkbox" name="nyelv[]" value="html" /> HTML
	<input type="checkbox" name="nyelv[]" value="css" /> CSS
	<input type="checkbox" name="nyelv[]" value="php" /> PHP

Miután elküldtük az űrlapot, létrejön a $_POST["nyelv"] változó, ami azonban most egy tömb, és tartalmazza az összes bepipált checkbox value paraméterét. A tömb indexelése 0-tól indul és egyesével nő, így bejárhatjuk egy egyszerű ciklussal, de használhatjuk a foreach szerkezetet is:

	for ($n = 0; $n < count($_POST["nyelv"]); ++$n){
		print $_POST["nyelv"][$n];
	}
	//ezzel egyenértékű:
	foreach ($_POST["nyelv"] as $nyelv){
		print $nyelv;
	}

Mivel a $_POST["nyelv"] maga is egy tömb, az elemeire a kód 2. sorában látható módon kell hivatkozni (ld. Alapok 17. lecke, bővebben az Alapok 19. leckében). A tömbindexeket egyébként le is rögzíthetjük, ha a name paramétert például name="nyelv[0]" formában adjuk meg, de ekkor már csak a foreach-el járhatjuk be, mert nem tudhatjuk előre, hogy melyik indexű lesz bepipálva és melyik nem, így checkboxok esetén nem sok értelme van. Az itt elmondottak ugyanígy alkalmazhatóak multipleselect elemek esetén is:

	<select name="gyumolcs[]" size="3" multiple="multiple">
		<option value="alma">Alma</option>
		<option value="korte">Körte</option>
		<option value="barack">Barack</option>
		<option value="banan">Banán</option>
	</select>

A kiválasztott elemek feldolgozása pedig pontosan ugyanúgy történik, mint a checkboxok esetén.
Néha előfordul, hogy egy magányos checkboxot hozunk létre, vagyis az adott name paraméterrel csak egy checkbox rendelkezik (például az űrlap végén néha szokott lenni olyasmi, hogy elfogadom a feltételeket, vagy hasonló). Ilyenkor fölösleges tömböt létrehozni, ha a felhasználó bepipálta, akkor a feldolgozó kódban létezik a változó az adott value értékkel, ha nem pipálta be, akkor nem.

	<input type="checkbox" name="elfogad" value="1" /> Elfogadom a feltételt
	if (isset($_POST["elfogad"])){
		//feldolgozás
	}
	else{
		print "Mégis hogy gondolod azt, hogy nem fogadod el?";
	}

A változó értékét is meg lehet vizsgálni az isset() használata helyett, de ekkor érdemes a === operátort használni, hogy biztosra menjünk.
Előfordulhat olyan eset, amikor célszerű nem checkbox vagy multipleselect típusú elemek által küldött értékeket is tömbként elküldeni. Például nézzük az alábbi űrlapot:
Telefonszám: / -
Ha például a feldolgozó oldalon össze szeretnénk rakni az így átküldött karakterláncokat, akkor kényelmesebb lehet, ha tömbként küldjük át:

	<input type="text" name="tel[0]" value="+36" />
	<select name="tel[1]">
		<option value="20">20</option>
		<option value="30">30</option>
		<option value="70">70</option>
	</select> /
	<input type="text" name="tel[2]" value="" /> -
	<input type="text" name="tel[3]" value="" />

A feldolgozó oldalon így egyszerűbben tudjuk összerakni:

	$telefonszam = "";
	foreach ($_POST["tel"] as $tel){
		$telefonszam .= $tel;
	}

Persze a legegyszerűbb, ha csak egy beviteli mezőt rakunk ki, de sokszor fontos lehet a felhasználó kényelme, meg így valószínűbb, hogy olyan formában írja be a telefonszámot, ahogy azt mi szeretnénk.

Post és Get metódus

Ha egy php fájlnak változókat (adatokat) szeretnénk továbbítani, akkor ennek az egyik módja, ha elküldünk neki egy űrlapot. Most megnézünk egy másik módszert is, hogy megérthessük valamilyen szinten a form teg method paraméterét, a használatára majd egy későbbi leckében nézünk példát. A php fájlra mutató link (URL) is tartalmazhat információkat, amit az adott fájl hasonlóan tud használni, mintha űrlapon kapta volna. Legyen a php fájl neve feldolgozo.php! Ezt megnyithatjuk például úgy, hogy a böngésző erre szolgáló sorába beírjuk az elérési útját. Ha linket (<a> teg) készítünk hozzá, akkor ott ugyanezt kell beírni a href paraméter után (annyi különbséggel, hogy utóbbi esetben ralatív elérési utat is használhatunk). Mindkét esetben az alábbi módon írva az elérési utat, változókat tudunk átadni:

.../feldolgozo.php?nev=Valaki&jelszo=nemtudom

Ebben az esetben a feldolgozo.php oldalon az alábbi két változó jön létre:

	$_GET["nev"] = "Valaki"
	$_GET["jelszo"] = "nemtudom"

Látható, hogy az URL végére egy ? után írhatjuk a változók listáját név=érték formában, az egyes változókat pedig & jelekkel választjuk el. Ha a változók értékeiben szerepelnek ékezetes betűk vagy írásjelek, akkor előbb kódolnunk kell az értéket az urlencode() függvénnyel, majd így kell továbbítani. Például:

	$nev = urlencode("Hörb");
	$email = urlencode("example@example.com");
	$url = "feldolgozo.php?nev=".$nev."&email=".$email;
	print '<a href="'.$url.'">link</a>';

Ezután a feldolgozó kódban az urldecode() függvénnyel tudjuk dekódolni a kapott kriksz-krakszot:

	$nev = urldecode($_GET["nev"]);
	$email = urldecode($_GET["email"]);

Tehát ebben az esetben a $_GET asszociatív tömbbe kerülnek a továbbküldött változók. Akkor is ez történik, ha űrlapot használunk, és a form tegbe method="get" paramétert írunk. Adatokat tehát kétféle módon továbbíthatunk: post vagy get metódussal. Utóbbi esetben a feldolgozó oldalon az űrlapelemek adatai is a $_GET tömbbe kerülnek, és megjelennek az URL-ben is (vagyis látszódni fognak a böngésző címsorában). Egyébként nem érdemes űrlapot get metódussal küldeni, mert ezzel néhány kilobájt adatot lehet csak továbbítani, post metódussal viszont elvileg akármennyit.
Get metódust inkább csak az URL-ben szoktak használni. Például sok dinamikus oldal (köztük ez is) olyan, hogy az összes menüpontja az index.php-re mutat, hogy éppen melyik menüpontot kell megjeleníteni, azt az utána átadott változók határozzák meg. Az index.php-nek ebben az esetben az a dolga, hogy a kapott $_GET változók alapján elindítsa a megfelelő kódot, ami az adott menüpont tartalmát megjeleníti.

Házi feladat

Készítsd el az alábbi űrlapot:

Név:
Megjegyzés:
Háziállatok: Kutya    Macska    Rágcsáló    Egyéb
Nem:
  Elfogadom a feltételeket
 

A feldolgozó kód legyen ugyanebben a fájlban, és úgy működjön, hogy ha nem pipálja ki a felhasználó elküldés előtt az "elfogadom a feltételeket" checkboxot, akkor jelenjen meg egy figyelmeztető üzenet. Ha bepipálja, akkor írjuk ki a továbbított adatokat. Próbáljuk meg úgy megoldani, hogy ha nem pipálja be a checkboxot, ne kelljen újra kitöltenie az űrlapot!

Megoldás

A HTML kódban felhasznált űrlapelemek:

		Név:
		<input type="text" name="nev" value="" />
		Megjegyzés:
		<textarea cols="15" rows="3" name="megjegyzes"></textarea>
		Háziállatok:
		<input type="checkbox" name="haziallat[]" value="0" /> Kutya
		<input type="checkbox" name="haziallat[]" value="1" /> Macska
		<input type="checkbox" name="haziallat[]" value="2" /> Rágcsáló
		<input type="checkbox" name="haziallat[]" value="3" /> Egyéb
		Nem:
		<select name="nem">
			<option value="0">Válassz</option>
			<option value="1">Férfi</option>
			<option value="2">Nő</option>
		</select>
		<input type="checkbox" name="elfogad" value="1" /> Elfogadom a feltételeket
		<input type="submit" name="submit" value="Elküld" />

Persze ha ezt így bevágjuk a HTML kódba, nem egészen úgy fog kinézni az űrlap mint ott fent, az azért ilyen rendezett, mert egy táblázat celláiba rakosgattam őket. De most nem az űrlap formázása a lényeg, hanem a működés. A feldolgozó kód feladata, hogy kiírja a továbbított adatokat. Ez például így nézhet ki:

		<?php

		if (isset($_POST["submit"]) && isset($_POST["elfogad"])){
			print "Név: ".$_POST["nev"]."<br />";
			print "Megjegyzés: ".$_POST["megjegyzes"]."<br />";
			print "Háziállatok: ";
			if (is_array($_POST["haziallat"])){
				foreach ($_POST["haziallat"] as $allat){
					switch ($allat){
						case "0": print "Kutya, "; break;
						case "1": print "Macska, "; break;
						case "2": print "Rágcsáló, "; break;
						case "3": print "Egyéb, "; break;
					}
				}
			}
			print "<br />Nem: ";
			if ($_POST["nem"] == 1){
				print "Férfi";
			}
			else if ($_POST["nem"] == 2){
				print "Nő";
			}
		}
		else if (isset($_POST["submit"]) && !isset($_POST["elfogad"])){
			print "El kell fogadnod a feltételeket!";
		}

		?>

Látható, hogy a kiírás csak akkor történik meg, ha elküldte az űrlapot, és bepipálta a checkboxot. Ha elküldte, de nem pipálta be, akkor csak egy hibaüzenetet íruk ki, ha pedig még nincs elküldve akkor a PHP kód nem csinál semmit.
A PHP kód alatt persze ott van az űrlap HTML kódja, ahol még gondoskodni kéne arról, hogy ha el lett küldve az űrlap, de a legalsó checkbox nem lett bepipálva, akkor legyenek kitöltve az űrlapelemek az elküldött $_POST változóknak megfelelően.
A text és textarea mezők esetén ez könnyű, ott csak egyszerűen be kell írni a megfelelő helyre az adott $_POST változót. Hogy csak az említett esetben töltődjön ki az űrlap, a fenti else if ágban hozzunk létre változókat, amiket a HTML kód megfelelő helyén kiírunk. Ha a változó nem létezik, akkor úgyse íródik ki semmi, így kezdetben az űrlap üres lesz. Tehát az else if ág belsejét egészítsük ki ezzel:

		// text
		$nev = $_POST["nev"];
		// textarea
		$megjegyzes = $_POST["megjegyzes"];
		// checkboxok
		$allat = array();
		if (is_array($_POST["haziallat"])){
			foreach ($_POST["haziallat"] as $n => $value){
				$allat[$n] = 'checked="checked"';
			}
		}
		// select
		$nem = array();
		$nem[$_POST["nem"]] = 'selected="selected"';

A HTML kódban így tudjuk felhasználni ezeket a változókat:

		Név:
		<input type="text" name="nev" value="<?php print $nev; ?>">
		Megjegyzés:
		<textarea cols="15" rows="3" name="megjegyzes">
			<?php print $megjegyzes; ?>
		</textarea>
		Háziállatok:
		<input type="checkbox" name="haziallat[]" value="0" <?php print $allat[0]; ?>> Kutya
		<input type="checkbox" name="haziallat[]" value="1" <?php print $allat[1]; ?>> Macska
		<input type="checkbox" name="haziallat[]" value="2" <?php print $allat[2]; ?>> Rágcsáló
		<input type="checkbox" name="haziallat[]" value="3" <?php print $allat[3]; ?>> Egyéb
		Nem:
		<select name="nem">
			<option value="0" <?php print $nem[0]; ?>>Válassz</option>
			<option value="1" <?php print $nem[1]; ?>>Férfi</option>
			<option value="2" <?php print $nem[2]; ?>>Nő</option>
		</select>
		<input type="checkbox" name="elfogad" value="1"> Elfogadom a feltételeket
		<input type="submit" name="submit" value="Elküld">

Amelyik változó (ami lehet egy tömbelem is) nem létezik, annak a helyére nem íródik semmi. Látható, hogy érdemes minél egyszerűbben és logikusabban elnevezni a name és value paramétereket különösen a bonyolultabb űrlapelemek esetén (mint amilyen pl. a checkbox), mert ez jelentősen egyszerűsítheti az űrlapot feldolgozó PHP kódot is.
A php fájl, amiben a teljes kód megtalálható (formázott űrlappal), letölthető innen.