Informaticasite van het Sondervick College te Veldhoven                 © L.J.M van Haperen (bron : R.J. van der Beek)
 

Hoofdstuk 19. PHP en MySQL

19.5 SQL toepassen in PHP-documenten.

We gaan in dit hoofdstuk bespreken hoe je m.b.v. PHP gegevens uit een database kunt bekijken, invoeren en wijzigen. We gaan er daarbij van uit dat je de database tennisvereniging hebt aangemaakt (zie het vorige hoofdstuk), met één tabel: leden. En die tabel heeft zeven velden, namelijk lidnr, naam, woonplaats, geboren, leeftijd, lidsoort en score.
Verder heeft de gebruiker met de gebruikersnaam leerling en het wachtwoord lc2006 het recht om met die database te werken.

  19.5.1. Een verbinding maken met MySQL m.b.v. PHP

Als je met SQL wilt werken in PHP moet je er eerst voor zorgen dat MySQL wordt opgestart, dat er bekend is op welke computer dat gebeurt, en welke gebruiker er gebruik van gaat maken.
De opdrachten daarvoor zijn:

$host="localhost";
$gebruiker="leerling";
$wachtwoord="lc2006";
$verbinding=mysql_connect($host,$gebruiker,$wachtwoord);

(in sommige versies van PHP moeten de variabelen beslist tussen aanhalingstekens, dus $verbinding=mysql_connect('$host','$gebruiker','$wachtwoord'); )

Het kan ook m.b.v. één opdracht, namelijk als volgt:
(maar meestal wordt het bovenstaande gebruikt, als er iets aangepast moet worden is die manier handiger)

$verbinding=mysql_connect("localhost","leerling","lc2006");

De variabele $verbinding krijgt dan een waarde (een getal) waarmee de server de verbindingsgegevens terug kan vinden.

Maar als er iets niet klopt zal er een foutmelding verschijnen. Als je bijvoorbeeld als gebruikersnaam leerlin intikt i.p.v. leerling, en het php-script wordt uitgevoerd, dan verschijnt er:
Warning: mysql_connect() [function.mysql-connect]: Access denied for user: 'leerlin@localhost' (Using password: YES) in c:\wamp\www\testen\tennisvereniging1.php on line 11

Als je wilt dat het script dan op een normale manier stopt en je eigen foutmelding verschijnt, dan kun je bijvoorbeeld de volgende regel toevoegen:
if (!$verbinding) die ("<br>Kan geen verbinding maken met de database, het script wordt afgebroken");
Dat betekent: als $verbinding geen waarde heeft gekregen, dus als er geen verbinding is, druk dan de zin die tussen aanhalingstekens staat af en stop met het script.
Maar de eerste foutmelding verschijnt ook nog steeds. Die kun je echter voorkomen door voor de regel met $verbinding=mysql_connect($host,$gebruiker,$wachtwoord); de opdracht error_reporting(0); te zetten.
Die laatste opdracht heeft tot gevolg dat er geen foutmeldingen van de server meer verschijnen.

Als je het php-script maakt, en het nog niet door anderen gebruikt wordt, is het juist handig als er wel foutmeldingen verschijnen. Want het lukt je bijna nooit een script te maken zonder foutjes door vergissingen. Daarom kun je dan beter een regel met error_reporting(E_ALL); toevoegen, dan verschijnen alle foutmeldingen.

  19.5.2. De gegevens van een tabel tonen

Als er een verbinding gemaakt is kun je SQL-opdrachten geven, waarmee de gegevens getoond en gewijzigd kunnen worden.
De SQL-query voor het tonen van alle records van de tabel leden van de tennisvereniging (en alle kolommen van de records) is: SELECT * from leden
Als je dit met een script wilt doen dan heb je aantal opdrachten nodig:
  • Je moet beginnen met de volgende PHP-opdrachten:

    $dbnaam="tennisvereniging";
    $sql="SELECT * from leden";
    $result = mysql_db_query($dbnaam,$sql,$verbinding);

    (in sommige versies van PHP moeten de eerste twee variabelen beslist tussen aanhalingstekens, dus: $result = mysql_db_query('$dbnaam','$sql',$verbinding); )

    Maar de ene opdracht $result = mysql_db_query($dbnaam,$sql,$verbinding); kun je ook splitsen in twee opdrachten.
    Die manier is vooral handig als je verschillende queries wilt laten uitvoeren.
    Het gaat dan op de volgende manier:

    $dbnaam="tennisvereniging";
    mysql_select_db($dbnaam,$verbinding);

    $sql="SELECT * from leden";
    $result = mysql_query($sql);

    Maar dan worden de gegevens nog niet getoond, ze worden in een array met de naam $result gezet.

    De opdracht mysql_db_query("naam van de database","sql-query", verbindings-variabele); zorgt er voor dat de sql-query wordt uitgevoerd, en dat het resultaat in een array wordt gezet.

  • Er kan natuurlijk ook weer een fout optreden, bijvoorbeeld als de sql-query niet klopt.
    Om ervoor te zorgen dat er dan een melding van jezelf komt, en geen foutmelding van de server (waarschijnlijk onbegrijpelijk voor de bezoeker van de site), moet je de opdracht als volgt geven:
    $result = mysql_db_query($dbnaam,$sql,$verbinding) or die ("De sql-query is niet uitgevoerd, het script wordt afgebroken");
    Dat betekent: als $result geen waarde heeft gekregen, dus als er een fout is opgetreden, druk dan de zin die tussen aanhalingstekens staat af en stop met het script.

  • Het aantal rijen van de resultaattabel krijg je met de volgende opdracht:
    $aantal_rijen=mysql_num_rows($result);

  • Het aantal kolommen van de resultaattabel krijg je met de volgende opdracht:
    $aantal_velden=mysql_num_fields($result);

  • De naam van de eerste kolom van de tabel krijg je met de volgende opdracht:
    $naam_veld=mysql_field_name($result,0);
    De naam van de tweede kolom krijg je met de opdracht: $naam_veld=mysql_field_name($result,1);
    De naam van de derde kolom met: $naam_veld=mysql_field_name($result,2); enz.
    Denk er om dat er bij het tellen begonnen wordt bij 0 !

  • De eerste rij van de resultaattabel krijg je met de volgende opdracht:
    $rij=mysql_fetch_row($result);
    Dat is dan een array, en $rij[0] bevat dan de eerste kolom van die rij, $rij[1] bevat de tweede kolom, $rij[2] bevat de derde kolom, enz.
    Als je die wilt afdrukken kan dat bijvoorbeeld met de opdracht:
    print ($rij[0]."       ".$rij[1]."       ".$rij[2]."       ".$rij[3]);
    (ze worden dan achterelkaar afgedrukt met een aantal spaties ertussen, denk er om dat ook hier bij het tellen bij 0 wordt begonnen!)

  • De tweede rij van de resultaattabel krijg je als dezelfde opdracht als hierboven nog eens voorkomt:
    $rij=mysql_fetch_row($result);
    En zo kun je alle rijen krijgen door die opdracht maar vaak genoeg te herhalen. De server houdt bij welke rij aan de beurt is.

  • Als je niet meer verder wilt werken met de database in het php-script dan hoor je de verbinding netjes af te sluiten met de opdracht:
    mysql_close($verbinding);
Nu het complete script:

<html>
<head><title>PHP met MySQL</title></head>
<body>  
<?php 
$host="localhost";
$gebruiker="leerling";
$wachtwoord="lc2006";
error_reporting(0);
$verbinding=mysql_connect($host,$gebruiker,$wachtwoord);
if (!$verbinding) die ("<br>Kan geen verbinding maken met de database, 
het script wordt afgebroken"); $dbnaam="tennisvereniging"; $sql="SELECT * from leden"; $result = mysql_db_query($dbnaam,$sql,$verbinding); $aantal_rijen=mysql_num_rows($result); echo "aantal rijen van de tabel = $aantal_rijen<br>\n"; $aantal_velden=mysql_num_fields($result); echo "aantal velden van de tabel = $aantal_velden<br>\n"; for($i=0;$i<$aantal_velden;$i++) { $naam_veld=mysql_field_name($result,$i); echo "Veld nr. $i is $naam_veld<br>\n"; } for($r=0;$r<$aantal_rijen;$r++) { $row=mysql_fetch_row($result); print ("<br>record nr. $r<br>"); for($i=0;$i<$aantal_velden;$i++) { print ("kolom"."$i: "."$row[$i]"."<br>"); } } mysql_close($verbinding); ?> </body></html>

Start de Verkenner, en ga naar de map C:\wamp\www
Maak in die map een nieuwe map met de naam testmap aan.
Tik bovenstaand script in m.b.v. Kladblok of een andere editor (knippen en plakken kan ook), en sla het op onder de naam mysqltest.php in de netgemaakte map C:\wamp\www\testmap

Start dan je browser, en tik op de adresregel localhost in. Dan wordt index.php van de map C:\wamp\www getoond
Je ziet dan het volgende:



Klik dan op de map testmap. Dan worden de bestanden, die in die map staan, getoond.
Klik op mysqltest.php
Dan wordt het script uitgevoerd, en dan zie je het volgende (als alles goed gaat):
(Het ziet er nog niet fraai uit, maar dat is van later zorg. Eerst moet je de principes kennen)

  19.5.3. Gegevens invoeren m.b.v. SQL

Je kunt een html-document maken met een formulier, waarmee gegevens van de leden van de tennisvereniging kunnen worden ingevoerd.
En dan kun je er voor zorgen dat die gegevens aan de database worden toegevoegd.
Eerst de code voor het formulier, dat kan er als volgt uitzien:

<html>
<head>
<title>Toevoegen aan de tabel leden van de tennisvereniging</title>
</head>
<body>

<form ACTION="verwerk.php" METHOD="post">
<table>
   <tr>
       <td>Naam: </td>
       <td> <input type="text" name="naam" size="30"></td>
   </tr> 
   <tr>
       <td>Woonplaats: </td>
       <td><input type="text" name="woonplaats" size="20"></td>
   </tr> 
   <tr>
       <td>Geboren (yyyy-mm-dd): </td>
       <td> <input type="text" name="geboren" size="10"></td>
   </tr> 
   <tr>
       <td>Leeftijd: </td><td>
       <input type="text" name="leeftijd" size="10"></td>
   </tr> 
   <tr>
       <td>Lidsoort: </td>
       <td> <input type="text" name="lidsoort" size="30"></td>
   </tr> 
   <tr>
       <td>Score: </td>
       <td> <input type="text" name="score" size="10"></td>
   </tr> 
   <tr>
     <td> </td>		
     <td>
     <input type="submit" value="Voeg dit lid toe aan de tabel leden !!">
     </td>
   <tr>
</table>

</form> 
</body></html>

Als je dit m.b.v. een browser bekijkt dan ziet het er zo uit:



Als je op de knop klikt met "Voeg dit lid toe aan de tabel leden" dan wordt het script verwerk.php uitgevoerd.
  • Ok daarin komt weer de opdracht voor om de verbinding met MySQL plaats te doen vinden, dus de volgende opdrachten:
    $host="localhost";
    $gebruiker="leerling";
    $wachtwoord="lc2006";
    $verbinding=mysql_connect($host,$gebruiker,$wachtwoord);


  • Verder moet er een sql-query worden uitgevoerd om de gegevens aan de tabel van het tennisvereniging toe te voegen, en die query luidt als volgt:
    $sql="INSERT into leden (naam, woonplaats, geboren, leeftijd, lidsoort, score) VALUES ('$naam','$woonplaats','$geboren','$leeftijd','$lidsoort','$score')";

  • Je ziet dat de eerste kolom van de tabel, het lidnummer, hier niet in voorkomt. Dat is ook niet nodig want er is aangegeven dat die kolom van het type int is en dat het auto-increment is, en dat betekent dat dat getal door de server zelf wordt bepaald en vastgelegd als er een rij aan de tabel wordt toegevoegd.

  • De opdracht die er voor zorgt dat de sql-query wordt uitgevoerd is (net zo als in de vorige paragraaf): $result = mysql_db_query($dbnaam,$sql,$verbinding);
    Daarbij bevat $dbnaam de naam van de databse, $sql de sql-query, en $verbinding de verbindingswaarde.

  • Ook nu kun je zorgen voor je eigen foutmelding m.b.v. if (!result) die ("Er treedt een fout op");
    Maar het kan ook anders.
    mysql_errno($verbinding); levert het foutnummer op, als er een fout optreedt, en als er geen fout optreedt krijgt het de waarde 0.
    Je kunt dus op de volgende manier ook zorgen voor je eigen foutmelding:
    $fout = mysql_errno($verbinding);
    if ($fout != 0)
                {
                print ("Er treedt een fout op");
                mysql_close($verbinding);
                }
De code van het totale script volgt hieronder.

<HTML>
<HEAD>
<TITLE>Verwerking van een toevoeging aan het tennisvereniging</TITLE>
</head> 
<body>
<H1>Een lid toevoegen aan de tabel leden van de tennisvereniging</H1><hr>

<?php
  $naam=strip_tags(stripslashes(trim($_POST['naam'])));
  $woonplaats=strip_tags(stripslashes(trim($_POST['woonplaats'])));
  $geboren=strip_tags(stripslashes(trim($_POST['geboren'])));
  $leeftijd=strip_tags(stripslashes(trim($_POST['leeftijd'])));
  $lidsoort=strip_tags(stripslashes(trim($_POST['lidsoort'])));
  $score=strip_tags(stripslashes(trim($_POST['score'])));

  Je hebt de volgende dingen ingevuld:<br><br>
  print ("Naam: $naam<br>\n");
  print ("Woonplaats: $woonplaats<br>\n");
  print ("Geboren: $geboren<br>\n");
  print ("Leeftijd: $leeftijd<br>\n");
  print ("Lidsoort: $lidsoort<br>\n");
  print ("Score: $score<br>\n");
  print (" <br>\n");
  print (" <br>\n");
  $doorgaan=true;
      
if ($naam=="" or $woonplaats=="" or $geboren="" or $leeftijd="") 
{
  print("Je hebt geen naam, woonplaats, geboortedatum of leeftijd ingevuld.
  Dit wordt niet in de leden-tabel opgenomen.<br>\n");
  $doorgaan=false; 
}

if ($doorgaan==true)
{ 
  $host="localhost";
  $gebruiker="leerling";
  $wachtwoord="lc2006";
  error_reporting(0);
  $verbinding=mysql_connect($host,$gebruiker,$wachtwoord);
  if (!$verbinding) die ("<br>Kan geen verbinding maken met de database, 
  de gegevens worden niet vastgelegd in de leden-tabel"); 

  $dbnaam="tennisvereniging";
  $sql="INSERT into leden 
  (naam, woonplaats, geboren, leeftijd, lidsoort, score) 
  VALUES 
  ('$naam','$woonplaats','$geboren','$leeftijd','$lidsoort','$score')";
  $result = mysql_db_query($dbnaam,$sql,$verbinding);
  $fout=mysql_errno($verbinding);
  if ($fout != 0) 
  {
     echo "Er treedt een fout op, de gegevens worden niet weggeschreven";
     mysql_close($verbinding);
  }
  else 
  {
     echo "De gegevens werden correct weggeschreven naar de database";
     mysql_close($verbinding);
  }
}
?>
</body></html>

  19.5.4. SQL-queries invoeren m.b.v. een formulier

Je kunt een html-document maken met een formulier, waarmee je een sql-query kunt invoeren.
En dan kun je er voor zorgen dat die query wordt uitgevoerd.
Welke queries je kunt invoeren staat uitgelegd in de cursus SQL, die queries kun je uitproberen.

Eerst de code voor het formulier, dat is heel simpel want er hoeft maar één tekstvenster te verschijnen, en in dat tekstvenster kan dan een query worden ingevoerd.
En als er op de submit-knop, waarop "Voer deze query uit !!" staat, wordt geklikt moet de query worden uitgevoerd.
Dat moet dan gebeuren d.m.v. het php-script met de naam "verwerkquery.php"
Het document voor dat formulier kan er als volgt uitzien:

<html>
<head><title>SQL-query invoeren</title></head>
<body>
<form ACTION="verwerkquery.php" METHOD="post">
<br>Query:  <input type="text" name="query" size="100">
<br><br><input type="submit" value="Voer deze query uit !!">
</form> 
</body></html>

En dan nu het php-script met de naam "verwerkquery.php"

<HTML>
<HEAD>
<TITLE>Query uitvoeren</TITLE>
</head> 
<body>
<H1>Query uitvoeren op de tabel leden van de tennisvereniging</H1><hr>

<?php
      $sql=strip_tags(stripslashes(trim($_POST['query'])));
      $host="localhost";
      $gebruiker="leerling";
      $wachtwoord="lc2006";
      
      error_reporting(0); 
      $verbinding=mysql_connect($host,$gebruiker,$wachtwoord) or 
      die ("<br>Kan geen verbinding maken met de database, 
      het script wordt afgebroken"); 

      $dbnaam="tennisvereniging";
      $result = mysql_db_query($dbnaam,$sql,$verbinding) or 
      die ("<br>Er treedt een fout op bij het uitvoeren van 
      de query:<br>".mysql_error($verbinding));
      
      print ("De query is met succes uitgevoerd.<br><br>");
             
      $aantal_rijen=mysql_num_rows($result);
      $aantal_velden=mysql_num_fields($result);
	
      print ("<table border=1 bgcolor='#AAAAAA'>\n<tr>");
	
      for($i=0;$i<$aantal_velden;$i++)
      {
    	   print ("<td><font color='#FF0000'><b>");
    	   $naam_veld=mysql_field_name($result,$i);
    	   print ("$naam_veld</b></font></td>");
      }
      print ("</tr>\n");

      for($r=0;$r<$aantal_rijen;$r++) 
      {
    	   print ("<tr>");

    	   $row=mysql_fetch_row($result);
	   for($i=0;$i<$aantal_velden;$i++)
           {
        	print ("<td><font color='#00FFFF'><b>");
        	print ("$row[$i]");print ("</b></font></td>");
           }
           print ("</tr>\n");
      }        
      print ("</table>\n\n"); 
      mysql_close($verbinding);
?>
</body></html>

Uitleg:
  • Het begin zal wel duidelijk zijn, $sql krijgt de inhoud van de query, die bij het vorige formulier is ingevuld.
    De spaties aan het begin en eind worden weggehaald (trim), als er een backslash in voorkomt dan wordt die weggehaald (stripslashes), en als er tags in zitten dan worden die weggehaald (striptags).
    Denk er om dat je het commando htmlspecialchars er niet op los laat, want dan krijg je een probleem als er een kleiner-dan teken in voorkomt.

  • Dan wordt er een verbinding met MySQL gezocht.
    Als dat niet lukt, dan verschijnt er op het scherm: "Kan geen verbinding maken met de database, het script wordt afgebroken", en het script wordt afgebroken. Dat komt door het commando "die".
    Dat de officiële foutmelding niet verschijnt komt doordat het commando error_reporting(0); ervoor is uitgevoerd.

  • Dan volgt de opdracht om de query uit te voeren: $result = mysql_db_query($dbnaam,$sql,$verbinding)
    Als dat mislukt dan verschijnt er op het scherm: "Er treedt een fout op bij het uitvoeren van de query:", en daaronder verschijnt de officiële foutmelding ook nog.
    Dat komt doordat de inhoud van de variabele mysql_error($verbinding) aan de vorige zin is vastgeplakt d.m.v. de punt.
    Dat is handig, dan kan degene die de sql-query heeft ingevoerd er misschien achter komen wat er verkeerd aan was.
    En dan wordt het script afgebroken (als er een fout optrad), dat komt door het commando "die".

  • Als alles goed ging gaat het script gewoon verder, en dan wordt er eerst afgedrukt: "De query is met succes uitgevoerd"

  • Dan wordt er gekeken hoeveel rijen er in de resultaattabel van de query zitten: $aantal_rijen=mysql_num_rows($result);
    Dat aantal kan nul zijn, want alleen als het een select-query was is er een resultaat-tabel.
    Als er een insert-query, of een delete-query, of een update-query is gegeven dan is er geen resultaat-tabel, dan wordt er verder ook niets afgedrukt. Dan zie je dat de query met succes is uitgevoerd, en verder niets.
    Als het een select-query was (bijvoorbeeld select * from leden) dan wordt er een tabel afgedrukt, hoe dat gebeurt lees je hieronder:

  • Het commando print ("<table border=1 bgcolor='#AAAAAA'>\n<tr>"); heeft tot gevolg dat er een tabel verschijnt, met celranden (border = 1) en met als achtergrondkleur grijs (bgcolor='#AAAAAA')
    En de begin-tag voor een tabelrij staat er nog achter: de eerste rij van de tabel komt ( <tr> )

  • De volgende php-regels zijn:
    for($i=0;$i<$aantal_velden;$i++)
    {
    print ("<td><font color='#FF0000'><b>");
    $naam_veld=mysql_field_name($result,$i);
    print ("$naam_veld</b></font></td>");
    }
    Die hebben tot gevolg dat de namen van de velden in de cellen van de eerste rij verschijnen:
    • <td><font color='#FF0000'><b> is de begin-tag voor een cel, waarin de tekst vetgedrukt wordt ( <b> ) en roodgekleurd ( font color='#FF0000' )

    • Dan wordt de naam van het veld er in afgedrukt, en daarna volgt de eind-tag van de cel ( $naam_veld </b></font></td> )

    • De herhalingslus for($i=0;$i<$aantal_velden;$i++) zorgt ervoor dat de namen van alle velden op die manier in een cel komen op de bovenste rij.

  • Op de volgende regel staat de eind-tag voor de eerste tabelrij ( print ("</tr>\n"); )

  • Dan volgt weer een herhalingslus: for($r=0;$r<$aantal_rijen;$r++) zorgt ervoor dat de commando's eronder net zovaak worden uitgevoerd als er rijen in de resultaat-tabel van de sql-query zijn.

  • Dan volgt eerst de begin-tag voor een tabelrij: de volgende rij van de tabel komt ( print ("<tr>"); )

  • Het commando $row=mysql_fetch_row($result); zorgt ervoor dat de volgende rij van de resultaat-tabel in de variabele $row wordt gezet.

  • De volgende php-regels zijn:
    for($i=0;$i<$aantal_velden;$i++)
    {
    print ("<td><font color='#00FFFF'><b>");
    print ("$row[$i]");print ("</b></font></td>");
    }
    Die hebben tot gevolg dat de kolommen van de rij, die aan de beurt is, in de volgende cellen verschijnen.
    • <td><font color='#00FFFF'><b> is de begin-tag voor een cel, waarin de tekst geelgekleurd wordt ( font color='#00FFFF' )

    • Dan wordt de kolom er in afgedrukt, en daarna volgt de eind-tag van de cel ( $row[$i] </b></font></td> )

    • De herhalingslus for($i=0;$i<$aantal_velden;$i++) zorgt ervoor dat de namen van alle kolommen op die manier in een cel komen van de betreffende rij.

  • Op de volgende regel staat de eind-tag voor de betreffende tabelrij ( print ("</tr>\n"); )

  • De herhalingslus for($r=0;$r<$aantal_rijen;$r++) zorgt ervoor dat er net zoveel rijen worden afgedrukt als er rijen in de resultaat-tabel van de sql-query zijn.

  • Daarna volgt de eind-tag van de tabel ( print ("</table>\n\n"); )

  • En tenslotte wordt de verbinding met MySQL afgesloten ( mysql_close($verbinding); )
Als alles werkt, en je voert de query SELECT * FROM leden; in, dan moet de volgende tabel verschijnen:

lidnrnaamwoonplaatsgeborenleeftijdlidsoortscore
1AnnieBuitenpost1944-06-0262senior2075
2WillemVeenklooster1992-09-1314jeugdlid987
3HillegienKollum1968-01-1138senior1598
4MargreetKollum1980-09-1826aktielid234
5ElineBuitenpost1996-11-0410jeugdlid435
6GerritTwijzel1958-05-0448senior5989
7FemkeAugustinusga1993-09-1913jeugdlid798
8DonaBurum2000-05-156mkmt155
9ChrisBurum1998-12-127mkmt236
10DieuwkeBuitenpost1959-09-0647senior7345
11KeesVeenklooster1965-07-2741senior6345
12LeonAugustinusga1980-06-0626aktielid380
13SabineDrogeham1970-11-1036senior4999
14FemkeDrogeham1979-07-0627senior3768

  19.5.5. Een andere manier om een verbinding te maken met SQL

Om een verbinding te maken met MySQL kun je ook de volgende opdrachten gebruiken:

$host="localhost";
$gebruiker="leerling";
$wachtwoord="lc2006";
$dbnaam="tennisvereniging";
$sql="SELECT * from leden";
mysql_connect($host,$gebruiker,$wachtwoord);
$result = mysql_db_query($dbnaam,$sql);

de laatste opdracht kan ook nog gesplitst worden:

mysql_select_db($dbnaam);
$result =mysql_query($sql);