logo

Extra Block Types (EBT) - Nieuwe Layout Builder ervaring❗

Extra Block Types (EBT) - gestileerde, aanpasbare bloktypes: Slideshows, Tabs, Cards, Accordions en vele andere. Ingebouwde instellingen voor achtergrond, DOM Box, javascript-plugins. Ervaar vandaag al de toekomst van layout building.

Demo EBT-modules Download EBT-modules

❗Extra Paragraph Types (EPT) - Nieuwe Paragraphs ervaring

Extra Paragraph Types (EPT) - analoge op paragrafen gebaseerde set modules.

Demo EPT-modules Download EPT-modules

Scroll

PHP-lessen - les 3.5 - Werken met MySQL-databases. De JOIN-operator. Bestanden uploaden naar de server.

09/10/2025, by Ivan

Voordat ik begon met het schrijven van deze les, heb ik lang nagedacht over de beste manier om query’s met JOIN-operatoren uit te leggen. Het punt is dat de JOIN-operator wordt gebruikt om gegevens uit meerdere tabellen tegelijk op te halen. En aangezien we nog een tweede tabel nodig hebben, gaan we die aanmaken. Ik stel voor om een tabel voor bestanden te maken, die we in deze les via een formulier zullen uploaden. Zo wordt deze les een combinatie van twee richtingen: werken met databases en werken met formulieren.

Laten we beginnen met het toevoegen van een veld voor het uploaden van een bestand. Om een formulier in staat te stellen bestanden te uploaden, moeten we het formulier een specifiek type geven in de parameters:

$content .=	'<form action="' . $_SERVER['PHP_SELF'] . '" method="post" enctype="multipart/form-data">'; 

Met de parameter enctype geven we de browser aan dat we via dit formulier bestanden zullen uploaden. Nu het formulier klaar is, voegen we een uploadveld toe:

  public function display_admin() { // methode voor berichtinvoer
	$content = '';
	
	$content .=	'<form action="' . $_SERVER['PHP_SELF'] . '" method="post" enctype="multipart/form-data">'; 
	$content .=	  '<label for="title">Naam:</label><br />';
	$content .=	  '<input name="title" id="title" type="text" maxlength="150" />';
	$content .=	  '<div class="clear"></div>';
	$content .=	  '<label for="bodytext">Bericht:</label><br />';
	$content .=	  '<textarea name="bodytext" id="bodytext"></textarea>';
	$content .=        '<input type="file" name="filename">'; // uploadveld
	$content .=	  '<div class="clear"></div>';
	$content .=	  '<input type="submit" value="Bericht toevoegen" />';
	$content .=	'</form>';	
	$content .=	'<p><a href="/index.php">Terug naar de startpagina</a></p>';

    return $content;
  }

Via een input van het type file kunnen we ons bestand uploaden. Als je het bestand opslaat en de pagina voor het toevoegen van een bericht vernieuwt, zou je nu een uploadveld voor een bestand moeten zien.

Laten we nu eens kijken hoe het bestand wordt verzonden in een POST-verzoek.

  public function write($p) { 
	print_r($p); // print het formulierarray
	print_r($_FILES); // print het array met bestanden
    $sql = 'INSERT INTO Messages (title, bodytext, created) VALUES ("'. $p["title"] . '", "' . $p["bodytext"] . '", ' . time() . ')';
    return mysql_query($sql);
  } 

Nu plaatsen we een bestand voor upload en slaan het bericht op. Alle bestanden die via het formulier worden geüpload, zijn beschikbaar in de superglobale variabele $_FILES. Ik heb een bestand geüpload en de volgende arrays ontvangen:

Array ( 
  [title] => asfasdf 
  [bodytext] => asfasdf 
) 
Array ( 
  [filename] => Array ( 
    [name] => ip.txt 
    [type] => text/plain 
    [tmp_name] => Y:\tmp\phpAA.tmp 
    [error] => 0 
    [size] => 13 
   ) 
) 

Nu we een array met gegevens en een bestand hebben, maken we een tabel voor bestanden waarin we de geüploade bestanden opslaan. Maak eerst een map files in de root van je website. Als je op Linux werkt of op een hostingomgeving, geef deze map dan rechten 777, zodat het script bestanden erin kan opslaan.

We passen de query voor het maken van tabellen in de methode buildDB() aan:

$sql = "CREATE TABLE Messages
(
mid int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(mid),
title varchar(15),
bodytext text,
created  int(11),
file int(11),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE Files
(
fid int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(fid),
filename varchar(255),
filepath varchar(255),
filemime varchar(255),
filesize int(10),
timestamp int(10),
)ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;";

Naast het toevoegen van een nieuwe tabel voegen we ook een veld fid toe, dat de externe sleutel voor de bestandstabel zal zijn. Voor de nieuwe tabel Files gebruiken we de volgende velden:

fid - de primaire sleutel van onze tabel, het nummer van het bestand.

filename - de naam van het bestand.

filepath - het pad naar het bestand vanaf de root van de site.

filemime - het MIME-type van het bestand, om te weten wat voor soort bestand het is en waarvoor het gebruikt kan worden (bijv. text/plain voor tekstbestanden, of image/jpg, image/png voor afbeeldingen).

filesize - de bestandsgrootte in bytes.

timestamp - het tijdstip waarop het bestand is geüpload.

Nu slaan we het bestand op en schrijven we een query om het bestand in de database toe te voegen. Je kunt de benodigde velden ook via phpMyAdmin aanmaken.

 if($_FILES["filename"]["size"] > 1024*3*1024)
   {
     echo ("Bestandsgrootte overschrijdt drie megabyte");
     exit;
   }
   // Controleren of het bestand is geüpload
   if(is_uploaded_file($_FILES["filename"]["tmp_name"]))
   {
     // Als het bestand succesvol is geüpload, verplaatsen we het
     // van de tijdelijke map naar de uiteindelijke map
     move_uploaded_file($_FILES["filename"]["tmp_name"], "/files/".$_FILES["filename"]["name"]);
   } else {
      echo("Fout bij uploaden van bestand");
   }

Zo slaan we het bestand op in de map files. Na succesvolle upload voegen we het bestand toe aan de database met de volgende query:

$sql = 'INSERT INTO Files (filename, filepath, filemime, filesize, timestamp) 
VALUES ("'. $_FILES['filename']['name'] . '",
"files/' . $_FILES['filename']['name'] . '",
"'. $_FILES['filename']['type'] .'",
'. $_FILES['filename']['size'] .',
'. time() . ')';  

mysql_query($sql);   

Nu we het bestand in de database hebben ingevoegd, moeten we ook het bericht invoegen. We passen de insert-query voor berichten iets aan en voegen het veld fid toe.

   $sql = 'INSERT INTO Messages (title, bodytext, created, fid) VALUES ("'. $p["title"] . '", "' . $p["bodytext"] . '", ' . time() . ',LAST_INSERT_ID())';

Let op de functie last_insert_id(). Dit is een MySQL-functie die het laatst ingevoegde ID retourneert uit welke tabel dan ook. In ons geval is dat de laatst ingevoegde record in de bestandstabel.

Nu worden de records ingevoegd in beide tabellen. We hoeven ze alleen nog maar weer te geven met behulp van de JOIN-operator. Laten we de query aanpassen om ook de bestandsnaam weer te geven:

  public function display_public() { // methode voor weergave van berichten
    $content = '';
	$sql = 'SELECT * FROM Messages LEFT JOIN Files ON Messages.fid=Files.fid ORDER BY mid DESC';
	$result = mysql_query($sql) or die(mysql_error());  
...

In dit geval gebruik ik de JOIN-operator samen met LEFT. Het combineren van tabellen voor selectie kan op verschillende manieren, en in een van de volgende lessen zullen we JOIN uitgebreider behandelen. Voor nu is het voldoende om te weten dat LEFT JOIN alle records toont, inclusief die zonder een fid-waarde.

Als we nu het queryresultaat printen:

  public function display_public() { // methode voor weergave van berichten
    $content = '';
	$sql = 'SELECT * FROM Messages LEFT JOIN Files ON Messages.fid=Files.fid ORDER BY mid DESC';
	$result = mysql_query($sql) or die(mysql_error());  
	while($row = mysql_fetch_array($result)){ // het resultaat moet worden verwerkt met mysql_fetch_array()
	  print_r($row);

Dan zien we dat zowel de gegevens uit de berichtentabel als uit de bestandstabel worden weergegeven. Als er geen bijbehorend bestand is, blijven de velden leeg. Daarom moeten we deze velden controleren.

	  if(!empty($row['filename'])){
	    $content .= '<p>Bijlage: <a target="_blank" href="/'. $row['filepath'] .'">'. $row['filename'] .'</a></p>';
	  }

Nu wordt samen met het bericht ook de bijlage weergegeven als een link naar het door ons geüploade bestand. In de volgende les zullen we de krachtige JOIN-operator uitgebreider bekijken, die het mogelijk maakt om gegevens uit meerdere tabellen tegelijk op te halen. Bij de bijlagen zal ik voortaan ook een actuele database-dump toevoegen, gemaakt via phpMyAdmin.