Deze website maakt gebruik van diensten van Google voor het tonen van advertenties en het bijhouden van bezoekersstatistieken. Google kan hiermee uw surfgedrag volgen. Zie voor meer informatie het privacybeleid van Google. Via Your Online Choices kunt u zich afmelden voor gepersonaliseerde advertenties. Deze melding verbergen.

8 Formulier-variabelen

Familie van de URL-variabelen zijn de formulier-variabelen. Op het moment dat een HTML-formulier wordt verzonden kan een PHP script worden aangeroepen. Dit PHP script ontvangt de in het formulier ingevoerde informatie dan als formulier-variabelen.

Theorie

Net als de URL-variabelen zijn de formulier-variabelen beschikbaar via een array: $_POST.
De sleutels van deze array zijn gelijk aan de attributen name van het verzonden formulier.

Het formulier

De basistypen voor velden in een formulier zijn het invoervak, de radioknoppen, de selectievakjes en het tekstveld:

<form action="script.php" method="post">

<input type="text" name="email">

<input type="radio" name="abonnee" value="ja">
<input type="radio" name="abonnee" value="nee">

<input type="checkbox" name="keuze1" value="true">
<input type="checkbox" name="keuze2" value="true">
<input type="checkbox" name="keuze3" value="true">

<textarea name="bericht" rows="5" cols="20"></textarea>

<input type="submit" value="verzenden">

</form>

Het eerste belangrijke onderdeel van het formulier is de formulier-actie. Hierin wordt het PHP bestand vermeldt waarnaar het formulier 'verzonden' wordt. Dit PHP bestand pikt dus de inhoud van het formulier op en zal iets met de inhoud van het formulier moeten doen. In het hier genoemde PHP bestand komt ook de $_POST array beschikbaar met de inhoud van het formulier.

Tweede onderdeel is de formulier-methode. Deze moet op post worden ingesteld om de inhoud van het formulier via de $_POST-array in het verwerkende script beschikbaar te krijgen. Indien de formulier-methode wordt weggelaten komt de formulier-inhoud via $_GET beschikbaar (zie paragraaf Formulierinhoud via URL-variabelen).

In de laatste plaats moet ieder formulierveld een uniek name-attribuut hebben. Enige uitzondering zijn de radioknoppen: uit radioknoppen met dezelfde naam kan maar één waarde worden gekozen, waardoor deze radioknoppen een groep vormen. Indien meerdere velden dezelfde name hebben, zullen deze elkaar overschrijven.

Formulierinhoud in PHP

Indien een formulier wordt verzonden komt de ingevulde inhoud beschikbaar aan het in de formulier-actie opgegeven script. Via de $_POST array zijn de gegevens te gebruiken:

$_POST['name']

Hierin is name gelijk aan het name­-attribuut van een formulierveld.

Het formulier uit de vorige paragraaf levert dus de volgende sleutels in de $_POST array op:

$_POST['email'];
$_POST['abonnee'];
$_POST['keuze1'];
$_POST['keuze2'];
$_POST['keuze3'];
$_POST['bericht'];

Deze waarden kunnen dus verder in het script gebruikt worden.

Veiligheid

Voor formulier-variabelen kunnen dezelfde opmerkingen met betrekking tot veiligheid worden gemaakt als voor URL-variabelen. Hiervoor wordt dan ook verwezen naar hoofdstuk 7.

Gegevens uit formulieren kunnen HTML bevatten, dus het is verstandig om de functie htmlspecialchars() toe te passen voordat formuliergegevens in een webpagina worden weergegeven, zoals besproken is in hoofdstuk 7.

Eerder is opgemerkt dat de in het formulier ingevulde gegevens verborgen blijven. Merk op dat verborgen niet betekent dat de gegevens versleuteld zijn. Gegevens uit een formulier (inclusief wachtwoorden) worden onversleuteld over internet van de bezoeker naar de server verstuurd en kunnen onderweg mogelijk door kwaadwillenden worden onderschept. Voor de meeste websites is dit een geaccepteerd risico, ookal schrijft artikel 13 van de Wet Bescherming Persoonsgegevens voor dat persoonsgegevens versleuteld moeten worden verzonden. Wil je dit risico afdekken, dan kun je de verbinding tussen bezoeker en server versleutelen via bijvoorbeeld SSL.

Formulierinhoud via URL-variabelen

Naast het ontvangen van formulier-gegevens via $_POST, is het ook mogelijk om de formulier-gegevens via de $_GET-array (zie hoofdstuk 7) aan het verwerkende script beschikbaar te stellen. In dit geval dient de form method in plaats van op post te worden ingesteld op get:

<form action="script.php" method="get">

Op dit moment worden de formulier-gegevens niet meer verborgen verzonden, maar worden ze aan de url van (in dit geval) script.php toegevoegd. Dit is tevens de standaard-methode indien er geen method wordt aangegeven in form.

Omdat een url niet oneindig lang kan zijn, is de get-methode niet bruikbaar voor grote formulieren en in het bijzonder formulieren met textarea's. De post-methode kent deze beperking niet.

Praktijkvoorbeeld: formuliercontrole

In veel formulieren is het verplicht om één of meerdere velden in te vullen. PHP kan gebruikt worden om te kijken of de bezoeker ook daadwerkelijk alle verplichte velden heeft ingevuld. In dit praktijkvoorbeeld gaan we een eenvoudig formulier in actie zien en zullen we een controle inbouwen voor verplichte velden.

Hierbij zal de functie empty() gebruikt gaan worden:

bool empty ( mixed $var )

Deze functie controleert of de opgegeven variabele leeg is. Als dat het geval is wordt TRUE gegeven. Als de variabele niet leeg is wordt FALSE gegeven. We gaan empty() ook gebruiken om te bepalen of een formulier wel of niet verzonden is.

Formuleren

Laten we eerst eens het formulier bekijken. In dit eenvoudige voorbeeld bestaat het formulier uit twee velden: naam en email.

<form method="post">
Naam: <input type="text" name="naam"><br>
Email: <input type="text" name="email"><br>
<input type="submit" value="Verzenden">
</form>

De formulieractie is weggelaten, wat betekent dat bij het verzenden van het formulier hetzelfde bestand wordt aangeroepen. Dit kan als het formulier en de afhandeling ervan in hetzelfde bestand worden opgenomen, wat het geval is in dit voorbeeld. Wel is de post-methode gekozen voor verzending van het formulier.

Controleren

Op het moment dat het formulier verzonden wordt, zal de verzonden informatie worden opgepikt door praktijkvoorbeed.php. Omdat voor de veldnamen naam en email is gebruikt, is de inhoud van deze velden beschikbaar in respectievelijk $_POST['naam'] en $_POST['email'].

Met dit gegeven en de functie empty() kunnen we een formuliercontrole opstellen:

//veldcontrole
if (empty($_POST['naam'])) $veldfout['naam'] = TRUE;
if (empty(
$_POST['email'])) $veldfout['email'] = TRUE;

//afhandeling
if (!empty($veldfout)) {
    
//formulier incorrect ingevuld
    
echo 'Niet alle velden zijn ingevuld.';
}
else {
    
//formulier correct
    
echo 'Alle velden zijn ingevuld.';
}

Allereerst wordt voor ieder veld gecontroleerd of er iets is ingevuld. Als niets is ingevuld wordt een sleutel aan de array $veldfout toegevoegd. De sleutelnaam is hierbij gelijk aan de naam van het veld dat leeg is gelaten. In dit voorbeeld wordt verder de waarde TRUE toegekend, maar dit kan ook iedere willekeurige andere waarde zijn.

Op het moment dat alle velden correct zijn ingevuld, zal de array $veldfout leeg zijn. Staat er wel iets in, dan is in ieder geval één veld niet ingevuld. Met behulp van empty() kan nu onderscheid gemaakt worden tussen correct en niet correct ingevulde formulieren. In dit geval wordt met !empty() precies het tegenovergestelde bekeken: als $veldfout niet leeg is wordt een foutmelding gegeven. Het uitroepteken is de logische operator "niet", zie tabel 4.2.

Combineren

Tijd om de controle en het formulier samen te voegen. Wederom zal nu empty() gebruikt worden. Ditmaal om te bepalen of het formulier verzonden is of niet. Op het moment dat het formulier niet verzonden is, zal $_POST immers leeg zijn.

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Praktijkvoorbeeld Formuliercontrole</title>
</head>
<body>

<?php
if (!empty($_POST)) {
    
//formulier is verzonden, controleer formulier
    
if (empty($_POST['naam'])) $veldfout['naam'] = TRUE;
    if (empty(
$_POST['email'])) $veldfout['email'] = TRUE;
    
    
//afhandeling
    
if (!empty($veldfout)) {
        
//formulier incorrect ingevuld
        
echo 'Niet alle velden zijn ingevuld.';
    }
    else {
        
//formulier correct
        
echo 'Alle velden zijn ingevuld.';
    }
}
else {
    
//formulier is niet verzonden, geef formulier weer
    
?>
    <form method="post">
    Naam: <input type="text" name="naam"><br>
    Email: <input type="text" name="email"><br>
    <input type="submit" value="Verzenden">
    </form>
    <?php
}
?>

</body>
</html>

Indien het formulier niet is verzonden, wordt het formulier weergegeven. Indien het formulier wel is verzonden, wordt de foutcontrole uitgevoerd. Let op het uitroepteken voor !empty($_POST). De formuliercontrole moet namelijk worden uitgevoerd wanneer $_POST niet leeg is.

Uitbreiden

Tot nu toe is de formuliercontrole niet echt gebruiksvriendelijk. Zodra een fout wordt gemaakt zijn alle gegevens die wel correct zijn ingevoerd kwijt. Verder weet de gebruiker niet wat er precies mis is gegaan.

Omdat in de formuliercontrole wordt onthouden welke velden incorrect zijn ingevuld, kunnen we deze informatie ook terugkoppelen naar de gebruiker. Daarnaast willen we het formulier opnieuw weergeven zodra dit niet correct is ingevuld, waarbij de reeds ingevulde informatie automatisch opnieuw in de velden neergezet wordt.

Voor deze uitbreiding zullen we afstappen van de structuur die in de vorige paragraaf aangereikt is. Voor dit redelijk gecompliceerde script is het dan ook verstandig om een stappenplan op te stellen:

  1. Bepaal of formulier is verzonden.
  2. Als formulier is verzonden, controleer of er incorrecte velden zijn.
  3. Als velden correct, geef succesmelding.
  4. Als formulier niet verzonden of niet correct, geef formulier weer.
  5. Als formulier incorrect, geef melding bij incorrect veld.
  6. Als formulier incorrect, vul verstrekte gegevens terug in.

Stap 1

Om te bepalen of het formulier is verzonden kunnen we gebruik maken van de reeds bekende code:

if (!empty($_POST)) {
    
//formulier is verzonden
}
else {
    
//formulier niet verzonden
}

Stap 2

Als het formulier verzonden is, zullen we controleren of de velden correct zijn ingevuld. Ook hier kunnen we weer de eerder afgeleide code gebruiken:

if (!empty($_POST)) {
    
//formulier is verzonden
    //controleer velden:
    
if (empty($_POST['naam'])) $veldfout['naam'] = TRUE;
    if (empty(
$_POST['email'])) $veldfout['email'] = TRUE;
}
else {
    
//formulier niet verzonden
}

Stap 3

Als alle velden correct zijn ingevuld, zal $veldfout niet bestaan en kunnen we een succesmelding weergeven. In plaats van te kijken of $veldfout bestaat kijken we door toevoeging van het uitroepteken juist of $veldfout niet bestaat.

if (!empty($_POST)) {
    
//formulier is verzonden
    //controleer velden:
    
if (empty($_POST['naam'])) $veldfout['naam'] = TRUE;
    if (empty(
$_POST['email'])) $veldfout['email'] = TRUE;
    
    
//afhandeling
    
if (empty($veldfout)) {
        
//als $veldfout niet bestaat:
        
echo 'Alle velden zijn ingevuld';
    }
}
else {
    
//formulier niet verzonden
}

Stap 4

Nu wordt het formulier toegevoegd. Omdat het formulier ook moet worden weergegeven als het formulier wel is verzonden maar niet correct ingevuld, kunnen we het formulier niet in de resterende else bij //formulier niet verzonden onderbrengen. In plaats daarvan zullen we bij deze else een extra variabele toevoegen die aangeeft dat het formulier niet is verzonden.

Het daadwerkelijke formulier brengen we dan onder in een losse if-constructie die er voor zal zorgen dat het formulier alleen wordt weergegeven als het niet is verzonden of niet correct is ingevuld:

if (!empty($_POST)) {
    
//formulier is verzonden, controleer velden:
    
if (empty($_POST['naam'])) $veldfout['naam'] = TRUE;
    if (empty(
$_POST['email'])) $veldfout['email'] = TRUE;

    if (empty(
$veldfout)) {
        
//als $veldfout niet bestaat:
        
echo 'Alle velden zijn ingevuld';
    }
}
else {
    
//formulier niet verzonden
    
$nietverzonden = TRUE;
}

if (!empty(
$veldfout) || ($nietverzonden == TRUE)) {
    
//formulier niet verzonden of fout, laat formulier zien:
    
?>
    <form method="post">
    Naam: <input type="text" name="naam"><br>
    Email: <input type="text" name="email"><br>
    <input type="submit" value="Verzenden">
    </form>
    <?php
}

Stap 5

Voor het weergeven van de foutmeldingen gaan we gebruik maken van $veldfout. Ieder verkeerd ingevulde veld heeft een vermelding in $veldfout die we kunnen gebruiken om op juiste plek de juiste foutmelding weer te geven.

if (!empty($veldfout) || ($nietverzonden == TRUE)) {
    
//formulier niet verzonden of fout, laat formulier zien:
    
?>
    <form method="post">
    <?php if ($veldfout['naam'] == TRUE) echo 'Naam verplicht:<br>'; ?>
    Naam: <input type="text" name="naam"><br>
    <?php if ($veldfout['email'] == TRUE) echo 'Email verplicht:<br>'; ?>
    Email: <input type="text" name="email"><br>
    <input type="submit" value="Verzenden">
    </form>
    <?php
}

Het eerste gedeelte van het script is hier tijdelijk weggelaten.

Stap 6

De laatste stap is het terug invullen van reeds opgegeven informatie. Voor het terug invullen van informatie worden er value­-attributen aan de formuliervelden toegevoegd. Om te voorkomen dat kwaadaardige code wordt geïnjecteerd zal ook de functie htmlspecialchars() gebruikt gaan worden.

if (!empty($veldfout) || ($nietverzonden == TRUE)) {
    
//formulier niet verzonden of fout, laat formulier zien:
    
?>
    <form method="post">

    <?php if ($veldfout['naam'] == TRUE) echo 'Naam verplicht:<br>'; ?>
    Naam: <input type="text" name="naam" <?php if (!empty($_POST['naam'])) echo 'value="'.htmlspecialchars($_POST['naam']).'" '; ?>><br>

    <?php if ($veldfout['email'] == TRUE) echo 'Email verplicht:<br>'; ?>
    Email: <input type="text" name="email" <?php if (!empty($_POST['email'])) echo 'value="'.htmlspecialchars($_POST['email']).'" '; ?>><br>

    <input type="submit" value="Verzenden">
    </form>
    <?php
}

Het eerste gedeelte van het script is hier tijdelijk weggelaten.

Totale code

De totale code van het formulier met controle en foutafhandeling wordt hiermee als volgt:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Praktijkvoorbeeld Formuliercontrole</title>
</head>
<body>

<?php
if (!empty($_POST)) {
    
//formulier is verzonden
    //controleer velden:
    
if (empty($_POST['naam'])) $veldfout['naam'] = TRUE;
    if (empty(
$_POST['email'])) $veldfout['email'] = TRUE;
    
    
//afhandeling
    
if (empty($veldfout)) {
        
//als $veldfout niet bestaat:
        
echo 'Alle velden zijn ingevuld';
    }
}
else {
    
//formulier niet verzonden
    
$nietverzonden = TRUE;
}

if (!empty(
$veldfout) || ($nietverzonden == TRUE)) {
    
//formulier niet verzonden of fout, laat formulier zien:
    
?>
    <form method="post">
    <?php if ($veldfout['naam'] == TRUE) echo 'Naam verplicht:<br>'; ?>
    Naam: <input type="text" name="naam" <?php if (!empty($_POST['naam'])) echo 'value="'.htmlspecialchars($_POST['naam']).'" '; ?>><br>
    <?php if ($veldfout['email'] == TRUE) echo 'Email verplicht:<br>'; ?>
    Email: <input type="text" name="email" <?php if (!empty($_POST['email'])) echo 'value="'.htmlspecialchars($_POST['email']).'" '; ?>><br>
    <input type="submit" value="Verzenden">
    </form>
    <?php
}
?>

</body>
</html>

Zelftest

  1. De functie empty()
    1. …controleert of een variabele leeg is.
    2. …maakt een variabele leeg.
    3. …is een lege functie zonder betekenis.
    4. …bestaat niet.
  2. sleutel in $_POST['sleutel'] is gelijk aan?
    1. De naam van het formulier.
    2. De waarde van het formulierveld.
    3. De naam van het formulierveld.
    4. De methode van het formulier.
  3. Welke van onderstaande stellingen is/zijn waar?
    I             Radioknoppen moeten allen een uniek name-attribuut hebben.
    II            Waarden in $_POST zijn altijd betrouwbaar.
    1. Alleen stelling I is waar.
    2. Alleen stelling II is waar.
    3. Beide stellingen zijn waar.
    4. Beide stellingen zijn onwaar.

Antwoorden zelftest

Antwoorden

  1. a (voor de wijsneuzen die d hebben gekozen: waarom lees je dit boek als je weet dat empty() officieel geen functie maar een taalconstructie is? In PHPBoek(); wordt geen onderscheid gemaakt tussen functies en taalconstructies)
  2. c
  3. d

Oefening: raad het getal

De functie rand() genereert een willekeurig getal tussen aangegeven grenzen:

int rand ( int $min , int $max )

Om een willekeurig getal tussen 5 en 10 te genereren (inclusief 5 en 10), kan dus rand(5, 10) worden gebruikt.

Opdracht

Maak een eenvoudig spel dat de bezoeker een getal tussen 1 en 5 laat raden. De bezoeker vult een gekozen getal in een formulierveld in en verzendt het formulier. Het script controleert of het gekozen getal gelijk is aan het door rand() gegenereerde willekeurige getal.

Het spel moet de volgende functies bevatten:

  1. Er wordt gecontroleerd of het ingevulde getal daadwerkelijk tussen 1 en 5 ligt. Indien dat niet het geval is wordt de bezoeker hier op gewezen (zie tabel 4.1).
  2. Er wordt gecontroleerd of het ingevulde getal gelijk is aan een gegenereerd getal. Indien het getal juist is geraden wordt dit aan de bezoeker medegedeeld. Indien het getal niet is geraden wordt dit eveneens aan de bezoeker medegedeeld.
  3. Het invoervak blijft altijd beschikbaar om het spel nogmaals te spelen.

Uitwerking opdracht

Uitwerking

spel.php

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Raad het getal</title>
</head>
<body>
    
    <?php
    if (!empty($_POST)) { 
        //controleer of het getal tussen 1 en 5 is
        if (($_POST['getal'] < 1) || ($_POST['getal'] > 5)) {
            echo '<p>Het ingevulde getal moet tussen 1 en 5 liggen.</p>';
        }
        else {
            //genereer random getal
            $raad = rand(1,5);
            if ($_POST['getal'] == $raad) {
                echo '<p>Gefeliciteerd! Het juiste getal is inderdaad '.$raad.'.</p>';
            }
            else {
                echo '<p>Jammer, het juiste getal is '.$raad.'.</p>';
            }
        }
    }
    ?>
    
    <p>Raad het getal! Vul een getal in tussen 1 en 5 en speel mee!</p>

    <form action="spel.php" method="post">
    <input type="text" name="getal">
    <input type="submit" value="Speel!">
    </form>

</body>
</html>