PHP tutorial : formulier afhandeling met GET en POST
Inhoud
Intro
GET methode
POST methode
Handigheden
Arrays in formulieren
Valkuilen
Slashes
Intro
Als je met PHP werkt, dan heb je altijd te maken met formulieren. Dat is eigenlijk niet alleen met PHP, maar met iedere script- en programmeertaal. Het is daarom belangrijk om de basis van het afhandelen van formulieren te kennen, omdat je dat continue moet gebruiken. Op het net zijn talloze scripts te vinden waarin formulieren gebruikt worden. Jammer genoeg worden er ook veel scripts op het net geplaatst die simpelweg niet in orde zijn. Deze tutorial behandelt de basis van het afhandelen van formulieren op beginnersniveau, zodat je zelf scripts kunt ontwikkelen en foute scripts kunt verbeteren.
Een formulier wordt altijd met HTML gemaakt, soms komt daar wat javascript bij kijken, maar de basis is altijd HTML. Een formulier is bedoeld om informatie te versturen. Met deze informatie kan vervolgens een handeling plaats vinden. In de praktijk komt dat vaak neer op opslaan in een database of bestand, of versturen via e-mail, of een combinatie. Er zijn natuurlijk veel meer handelingen te bedenken, maar één ding hebben ze allemaal overeenkomstig en dat is dat PHP de informatie uit het formulier moet zien te bemachtigen en klaar moet zetten voor een eventuele handeling.
GET methode
Gegevens vanuit een formulier kunnen op twee manieren worden verzonden. De eerste manier is met de GET methode. Deze methode verstuurd de informatie uit het formulier via de url. Een formulier in HTML begint altijd met de form-tag. Deze tag heeft altijd twee attributen nodig, het action attribuut en het method attribuut. De waarde van het method attribuut kan GET of POST zijn. Bij de GET methode krijgen we de volgende form-tag :
<form action="./contact.php" method="get">
Gemakshalve gaan we er even van uit dat de informatie uit het formulier verzonden moet worden naar zichzelf, het bestand (of pagina) contact.php . De rest van dit contact formulier bestaat uit de velden naam en e-mail adres. We maken het formulier even af.
<form action="./contact.php" method="get">
Naam : <input type="text" name="contact_naam" /><br />
E-mail : <input type="text" name="contact_email" /><br />
<input type="submit" name="submit" value="verstuur" />
</form>
Als we dit formulier zouden vullen met de volgende gegevens
Naam : Donny
E-mail : pietje@puk.nl
en vervolgens zouden verzenden, dan zul je in de adresbalk het volgende zien :
http://www.site.nl/contact.php?contact_naam=Donny&contact_email=pietje@puk.nl&submit=verstuur
Dit gaan we ontleden. Na het domein (http://www.site.nl) komt de pagina waar het formulier naar verwijst, contact.php. Daarachter staat een hele riedel informatie :
?contact_naam=Donny&contact_email=pietje@puk.nl&submit=verstuur
Als er via de GET methode informatie wordt verstuurd gebeurt dit dus via de adresbalk. Om aan te geven dat de URL informatie bevat, wordt er na de pagina een vraagteken geplaatst. Dit geeft aan de pagina door dat er informatie wordt meegestuurd. Na het vraagteken krijgen we een reeks te zien die hieronder uitgesplitst staat.
contact_naam=Donny
&
contact_email=pietje@puk.nl
&
submit=verstuur
En meteen is duidelijk dat de informatie die we via het formulier verstuurd hebben, letterlijk in de URL staat, gescheiden door een ampersand, het & teken. De input velden uit het formulier hebben allemaal een unieke naam in dit geval. Bij Naam heet het input vuld contact_naam, bij E-mail heet het input veld contact_email en de laatste is de submit knop, wat eigenlijk ook input veld is, genaamd submit in dit geval en met een waarde die in de HTML is opgegeven, namelijk verstuur.
Voor ons is nu duidelijk dat er informatie verstuurd is via de adresbalk met de GET methode. Nu moeten we aan het script doorgeven dat er informatie is verstuurd met de GET Methode. PHP kent een aantal voorgedefinieerde variabelen. Deze kun je vinden in de lijst met voorgedefinieerde variabelen op php.net. Drie van deze variabelen hebben betrekking op formulieren, te weten :
- $_GET
- $_POST
- $_REQUEST
- contact_naam
- contact_email
- submit
| key | value | |
| => | Donny | |
| => | pietje@puk.nl | |
| => | verstuur |
<?php
$contact_naam = $_GET['contact_naam'];
?>
Als we variabele $contact_naam vervolgens printen, dan zien we dat daar de waarde komt te staan die opgegeven is in het formulier :
<?php
$contact_naam = $_GET['contact_naam'];
print($contact_naam);
?>
Geeft als HTML output :
Donny
Als we iedere waarde uit het formulier dus zouden willen gebruiken, zullen we dus voor iedere waarde de bijbehorende key uit het array $_GET moeten aanroepen. Stel dat we de verstuurde waarden willen printen, na het verzenden van het formulier. Dan zouden we de eerst een variabele kunnen definieren en die vullen met de waarde uit het array, of we printen direct uit het array. We krijgen dan :
<?php
print($_GET['contact_naam']);
print("<br />\n");
print($_GET['contact_email']);
?>
Met als Output :
Donny
pietje@puk.nl
Als je alle ingevulde waarden voor andere doeleinden wilt gebruiken zul je ze dus op moeten slaan als variabele waarna je ze voor allerlei doeleinden kunt gebruiken.
<?php
$contact_naam = $_GET['contact_naam'];
$contact_email = $_GET['contact_email'];
?>
POST methode
Naast de GET methode kun je gegevens uit een formulier ook verzenden met de POST methode. In principe werken de POST en GET methode hetzelfde alleen wordt de informatie uit het formulier niet verzonden via de adresbalk maar via een zogenaamd HTTP post transactie. Dit zegt weinig mensen iets dus we gaan de POST methode gewoon in de praktijk brengen.
Het formulier is op één ding na het zelfde als bij de GET methode. Het enige verschil is, en je raad het misschien al, de method attribuut in de form-tag. Dit attribuut bevat de waarde POST:
<form action="./contact.php" method="post">
Naam : <input type="text" name="contact_naam" /><br />
E-mail : <input type="text" name="contact_email" /><br />
<input type="submit" name="submit" value="verstuur" />
</form>
Bij het versturen van het formulier zul je echter geen informatie in de adresbalk zien. De informatie wordt niet zichtbaar verstuurd. Dat maakt deze methode een stukje veiliger omdat niemand nu kan wat er eigenlijk verstuurd wordt. Als de gegevens in de adresbalk staan, kan iedereen die het formulier gebruikt zien welke informatie er allemaal verstuurd wordt. Op zicht maakt dat niet zo heel veel uit, want mensen die thuis zijn in HTML kunnen sowieso in de HTML zien wat voor informatie er allemaal verstuurd wordt. Het voordeel van POST is dat je meer informatie kunt versturen dan met GET, maar daar komen we nog op terug.
Omdat we nu een andere methode gebruiken, zullen we PHP moeten vertellen dat we dit met POST doen. Dat doen we door de voorgedefinieerde variabele $_POST te gebruiken. Net als $_GET is $_POST een array en bevat in dit geval dezelfde keys en values als $_GET in het vorige voorbeeld. We kunnen het tweede voorbeeld dus makkelijk houden. Stel dat we met bovenstaand formulier de volgende waarden versturen :
Naam : Mark
E-mail : admin@site.nl
Binnen PHP vangen we dat dan zo af :
<?php
$contact_naam = $_POST['contact_naam'];
$contact_email = $_POST['contact_email'];
?>
Zoals je ziet werkt de POST methode nagenoeg hetzelfde als de GET methode, met het verschil dat de informatie niet getoond wordt in de adresbalk (URI genaamd in dit geval). Voor formulierafhandeling gebruiken we eigenlijk altijd de POST methode omdat dit bij veel informatie minder gedoe geeft in de adresbalk en daardoor minder kans heeft op fouten die zouden kunnen ontstaan.
Handigheden
Het kan altijd voorkomen dat je een script hebt dat een bepaalde waarde moet uitlezen die de ene keer via de POST methode wordt verstuurd en de andere keer via de GET methode. Je kunt dan in je script het volgende doen.
<?php
# Stel dat we een ID moeten afvangen dat de ene keer uit een formulier komt
# en de andere keer uit de adresbalk.
if (isset($_GET['id']))
{
$id = $_GET['id'];
}
elseif (isset($_POST['id']))
{
$id = $_POST['id'];
}
?>Een handigheid hierbij is de voorgedefinieerde variabele $_REQUEST. Deze variabele vangt zowel de POST als GET variabelen af, maar ook COOKIES. Het is daarom geen veilige methode en het wordt dan ook afgeraden om deze te gebruiken, maar ik laat toch de werking even zien.
<?php
# Stel dat we een ID moeten afvangen dat de ene keer uit een formulier komt
# en de andere keer uit de adresbalk.
if (isset($_REQUEST['id']))
{
$id = $_REQUEST['id'];
}
?>Als je werkt met formulieren is het noodzakelijk om aan het script door te geven dat er acties moeten gebeuren wanneer het formulier verzonden is. We maken onderscheid in het script tussen drie gedeeltes. Het eerste deel is het deel dat de verwerkingen doet als het formulier verzonden is. Het tweede deel doet de verwerkingen die nodig zijn als het formulier niet verzonden is en het derde deel doet bewerkingen die gedaan moeten worden wanneer het formulier niet en wel verzonden is.
Om te bepalen of het formulier verzonden is, zullen we moeten kijken of de voorgedefinieerde variabele gevuld is of niet. Dat kan heel makkelijk door te controleren of één van de inputvelden in het array van $_POST zit (tenminste, als we het formulier met de POST methode versturen. Stel we hebben het onderstaande formulier :
<form action="./contact.php" method="post">
Naam : <input type="text" name="contact_naam" /><br />
E-mail : <input type="text" name="contact_email" /><br />
Adres : <input type="text" name="contact_adres" /><br />
<input type="submit" name="submit" value="verstuur" />
</form>Dan zouden we één van deze input velden kunnen gebruiken om te controleren of het formulier verzonden is, op één na. Het is niet verstandig om het submit-inputveld te gebruiken om te controleren of het formulier verzonden is om de reden dat, wanneer het formulier verzonden wordt met de enter knop, dus niet via een muisklik op de knop, de submitknop niet meegenomen wordt in het formulier. Dus voeren we de controle uit op een ander veld. Persoonlijk gebruik ik altijd een inputveld van het type hidden met een willekeurige naam en waarde.
<form action="./contact.php" method="post">
<input type="hidden" name="zendform" value="1" />
Naam : <input type="text" name="contact_naam" /><br />
E-mail : <input type="text" name="contact_email" /><br />
Adres : <input type="text" name="contact_adres" /><br />
<input type="submit" name="submit" value="verstuur" />
</form>Als het formulier vervolgens verstuurd wordt, dan komt het script er zo uit te zien :
<?php
# Controleren of het formulier is verzonden via de POST methode
if (isset($_POST['zendform']))
{
// Hier alle bewerkingen die moeten gebeuren
// met de verzonden waarden uit het formulier
}
else
{
// Hier alle bewerkingen die moeten gebeuren
// als het formulier nog niet verzonden is
}
// En dan daaronder alle bewerkingen die moeten gebeuren
// ongeacht of het formulier verzonden is
?>Een andere manier om te controleren of het formulier verzonden is, is de volgende :
<?php
# Controleren of het formulier is verzonden via de POST methode
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
// Hier alle bewerkingen die moeten gebeuren
// met de verzonden waarden uit het formulier
}
?>Deze methode is ook goed te gebruiken tenzij je meer dan 1 formulier in een script hebt. Als je meerdere formulieren hebt zul je daar toch onderscheid in moeten maken. Dit is nog een reden om niet te controleren op $_POST['submit'] omdat de meeste submitknoppen submit ook als naam hebben. Bij het gebruik van meerdere formulieren met de submitknop genaamd submit, loopt je script in het honderd als je controleert op deze knop omdat PHP dan ieder formulier accepteert in plaats van die enkele die geaccepteerd zou moeten worden.
Wanneer je met grote formulieren werkt en met veel input velden, dan kom je al gauw tegen het punt aan dat je heel veel variabelen moet definieren met de verzonden waarden. Stel dat we een formulier hebben waarin tal van persoonsgegevens moeten worden ingevuld. Als het formulier dan verzonden is, dan zouden we de variabelen één voor één kunnen definieren :
<?php
# Controleren of het formulier is verzonden via de POST methode
if (isset($_POST['zendform']))
{
$voorletters = $_POST['voorletters'];
$tussenvoegsel = $_POST['tussenvoegsel'];
$achternaam = $_POST['achternaam'];
$straatnaam = $_POST['straatnaam'];
$huisnummer = $_POST['huisnummer'];
$toevoeging = $_POST['toevoeging'];
$postcode = $_POST['postcode'];
$woonplaats = $_POST['woonplaats'];
$telefoonnummer = $_POST['telefoonnummer'];
$emailadres = $_POST['emailadres'];
}
?>Als je dan een bewerking moet doen op deze variabelen, bijvoorbeeld ontdoen van overbodige spaties met de functie trim(), dan zul je dat op iedere variabele moeten toepassen :
<?php
# Controleren of het formulier is verzonden via de POST methode
if (isset($_POST['zendform']))
{
$voorletters = trim($_POST['voorletters']);
$tussenvoegsel = trim($_POST['tussenvoegsel']);
$achternaam = trim($_POST['achternaam']);
$straatnaam = trim($_POST['straatnaam']);
$huisnummer = trim($_POST['huisnummer']);
$toevoeging = trim($_POST['toevoeging']);
$postcode = trim($_POST['postcode']);
$woonplaats = trim($_POST['woonplaats']);
$telefoonnummer = trim($_POST['telefoonnummer']);
$emailadres = trim($_POST['emailadres']);
}
?>Bij een paar variabelen en 1 functie valt dit allemaal nog wel te doen, maar wat als je met enkele 10-tallen variabelen en meerdere functies en restricties moet werken? Dan passen we een handigheidje toe. We lezen het array $_POST uit met foreach(), deze functie splitst het array in keys en values waar deze apart te behandelen zijn. Met een trucje kun je dan de variabelen in één keer voorzien van de juiste waarde :
<?php
# Controleren of het formulier is verzonden via de POST methode
if (isset($_POST['zendform']))
{
foreach($_POST as $key => $value)
{
$$key = trim($value);
}
}
?>De dubbele $$ maakt van de key een variabele die de naam van de key heeft. Die variabele definieer je met de waarde die bij de key hoort. Dat doe je, dankzij de foreach() functie met iedere key (en bijbehorende value) die in het array $_POST zitten. Dit gaat echter niet op wanneer je gebruik maakt van arrays in het formulier, maar daarover later meer
Arrays in formulieren
Het is mogelijk om via HTML informatie te versturen in arrays. En dan bedoel ik niet een $_POST of $_GET array, maar een inputveld als array. Uiteindelijk komt dit array wel terecht in het hoofdarray $_POST of $_GET.
Een veel gebruikte methode is de volgende. Stel je hebt een selectbox waaruit meerdere opties te kiezen zijn. Die opties wil je afvangen met PHP. We krijgen dan het volgende HTML formulier :
<form action="./contact.php" method="post">
<input type="hidden" name="zendform" value="1" />
Naam : <input type="text" name="contact_naam" /><br />
E-mail : <input type="text" name="contact_email" /><br />
Voorkeur : <select name="contact_voorkeur[]" multiple="multiple">
<option value="1">09:00 - 11:00</option>
<option value="2">11:00 - 13:00</option>
<option value="3">13:00 - 15:00</option>
<option value="4">15:00 - 17:00</option>
<option value="5">17:00 - 19:00</option>
<option value="6">19:00 - 21:00</option>
</select><br />
<input type="submit" name="submit" value="verstuur" />
</form>
Waarbij het dus mogelijk is, om met behulp van de knop CTRL of SHIFT, meerdere tijd-opties te kiezen in de selectbox. Wat ook meteen opvalt is de naam van de selectbox; contact_voorkeur[] . Daar staan twee rechte haken in. Deze haken geven aan dat het inputveld contact_voorkeur een array is waarin meerder opties kunnen zitten. Dat houdt dus in dat in het array $_POST straks een subarray zit, genaamd contact_voorkeur, met daarin de opties uit de selectbox.
Als we dit formulier gaan verzenden en we hebben een naam, e-mail adres en de opties 11:00-13:00, 13:00-15:00 en 19:00-21:00 geselecteerd, dan bevat het array $_POST de volgende keys en values :
- zendform
- contact_naam
- contact_email
- contact_voorkeur
- submit
| key | value | ||||
| => | 1 | ||||
| => | Kees | ||||
| => | kees@site.nl | ||||
| => | Array | ||||
| 0 | => | 2 | |||
| 1 | => | 3 | |||
| 2 | => | 6 | |||
| => | verstuur | ||||
De value die hoort bij key contact_vookeur is een array die weer is opgebouwd uit keys en values. De keys zijn automatisch genummerd van 0 tot aan het aantal opties met als waarde de geselecteerde opties uit het formulier.
Om alle informatie uit het formulier om te zetten naar bruikbare variabelen in PHP kun je dan gebruik maken van het volgende script :
<?php
if (isset($_POST['zendform']))
{
foreach($_POST as $key => $value)
{
# controleren of $value een array is
if (is_array($value))
{
foreach($value as $key_sub => $value_sub)
{
$key2 = $key . $key_sub;
$$key2 = $value_sub;
}
}
else
{
$$key = trim($value);
}
}
}
?>
Je zou natuurlijk ook een andere bewerking kunnen doen. Het nadeel van het werken met arrays is dat je vaak niet zeker weet om hoeveel opties het gaat. Daar zul je in je script dus rekening mee moeten houden.
Arrays in formulieren kunnen ook via text-input velden. Als je bijvoorbeeld automatisch een formulier genereert met de inhoud van een databasetabel of een bestand. In onderstaand voorbeeld halen we fictief voornamen en bijbehorende id's uit de database die we dan verwerken in een formulier dat gegenereert wordt aan de hand van het aantal resultaten.
<?php
# query maken
$sql = "SELECT id, voornaam
FROM tabel1";
# query uitvoeren
$result = mysql_query($sql)
or die(mysql_error());
# formulier printen
print("<form action=\"./update.php\" method=\"post\">\n");
print("<input type=\"hidden\" name=\"verzendform\" value=\"1\" />\n");
print("Voornamen :<br />\n");
# voornamen uit de database halen
while ($line = mysql_fetch_assoc($result))
{
print("<input type=\"text\" name=\"voornaam[" . $line['id'] . "]\"
value=\"" . $line['voornaam'] . "\" /><br />\n");
}
# verder met het formulier
print("<input type=\"submit\" name=\"submit\" value=\"update\" />\n");
print("</form>\n");
?>
Dit formulier ziet er in HTML zo uit :
<form action="./update.php" method="post">
<input type="hidden" name="zendform" value="1" />
Voornamen :<br />
<input type="text" name="voornaam[1]" value="Mark" /><br />
<input type="text" name="voornaam[2]" value="Kees" /><br />
<input type="text" name="voornaam[4]" value="Klaas" /><br />
<input type="text" name="voornaam[5]" value="Piet" /><br />
<input type="submit" name="submit" value="update" />
</form>
Als je dit formulier verzend dan bevat $_POST de volgend waarden :
- zendform
- voornaam
- submit
| key | value | ||||
| => | 1 | ||||
| => | Array | ||||
| 1 | => | Mark | |||
| 2 | => | Kees | |||
| 4 | => | Klaas | |||
| 5 | => | Piet | |||
| => | verstuur | ||||
Je ziet dat het array $_POST een subarray bevat genaamd voornaam, waarin de keys en values staan, die overeenkomen met het id en voornaam, die we geselecteerd hebben uit de database. Op die manier kun je dus heel eenvoudig meerdere rijen uit een databasetabel selecteren, in een formulier stoppen en de tabel weer updaten waarbij je het id van de rij meegeeft in het HTML formulier.
Valkuilen
In veel oude scripts klopt de methode om te controleren of er een formulier is verstuurd niet. Een veelvoorkomende fout is dit :
<?php
# Controleren of het formulier is verzonden
if ($submit)
{
// etc.
}
?>
De reden waarom dit niet goed is, omdat er vanuit wordt gegaan dat de variabele $submit al bestaat (gedefinieerd is). Maar een variabele is pas gedefinieerd als deze van te voren in het script een waarde heeft gekregen. Als de error_reporting op E_ALL staat dan zul je ook zien dat de volgende foutmelding wordt weergegeven
Notice: Undefined variable: submit in server/httpdocs/contact.php on line 3
De foutmelding zegt het eigenlijk al, er is een ongedefinieerde variabele. Dus om te controleren of een formulier verzonden is, behoor je altijd gebruik te maken van een gedefinieerde variabele. Daarnaast dien je te controleren of die variabele ook gezet is. Dat doe je met de functie isset() . Een correct voorbeeld is :
<?php
# Controleren of het formulier is verzonden
if (isset($_POST['unieke_index']))
{
// etc.
}
?>
Waarbij ´unieke_index´ dus een, voor dat formulier, uniek inputveld moet zijn.
Slashes
Het komt vaak voor dat je na het versturen van gegevens via een formulier de gegevens terug krijgt met een slash er voor, of soms zelfs met 3 slashes. Dit is een bekend probleem binnen PHP. Gelukkig zijn hier al genoeg artikelen met oplossingen over geschreven dus dat ga ik niet nog een keer doen. Goede Nederlandse artikelen over dit probleem :
Addslashes en stripslashes: wie wat waar wanneer en waarom?
Slashes? Wanneer en wanneer niet??
magic_quotes, addslashes, en stripslashes
-----------
Tot zo ver ´formulier afhandeling met GET en POST´.
Ik hoop dat jullie er wat van geleerd hebben. Mocht je fouten tegenkomen (nobody's perfect) laat me dit dan s.v.p. weten op donny at semeleer dot nl . Uiteraard zijn op- en aanmerkingen ook van harte welkom!
-----------
Overige PHP tutorials:
Mijn elftal zoekt een nieuwe keeper. Weet jij iemand?
-----------