Learnit Training

7. Uitgebreid Voorbeeld

In dit hoofdstuk gaan we alles wat we hiervoor hebben geleerd samenvoegen: we gebruiken formulieren, programmeer technieken en SQL om met de database te communiceren.

We gaan verder met het formulier dat we in hoofdstuk 4 (over formulieren) al maakten. Bij de verwerking van dit reactie formulier, dat voor bezoekers van een website bedoeld is, gaan we gegevens in de database opslaan. Daarnaast maken we een systeem voor de beheerder van een website om reacties te bekijken, aan te passen en weg te gooien.

7.1. Opslaan in de database

In verwerk.php controleerden we de invoer, en lieten we deze weer in de browser zien. We bewaarden de data nog niet. Dat gaan we nu wel doen.

Opdracht 7.1

  1. Maak in phpcursus/ een map 7/ aan.
  2. Sla form.html op in phpcursus/7/ (rechtermuisknop, doel opslaan als).
  3. Sla deze programmacode op als verwerk.php op in phpcursus/7/.
  4. Bekijk de bron van phpcursus/7/verwerk.php door het te openen in kladblok
  5. Bestudeer wat er gebeurt, er zijn een aantal dingen veranderd:
    • Er zijn stukken tekst die commentaar heten toegevoegd, ze beginnen steeds met //. Deze code wordt niet uitgevoerd en dient slecht om de code voor een programmeur leesbaarder te maken.
    • De variabele $correct is toegevoegd. Deze variabele houdt bij of er fouten worden gemaakt. Zodra we een fout tegenkomen zetten we de boleaanse variabele $correct op false (het is niet correct).
    • Het onderste stuk code is helemaal nieuw:
      //Was alles correct ingevuld?
      if ($correct) { // Opslaan!
      	// Vul hier de code in om de reactie op te slaan!
      	echo "<br /><br />Bovenstaande informatie is opgeslagen!<br />\n";
      	}
      else {
      	// Er is ergens een foute waarde ingevoerd, geef de bezoeker de 
      	// mogelijkheid om terug te gaan
      	echo "<br /><br />Er is een foute waarde ingevoerd,
      		 <a href=\"javascript:history.back();\">ga terug</a>.<br />\n";
      	}
      
      Op de plek van //Vul hier de code in om de reactie op te slaan! gaan we zometeen de code invoegen die de data op gaat slaan.
  6. Controleer wat het formulier doet door naar in uw browser naar http://localhost/phpcursus/7/form.html te surfen.
  7. Verander de regel //Vul hier de code in om de reactie op te slaan! in:
    $db = new PDO('mysql:host=localhost;dbname=reacties', 'root', '');
    
    //kijk of een persoon al bestaat
    $query = "SELECT id FROM personen WHERE naam = ? AND email = ?";
    $stmt = $db->prepare($query);
    $stmt->execute(array( $naam, $email));	
    
    if ($stmt->rowCount() > 0){
    	$row = $stmt->fetch(PDO::FETCH_ASSOC);
    	$persoon_id	= $row['id'];
    } else { // Voeg de naam en e-mail toe in de tabel personen
    	$query = "INSERT INTO personen(naam, email) VALUES (?, ?)";
    	$stmt = $db->prepare($query);
    	$stmt->execute(array( $naam, $email));	
    	
    	//vraag de id van de nieuwe persoon op
    	$persoon_id = $db->lastInsertId();
    }
    
    // voeg de reactie toe in de tabel reacties. Gebruik de id van de zojuist toegevoegde persoon
    $query = "INSERT INTO reacties(persoon_id, reactie, datum) VALUES (?, ?, ?)";
    $stmt = $db->prepare($query);
    $stmt->execute(array( $persoon_id, $reactie, date('Y-m-d H:i:s')));	
    

    In het bovenstaande staan een hoop nieuwe dingen die we hier even bespreken. Eerst wordt er een verbinding met de MySQL server gemaakt. Hierbij maken we gebruik van de PHP Data Object extensie. Deze PHP extensie maakt het mogelijk om vanuit ons PHP script met de database communiceren.

    Onze MySQL server draait op de localhost en we loggen in met het root account (eigenlijk is dit niet netjes, maar voor deze demonstratie het eenvoudigst), hier is geen wachtwoord voor nodig. De code om in te loggen ziet er daarom als volt uit:

    $db = new PDO('mysql:host=localhost;dbname=reacties', 'root', '');
    

    Het resultaat is een nieuw database object. Deze wordt opgeslagen in de variabele $db. Dit object kunnen we gebruiken om met de database te communiceren.

    Hierna maken we SQL queries, die u waarschijnlijk uit het vorige hoofdstuk herkent. Er is echter een groot verschil. Op de plek waar de naam en het e-mailadres moeten komen staat een ?, de zogenaamde placeholder. Door gebruik te maken van deze placeholder beschermen we ons tegen SQL injecties. Dit is een veel voorkomende aanval, waarbij hackers hun eigen SQL code proberen toe te voegen aan de query. Helaas kunnen we hier niet in detail op in gaan. Gelukkig is er veel online informatie beschikbaar over SQL injecties.

    We vragen de database de query voor te bereiden met $stmt = $db->prepare($query);. Hierna voeren we de queries uit met $stmt->execute(array( $naam, $email));. Pas nu bij het uitvoeren worden de variabelen $naam en $email meegegegeven. De SQL server plaats deze in de query op de plaats van de vraagtekens.

    Voor we de persoon toevoegen kijken we eerst, met behulp van een SELECT of er al een persoon bestaat met de naam en het e-mailadres die ingevuld zijn.

    De functie $db->lastInsertId(); zorgt ervoor dat het id van de laatste uitgevoerde query gebruikt wordt, hierdoor wordt een reactie aan de juiste persoon gekoppeld.

  8. Test het nieuwe script door weer naar het formulier te gaan en een aantal reacties toe te voegen. Zorg ervoor dat er personen zijn die meerdere berichten in de database hebben staan. U kunt de toegevoegde record bekijken met behulp van PHPMyAdmin http://localhost/phpmyadmin
  9. Download hier eventueel de nieuwe versie van de programmacode voor verwerk.php (overschrijf de oude verwerk.php).
Als het allemaal goed is gegaan heeft u de database gevuld met nieuwe gegevens, we gaan nu een simpel script maken om deze gegevens weer te geven.

7.2. Data weergeven

Uit het vorige hoofdstuk weten we nog hoe we data uit verschillende tabellen moeten combineren. We passen de query nog een beetje aan door een ORDER BY commando toe te voegen:

SELECT personen.naam, personen.email, reacties.reactie, reacties.datum
FROM personen, reacties
WHERE reacties.persoon_id = personen.id
ORDER BY reacties.datum

Als we dat niet doen worden de rijen in een niet gedefinieerde volgorde terug gegeven.

Onderstaand php script geeft alle reacties weer:

<html>
<head>
	<title>Reacties</title>
</head>
<body>
<table>
<?php

	$db = new PDO('mysql:host=localhost;dbname=reacties', 'root', '');
	
	// Selecteer alle reacties met naam en e-mailadres van de auteur
	$query = 	"SELECT reacties.id, personen.naam, personen.email, reacties.reactie, reacties.datum 
				FROM personen, reacties 
				WHERE reacties.persoon_id = personen.id 
				ORDER BY reacties.datum";
	$result = $db->query($query);
	
	while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
		echo "<tr><td>van <a href='mailto:" . $row["email"] . "'>" . $row["naam"] . "</a></td>
			  <td>op " . $row["datum"]  . "</td></tr>\n";
		echo "<tr><td colspan='2'>" . $row["reactie"]  . "</td></tr>\n";
		echo "<tr><td colspan='2'> </td></tr>\n"; //pas deze regel aan!
	}
?>
</table>
</body>
</html>
In dit script maken we wederom verbinding met de MySQL server, selecteren we een server en vervolgens voeren we SELECT commando uit. Daarna maken we een lus door de resultaten van de query heen met behulp van de while-lus. We printen het resultaat in een HTML tabel.

Opdracht 7.2.

  1. Sla reacties.php op in phpcursus/7/ (rechtermuisknop, doel opslaan als).
  2. phpcursus/7/reacties.php komt overeen bovenstaand script.
  3. Surf naar http://localhost/phpcursus/7/reacties.php om alle reacties die u eerder invoerde te bekijken.
  4. Bekijk via de browser de HTML code die met het reacties.php script is gegenereerd.

7.3. Verwijder data

We gaan phpcursus/7/reacties.php zo aanpassen dat er een knopje op komt om reacties te verwijderen. In het bestand is al aangegeven waar dit knopje moet komen, namelijk op de regel waar staat: //pas deze regel aan!. We gaan op die regel een linkje naar verwijder.php plaatsen en sturen het id van de reactie mee. Het verwijderen zelf wordt afgehandelt door het verwijder.php script:

<html>
<head>
	<title>Verwijderd</title>
</head>
<body>
<?php
// Controleer of we daadwerkelijk een integer (geheel getal) hebben binnen gekregen
if ( isset($_GET['reactie_id']) && filter_var($_GET['reactie_id'], FILTER_VALIDATE_INT )){
	$reactie_id = $_GET['reactie_id'];

	// We maken verbinding met de database
	$db = new PDO('mysql:host=localhost;dbname=reacties', 'root', '');
	
	$query = "DELETE FROM reacties WHERE id = ? ";
	$stmt = $db->prepare($query);
	$stmt->execute(array($reactie_id));
	echo 'De reactie is verwijderd!<br  />';
	echo 'Ga terug naar de <a href="reacties.php">reacties</a>.<br />';

} else {
	echo "Ongeldige aanvraag";
}
?>
</body>
</html>

Opdracht 7.2.

  1. Sla verwijder.php op in phpcursus/7/. Let op dat het bestand moet worden opgeslagen met de extensie .php
  2. Open phpcursus/7/reacties.php in kladblok
  3. Verander de regel met //pas deze regel aan! in:
        echo "<tr><td colspan='2'><a href='verwijder.php?reactie_id=" . $row["id"]  . "'>
            verwijder</a></td></tr>\n";
    
  4. Ga naar het reactie overzicht http://localhost/phpcursus/7/reacties.php Controleer of reactie daadwerlijk verwijdert zijn na klikken op de link.