CRUD

CRUD als basis voor gegevensbeheer

De term CRUD is nauw verbonden met het beheer van digitale gegevens. CRUD is een afkorting, afgeleid van de namen van de vier fundamentele bewerkingen in databasetoepassingen:

  • Create (gegevensrecord aanmaken)
  • Read of Retrieve (gegevensrecord lezen)
  • Update (gegevensrecord bijwerken)
  • Delete of Destroy (gegevensrecord verwijderen)

Eenvoudig gezegd bestaat de term CRUD uit alle functies die een gebruiker nodig heeft om gegevens aan te maken en te beheren. Verschillende datamanagementprocessen zijn gebaseerd op CRUD, waarbij de operations (bewerkingen) specifiek zijn aangepast aan de eisen van het systeem en de gebruiker, ongeacht of het gaat om het beheren van databases of het gebruik van applicaties. De operations vormen de typische en onmisbare toegangstools waarmee experts databaseproblemen kunnen controleren, terwijl CRUD voor een gebruiker betekent dat ze op elk moment een account kunnen aanmaken (create) en gebruiken (read), bijwerken (update) of verwijderen (delete). In verschillende taalomgevingen worden CRUD-bewerkingen overigens verschillend uitgevoerd, zoals weergegeven in de volgende tabel:

CRUD-bewerking SQL RESTful http XQuery
Create INSERT POST, PUT insert
Read SELECT GET, HEAD copy/modify/return
Update UPDATE PUT, PATCH replace, rename
Delete DELETE DELETE delete

CRUD-frameworks: toegangslaag voor databanken

Als afzonderlijke gegevensobjecten met een grafische gebruikersinterface worden gevisualiseerd en via de vermelde CRUD-bewerkingen kunnen worden gewijzigd, spreken we van een CRUD-framework of CRUD-grid. De interfaces zijn meestal HTML-interfaces. Een CRUD-framework vereist meerdere transactiestappen, waardoor bijvoorbeeld gegevens niet via eenvoudige invoer worden overgedragen, maar pas na het klikken op een knop ‘Opslaan’ of ‘Doorgaan’. Je kunt de bewerkingen van een CRUD-framework ook met een grote vertraging laten uitvoeren, zonder het datarecord in deze periode voor andere gebruikers te vergrendelen. Dit is met name van belang in systemen waarin meerdere gebruikers dezelfde gegevens tegelijkertijd moeten kunnen lezen.

Voor de uitvoering van de operations worden zogenaamde persistentielagen gebruikt, die meestal als uitbreidingen (modules) in het framework zijn opgenomen of daarin kunnen worden geïmplementeerd. Deze splitsen de relationele, tabelachtige weergave van de datasets af en presenteren ze in plaats daarvan op objectgeoriënteerd niveau. CRUD-frameworks maken de ontwikkeling en het gebruik van applicaties eenvoudiger door de toegang tot het gebruikte databanksysteem te optimaliseren. Er bestaan talloze frameworks met een CRUD-concept, gebaseerd op verschillende talen en platforms. We geven een paar voorbeelden:

Taal of platform Framework
Java JDBC (The Java Database Connectivity), Hibernate, JBoss Seam, Isis
PHP Yii, CakePHP, Zikula, Symfony, TYPO3 Flow
Perl Catalyst, Gantry
Python Django, SQLAlchemy, web2py
Groovy Grails
.NET NHibernate, ADO.NET/Entity Framework
Ruby Ruby on Rails
JavaScript Backbone.js, AngularJS

Zo ontwikkel je een CRUD-PHP-grid voor je database

Hieronder lees je hoe je een bootstrap-interface kunt maken voor het meest gebruikte databasesysteem MySQL, zodat toegang via CRUD-operations mogelijk wordt. Ook bespreken we de create-operation. Om de databasetabellen op de juiste wijze te manipuleren, gebruiken we de scripttaal PHP aan de serverzijde met behulp van een extensie, PDO (PHP Data Objects).

1. De eerste stap is het maken van een eenvoudige databasetabel die we later in deze tutorial via CRUD-toegang manipuleren. Hiervoor importeer je de volgende tabel met voorbeelden in je MySQL-database:

CREATE TABLE `customers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 100 ) NOT NULL ,
`email` VARCHAR( 100 ) NOT NULL ,
`mobile` VARCHAR( 100 ) NOT NULL
) ENGINE = INNODB;

De tabel is nodig om gebruikersgegevens te verzamelen – naam, e-mailadres en mobiel nummer. Elke invoer ontvangt automatisch een primaire sleutel (AUTO_INCREMENT PRIMARY KEY), ofwel een eigen individuele ID.

2. Daarna is het noodzakelijk om het aanmaken en verbreken van de verbinding met de database te regelen. Maak een PHP-bestand aan met de naam database.php en voeg het volgende script toe met de klasse ‘Database’ om de databaseverbindingen te beheren:

<?php
class Database
{
private static $dbName = 'database_naam';
private static $dbHost = 'localhost';
private static $dbUsername = 'gebruikersnaam';
private static $dbUserPassword = 'wachtwoord';

private static $cont = null;

public function __construct() {
die('Init-functie niet toegestaan);
}

public static function connect() {
// Alleen een enkele verbinding tijdens de gehele sessie toestaan
if ( null == self::$cont )
{
  try
  {
    self::$cont = new PDO
    ( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName, self::$dbUsername, self::$dbUserPassword);
  }
  catch(PDOException $e)
  {
    die($e->getMessage());
  }
} 
return self::$cont;
}

public static function disconnect()
{
self::$cont = null;
}
}

Om de hier gedefinieerde klasse voor databasetoegang met PDO te gebruiken, moet je de exacte waarden specificeren voor de vier items $dbName (naam van de gebruikte database), $dbHost (naam van de host waarop de database draait - meestal localhost), $dbUsername (naam van de toegangsgebruiker) en $dbUserPassword (wachtwoord van de toegangsgebruiker).

Aan de klasse ‘Database’ zijn in dit script drie functies toegewezen: __construct() is de constructor van de klasse en herinnert gebruikers eraan dat initialisatie (de toekenning van een beginwaarde) niet is toegestaan. Bij connect() gaat het om de hoofdfunctie van de klasse die de verbinding regelt. De tegenhanger is disconnect() waarmee je de verbinding dus weer verbreekt.

3. Aangezien CRUD-bewerkingen alleen met de juiste interface kunnen worden uitgevoerd, moet het basis-grid nu met Twitter Bootstrap worden aangemaakt. De huidige versie van het framework vind je op de officiële website. Pak Bootstrap uit in de map waar database.php zich bevindt en maak een bestand aan met de naam index.php. Daarin schrijf je nu de volgende interface:

<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8">
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
<div class="container">
<div class="row">
<h3>Mijn CRUD-PHP-grid</h3>
</div>
<div class="row">
<table class="table table-striped table-bordered">
<thead>
  <tr>
    <th>Naam</th>
    <th>E-mailadres</th>
    <th>Mobiel nummer</th>
  </tr>
</thead>>
<tbody>
<?php 
include 'database.php';
$pdo = Database::connect();
$sql = 'SELECT * FROM customers ORDER BY id DESC';
foreach ($pdo->query($sql) as $row) {
echo '<tr>';
echo '<td>' . $row['name'] . '</td>';
echo '<td>' . $row['email'] . '</td>';
echo '<td>' . $row['mobile'] . '</td>';
echo '</tr>';
}
Database::disconnect();
?>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>

In het <head>-gedeelte zijn de CSS- en JavaScript-bestanden van Bootstrap opgenomen, in het <body>-gedeelte de eerder aangemaakte database.php, inclusief de verzoeken om een PDO-verbinding tot stand te brengen (Database::connect()) en om de corresponderende data (SELECT) te verkrijgen. Daarnaast bevat het bestand de HTML-tabel <table> met de drie kolommen Naam, E-mailadres en Mobiel nummer, die ook in de database zijn opgeslagen.

Om de basis te voltooien, moeten we nu de verschillende CRUD-operations realiseren. De create-operation implementeren we bijvoorbeeld met een extra HMTL-pagina met formuliervelden voor het invoeren van de gebruikersgegevens, die gekoppeld is aan index.php en kan worden bereikt via een knop die is toegevoegd aan de bootstrap-interface. We houden het eenvoudig en maken deze knop door index.php opnieuw te openen en de volgende code toe te voegen aan de tweede <div class="row">-element in de tabel:

<p>
  <a href="create.php" class="btn btn-success">Create</a>
</p>

Je ziet al in het codefragment dat er een link naar het bestand create.php is, die nog niet bestaat. Een test van het vorige bootstrap-grid zal daarom de knop weliswaar weergeven, maar als je er dan op klikt, zie je alleen een foutpagina. Om de create-functie te programmeren, maak je het genoemde create.php-bestand aan en voeg je het volgende eerste deel van de code in:

<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8">
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
<div class="container">

<div class="span10 offset1">
<div class="row">
<h3>Create a Customer</h3>
</div>

<form class="form-horizontal" action="create.php" method="post">
<div class="form-group <?php echo !empty($nameError)?'has-error':'';?>">
<label class="control-label">Naam</label>
<div class="controls">
<input name="name" type="text" placeholder="Naam" value="<?php echo !empty($name)?$name:'';?>">
<?php if (!empty($nameError)): ?>
<span class="help-inline"><?php echo   $nameError;?></span>
<?php endif; ?>
</div>
</div>
<div class="form-group <?php echo !empty($emailError)?'has-error':'';?>">
<label class="control-label">E-mailadres</label>
<div class="controls">
<input name="email" type="text" placeholder="E-mailadres" value="<?php echo !empty($email)?$email:'';?>">
<?php if (!empty($emailError)): ?>
<span class="help-inline"><?php echo   $emailError;?></span>
<?php endif;?>
</div>
</div>
<div class="form-group <?php echo !empty($mobileError)?'has-error':'';?>">
<label class="control-label">Mobiel nummer</label>
<div class="controls">
<input name="mobile" type="text" placeholder="Mobiel nummer" value="<?php echo !empty($mobile)?$mobile:'';?>">
<?php if (!empty($mobileError)): ?>
<span class="help-inline"><?php echo $mobileError;?></span>
<?php endif;?>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-success">Create</button>
<a class="btn" href="index.php">Back</a>
</div>
</form>
</div>

</div> <!-- /container -->
</body>
</html>

De code genereert het HTML-formulier waarin de individuele gegevens van naam, mobiel nummer en e-mailadres kunnen worden ingevoerd. Voor elk invoerveld bouwen we bovendien een PHP-variabele in, die in combinatie met de volgende uitbreiding van de code (die je in create.php voor de HTML-code plaatst) foutmeldingen genereert, voor zover het veld vrij blijft tijdens de invoer:

<?php 

require 'database.php';

if ( !empty($_POST)) {
// Validatiefout verzamelen
$nameError = null;
$emailError = null;
$mobileError = null;

// Invoer verzamelen
$name = $_POST['name'];
$email = $_POST['email'];
$mobile = $_POST['mobile'];

// Invoer controleren
$valid = true;
if (empty($name)) {
$nameError = 'Voer een naam in';
$valid = false;
}

if (empty($email)) {
$emailError = 'Voer een e-mailadres in';
$valid = false;
} else if ( !filter_var($email,FILTER_VALIDATE_EMAIL) ) {
$emailError = 'Voer een geldig e-mailadres in';
$valid = false;
}

if (empty($mobile)) {
$mobileError = 'Voer een mobiel nummer in';
$valid = false;
}

// Daten eingeben
if ($valid) {
     $pdo = Database::connect();
     $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
     $sql = "INSERT INTO customers (name,email,mobile) values(?, ?, ?)";
     $q = $pdo->prepare($sql);
     $q->execute(array($name,$email,$mobile));
     Database::disconnect();
     header("Location: index.php");
}
      }
?>

Nu heb je een create.php-pagina aangemaakt die wordt geopend als je op de create-knop klikt en waarmee je de gebruikersinformatie kunt invoeren. Het script zorgt ervoor dat alle ingevoerde gegevens en validatiefouten worden geregistreerd, dat foutmeldingen worden weergegeven als deze onjuist zijn ingevoerd en dat de gegevens bij de opgegeven database terechtkomen.