# CRUD: die Basis der Datenverwaltung

Der Begriff CRUD ist eng mit dem Management digitaler Daten verknüpft. Genauer gesagt handelt es sich bei CRUD um ein **Akronym**, das sich aus den Bezeichnungen für die vier fundamentalen Operationen persistenter Datenbank-Anwendungen ableiten lässt:

- **C**reate (Datensatz anlegen)

- **R**ead bzw. **R**etrieve (Datensatz lesen)

- **U**pdate (Datensatz aktualisieren)

- **D**elete bzw. **D**estroy (Datensatz löschen)

Vereinfacht gesagt fasst der Begriff CRUD die Funktionen zusammen, die ein Nutzer benötigt, um Daten anzulegen und zu verwalten. Diverse Datenverwaltungsprozesse basieren auf CRUD, wobei die **Operationen spezifisch an die Anforderungen von System und User angepasst** sind – egal, ob bei der Verwaltung von Datenbanken oder bei der Nutzung von Anwendungen. So sind Operationen die typischen und unverzichtbaren Zugriffswerkzeuge mit denen Experten beispielsweise Datenbankprobleme überprüfen können, während CRUD für einen User bedeutet, einen Account anlegen (create) und jederzeit nutzen (read), anpassen (update) oder löschen (delete) zu können. Abhängig von der Sprachumgebung werden die CRUD-Operationen außerdem ganz unterschiedlich ausgeführt, wie die folgende Tabelle zeigt:

<table>
  <tbody>
    <tr>
      <td><strong>CRUD-Operation</strong></td>
      <td><strong>SQL</strong></td>
      <td><strong>RESTful HTTP</strong></td>
      <td><strong>XQuery</strong></td>
    </tr>
    <tr>
      <td><strong>Create</strong></td>
      <td>INSERT</td>
      <td>POST, PUT</td>
      <td>insert</td>
    </tr>
    <tr>
      <td><strong>Read</strong></td>
      <td>SELECT</td>
      <td>GET, HEAD</td>
      <td>copy/modify/return</td>
    </tr>
    <tr>
      <td><strong>Update</strong></td>
      <td>UPDATE</td>
      <td>PUT, PATCH</td>
      <td>replace, rename</td>
    </tr>
    <tr>
      <td><strong>Delete</strong></td>
      <td>DELETE</td>
      <td>DELETE</td>
      <td>delete</td>
    </tr>
  </tbody>
</table>

## CRUD-Frameworks: Zugriffsschicht für Datenbanken

Sind einzelne Datenobjekte **mithilfe einer grafischen Oberfläche visualisiert** und durch die genannten CRUD-Operationen veränderbar, spricht man von einem CRUD-Framework oder auch einem CRUD-Grid. Für gewöhnlich handelt es sich bei den Oberflächen um **HTML-Interfaces**. Ein CRUD-Framework setzt **mehrere Transaktionsschritte** voraus, sodass Daten beispielsweise nicht durch die einfache Eingabe, sondern erst nach Drücken eines „Speichern“- oder „Weiter“-Buttons übernommen werden. Die Operationen eines CRUD-Frameworks lassen sich zeitlich stark versetzt ausführen, ohne dass der Datensatz für diese Zeitspanne für andere Nutzer gesperrt wird. Insbesondere für **Mehrbenutzersysteme** ist diese Tatsache von großer Bedeutung, da somit mehrere Personen gleichzeitig denselben Datenbestand auslesen können.

Zur Umsetzung der Operationen werden sogenannte **Persistenz-Schichten** verwendet, die in der Regel in Form von Erweiterungen (Modulen) im Framework enthalten sind oder implementiert werden können. Diese schlüsseln die relationale, tabellarische Repräsentation der Datenbestände auf und präsentieren selbige stattdessen **auf einer objektorientierten Ebene.** CRUD-Frameworks erleichtern durch den optimierten Zugriff auf das genutzte Datenbanksystem sowohl die Entwicklung als auch die Nutzung von Anwendungen. Es gibt zahlreiche Frameworks mit CRUD-Konzept, die auf den unterschiedlichsten Sprachen und Plattformen basieren. Einige Beispiele finden Sie in der folgenden tabellarischen Übersicht:

<table>
  <tbody>
    <tr>
      <td><strong>Sprache bzw. Plattform</strong></td>
      <td><strong>Framework</strong></td>
    </tr>
    <tr>
      <td>Java</td>
      <td>JDBC (The Java Database Connectivity), Hibernate, JBoss Seam, Isis</td>
    </tr>
    <tr>
      <td>PHP</td>
      <td>Yii, CakePHP, Zikula, Symfony, TYPO3 Flow</td>
    </tr>
    <tr>
      <td>Perl</td>
      <td>Catalyst, Gantry</td>
    </tr>
    <tr>
      <td>Python</td>
      <td>Django, SQLAlchemy, web2py</td>
    </tr>
    <tr>
      <td>Groovy</td>
      <td>Grails</td>
    </tr>
    <tr>
      <td>.NET</td>
      <td>NHibernate, ADO.NET/Entity Framework</td>
    </tr>
    <tr>
      <td>Ruby</td>
      <td>Ruby on Rails</td>
    </tr>
    <tr>
      <td>JavaScript</td>
      <td>Backbone.js, AngularJS</td>
    </tr>
  </tbody>
</table>

## So entwickeln Sie ein CRUD-PHP-Grid für Ihre Datenbank

In den folgenden Abschnitten zeigen wir Ihnen, wie Sie für das verbreitetste Datenbanksystem **MySQL** ein **Bootstrap-Interface** erstellen, das den Zugriff per CRUD-Operationen ermöglicht. Ferner soll auch bereits die *create*-Operation eingerichtet werden. Um die Datenbanktabellen entsprechend zu manipulieren, wird die serverseitige Skriptsprache **PHP** mithilfe der Erweiterung **PHP Data Objects (PDO)** verwendet.

1. Im ersten Schritt geht es darum, eine einfache Datenbanktabelle anzulegen, die im späteren Verlauf dieses Tutorials per CRUD-Zugriff manipuliert werden soll. Importieren Sie zu diesem Zweck die folgende Beispiel-Tabelle in Ihre MySQL-Datenbank:

```none
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;
```

Die Tabelle dient der Sammlung von Nutzer-Informationen – Name, E-Mail-Adresse und Mobilnummer. Jeder Eintrag erhält automatisch einen **Primary Key** (*AUTO\_INCREMENT PRIMARY KEY*) – also eine eigene individuelle ID.

2\. Anschließend gilt es, den Verbindungsaufbau und -abbau zur Datenbank zu regeln. Erstellen Sie eine PHP-Datei mit dem Namen *database.php* und fügen das folgende Skript mit der Klasse „Database“ zur Verwaltung der Datenbank-Verbindungen ein:

```none
<?php
class Database 
{
private static $dbName = 'name_der_datenbank'; 
private static $dbHost = 'localhost';
private static $dbUsername = 'nutzername';
private static $dbUserPassword = 'passwort';
private static $cont = null;
public function __construct() {
die('Init-Funktion nicht erlaubt');
}
public static function connect() {
// Nur eine Verbindung während der gesamten Zugriffsdauer zulassen
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;
}
}
```

Damit auch Sie die hier definierte Klasse für den Datenbankzugriff mit PDO nutzen können, müssen Sie **die exakten Werte für die vier Einträge** ***$dbName*** (Name der verwendeten Datenbank), ***$dbHost*** (Name des Hosts, auf dem die Datenbank ausgeführt wird – für gewöhnlich wie im Beispiel [localhost](https://www.ionos.at/digitalguide/server/knowhow/localhost/ "Localhost")), ***$dbUsername*** (Name des zugreifenden Nutzers) und ***$dbUserPassword*** (Passwort des zugreifenden Nutzers) angeben.

Der „Database“-Klasse wurden in diesem Skript drei Funktionen zugewiesen: *\_\_construct()*, der **Konstruktor der Klasse**, erinnert Nutzer daran, dass die Initialisierung (also die Zuweisung eines Initial- oder Anfangswertes) nicht erlaubt ist. Bei *connect()* handelt es sich um die Hauptfunktion der Klasse, die den Verbindungsaufbau reguliert, das Gegenstück *disconnect()* dient dem Beenden der Verbindung.

3\. Da man CRUD-Operationen nur mithilfe der passenden Oberfläche ausführen kann, soll an dieser Stelle nun das Basis-Grid mit Twitter Bootstrap erstellt werden. Die aktuelle Version des Frameworks finden Sie auf der [offiziellen Homepage](http://getbootstrap.com/ "Hier geht’s zum Download des HTML-, CSS- und JavaScript-Frameworks Bootstrap"). Entpacken Sie Bootstrap im gleichen Verzeichnis, in dem sich auch die *database.php* befindet, und legen Sie zusätzlich eine weitere Datei mit dem Namen *index.php* an. In dieser erstellen Sie nun das Interface:

```none

<html lang="de">
<head>
<meta charset="utf-8">
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<h3>Mein CRUD-PHP-Grid</h3>
</div>
<div class="row">
<table class="table table-striped table-bordered">
<thead>
    <tr>
        <th>Name</th>
        <th>E-Mail-Adresse</th>
        <th>Mobilnummer</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 -->
<div class="hash d-none" hidden>hash_acef9949dff719a52a74ae61110f0391590c9b2a</div><script data-shy-copy-guard>(function(){var C=[0x00AD,0x200B,0x200C,0x200D,0x2060,0xFEFF];var s=function(t){for(var i=0;i<C.length;i++){t=t.split(String.fromCharCode(C[i])).join("");}return t;};document.addEventListener("copy",function(e){var sel=document.getSelection();if(!sel||sel.isCollapsed||!e.clipboardData){return;}e.clipboardData.setData("text/plain",s(sel.toString()));try{var d=document.createElement("div");d.appendChild(sel.getRangeAt(0).cloneContents());e.clipboardData.setData("text/html",s(d.innerHTML));}catch(x){}e.preventDefault();});})();</script></body>
</html>
```

Im *&lt;head&gt;*-Bereich wurden die CSS- und JavaScript-Dateien von Bootstrap, im *&lt;body&gt;*-Bereich die zuvor erstellte *database.php* inklusive der Aufforderungen, eine PDO-Verbindung zu errichten (*Database::connect()*) und die entsprechenden Daten zu beziehen (*SELECT*), eingebunden. Zusätzlich enthält die Datei die **HTML-Tabelle** *&lt;table&gt;* mit den drei Spalten Name, E-Mail-Adresse und Mobilnummer, die auch in der Datenbank gespeichert werden.

4\. Da damit das **Grundgerüst** steht, geht es nun darum, die verschiedenen CRUD-Operationen zu realisieren. Um beispielsweise die *create*-Operation zu implementieren, benötigen Sie eine weitere HMTL-Seite mit Formularfeldern zur Eingabe der Nutzerdaten, die in der *index.php* verlinkt wird und sich über einen **Button erreichen lässt, der dem Bootstrap-Interface hinzugefügt wird.** Der Einfachheit halber können Sie mit der Erstellung dieses Buttons beginnen, indem Sie erneut die *index.php* öffnen und das zweite *&lt;div class="row"&gt;*-Element, das die Tabelle enthält, um den folgenden Code ergänzen:

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

Sie können an dem Code-Schnippsel bereits erkennen, dass auf die Datei *create.php* verlinkt wird, die bisher noch gar nicht existiert. Ein Test des bisherigen Bootstrap-Grids zeigt daher zwar den Button an; ein Klick auf selbigen führt allerdings nur auf eine Fehlerseite. Um die *create*-Operation endgültig verfügbar zu machen, **erstellen Sie besagte *create.php*-Datei** und fügen zunächst einmal den folgenden ersten Teil des Codes ein:

```none

<html lang="de">
<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">Name</label>
<div class="controls">
<input name="name" type="text" placeholder="Name" 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-Mail-Adresse</label>
<div class="controls">
<input name="email" type="text" placeholder="E-Mail-Adresse" 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">Mobilnummer</label>
<div class="controls">
<input name="mobile" type="text" placeholder="Mobilnummer" 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 -->
<div class="hash d-none" hidden>hash_acef9949dff719a52a74ae61110f0391590c9b2a</div><script data-shy-copy-guard>(function(){var C=[0x00AD,0x200B,0x200C,0x200D,0x2060,0xFEFF];var s=function(t){for(var i=0;i<C.length;i++){t=t.split(String.fromCharCode(C[i])).join("");}return t;};document.addEventListener("copy",function(e){var sel=document.getSelection();if(!sel||sel.isCollapsed||!e.clipboardData){return;}e.clipboardData.setData("text/plain",s(sel.toString()));try{var d=document.createElement("div");d.appendChild(sel.getRangeAt(0).cloneContents());e.clipboardData.setData("text/html",s(d.innerHTML));}catch(x){}e.preventDefault();});})();</script></body>
</html>
```

Der Code erzeugt das **HTML-Formular**, in das die einzelnen Angaben zu Name, Mobilnummer und E-Mail-Adresse gemacht werden können. Für jedes Eingabe-Feld ist zusätzlich eine PHP-Variable eingebaut, die in Kombination mit der nun folgenden Erweiterung des Codes (dieser ist noch vor dem HTML-Code in die *create.php* einzufügen) Fehlermeldungen erzeugt, insofern das betreffende Feld bei der Eingabe frei bleibt:

```none
<?php 
require 'database.php';
if ( !empty($_POST)) {
// Validierungsfehler erfassen
$nameError = null;
$emailError = null;
$mobileError = null;
// Eingabewerte erfassen
$name = $_POST['name'];
$email = $_POST['email'];
$mobile = $_POST['mobile'];
// Eingabe validieren
$valid = true;
if (empty($name)) {
$nameError = 'Bitte geben Sie einen Namen an';
$valid = false;
}
if (empty($email)) {
$emailError = 'Bitte geben Sie eine E-Mail-Adresse an';
$valid = false;
} else if ( !filter_var($email,FILTER_VALIDATE_EMAIL) ) {
$emailError = 'Bitte geben Sie eine gültige E-Mail-Adresse an';
$valid = false;
}
if (empty($mobile)) {
$mobileError = 'Bitte geben Sie eine Mobilnummer an';
$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");
}
     }
?>
```

Damit haben Sie nun eine *create.php*-Seite erstellt, die bei einem Klick auf den *create*-Button aufgerufen wird und die Eingabe der Nutzerinformationen ermöglicht. Das Skript stellt sicher, dass **alle eingegebenen Daten** sowie **Validierungsfehler erfasst** werden, bei falscher Eingabe entsprechende **Fehlermeldungen** erscheinen und dass die **Daten** **an die deklarierte Datenbank weitergeleitet** werden. Wie Sie auch die anderen CRUD-Operationen *read*, *update* und *delete* erstellen bzw. nutzen können, erfahren Sie in diesem [Tutorial](http://www.startutorial.com/articles/view/php-crud-tutorial-part-1 "CRUD-PHP-Tutorial auf startutorial.com"), das auch noch einmal die Erstellung des Bootstrap-Grids sowie der *create*-Operation erklärt.


This is a markdown version of: [https://www.ionos.at/digitalguide/websites/web-entwicklung/crud-die-wichtigsten-datenbankoperationen/](https://www.ionos.at/digitalguide/websites/web-entwicklung/crud-die-wichtigsten-datenbankoperationen/) for AI/LLM consumption.