Quakenet/#php Tutorial

Hinweis: Wenn sie diese Seite von einer externen URL aufgerufen haben achten sie darauf das alle Kapitel aufeinander aufbauen. Stellen sie daher sicher dass sie alle vorherigen Kapitel gelesen haben, da sie sonst relevante Informationen übersehen.

Erweitertes Newsskript

  1. Funktionalität des neuen Newsskripts
  2. Aufbaue der MySQL-Tabellen
  3. Kategorie hinzufügen
  4. Kategorie bearbeiten
  5. Kategorie löschen
  6. News hinzufügen
  7. News bearbeiten
  8. News löschen
  9. News anzeigen
  10. SELECT-Anfragen gruppieren und Spezialfunktionen verwenden
  11. Entwickeln der SELECT-Anfrage für die News
  12. News laden und anzeigen
  13. Anzeigen und schreiben von Newskommentaren
  14. Newskommentar bearbeiten
  15. Kommentare löschen

1. Funktionalität des neuen Newsskripts

Da wir nun ein Loginsystem haben können wir ein neues Newsskript mit mehr Funktionalität schreiben. Neben der eigentlichen News wird es im Newssystem auch Links für Quellen, Kommentare für Newsbeiträge und Newskategorien geben.

2. Aufbaue der MySQL-Tabellen

Wir werden user Newssystem so schreiben das eine News zu einer Kategorie gehört. Wenn man möchte das eine News zu mehreren Kategorien gehört muss man ähnliche Tabellen wie für unser Adminbereich anlegen. In unserem Fall erstellen wir zuerst die Tabelle News_Kategorie für die Kategorien.

Dann gibt es natürlich die Tabelle News mit den Newseinträgen.

Für die Kommentare der News legen wir die Tabelle News_Kommentar an.

Falls es zu einer News Quellenangaben oder anderseitig Links gibt werden diese in der Tabelle News_Link gespeichert.

Diese Tabellen fügen wir nun mit phpMyAdmin in die Datenbank ein. Die alte News-Tabelle muss man ggf. vorher löschen.

3. Kategorie hinzufügen

Zuerst schreiben wir den Adminteil in der wir die Kategorien bearbeiten können da es ohne Kategorien auch keine News geben kann. In der Rechteliste-Tabelle fügen wir dafür das neue Recht NewsKat ein. Aufgrund des neuen Recht werden wir die Dateien admin_NewsKat_add.php, admin_NewsKat_edit.php und admin_NewsKat_del.php hinzufügen müssen. Aber zuerst der Teil zum hinzufügen neuer Kategorien.

Zuerst schreiben wir die Template-Datei admin_NewsKat_add.tpl.

<form action="index.php?section=admin&amp;cat=NewsKat&amp;action=add" method="post">
    <fieldset>
        <legend>Newskategorie hinzufügen</legend>
        <label>Name: <input type="text" name="Name" /></label>
        <input type="submit" name="formaction" value="Kategorie hinzufügen" />
    </fieldset>
</form>

Die Include-Datei admin_NewsKat_add.php sieht wie folgt aus.

<?php
$ret 
= array();
$ret['filename'] = 'admin_NewsKat_add.tpl';
$ret['data'] = array();
if (
'POST' != $_SERVER['REQUEST_METHOD']) {
    return 
$ret;
}
if (!isset(
$_POST['formaction'], $_POST['Name'])) {
    return 
INVALID_FORM;
}
if (
'' == $Name trim($_POST['Name'])) {
    return 
EMPTY_FORM;
}
$sql 'SELECT
            ID
        FROM
            News_Kategorie
        WHERE
            Name = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('s'$Name);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
if (
$stmt->fetch()) {
    return 
'Es ist bereits eine Kategorie mit diesen Namen vorhanden.';
}
$stmt->close();
$sql 'INSERT INTO
            News_Kategorie(Name)
        VALUES
            (?)'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('s'$Name);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->close();
return 
showInfo('Die Kategorie wurde hinzugefügt.');
?>

4. Kategorie bearbeiten

Wir beginnen wieder zuerst mit den Template-Dateien. Zuerst schreiben wir die Datei admin_NewsKat_edit_select.tpl um eine Kategorie auszuwählen.

<?php
/* Daten:
 *   Kategorien - Ein Array mit allen bereits vorhandenen Kategorien. Bei einem Arrayelement
 *                ist der Schlüssel die ID und der Wert der Name der Kategorie.
 */
?><form action="index.php?section=admin&amp;cat=NewsKat&amp;action=edit" method="post">
    <fieldset>
        <legend>Kategorie wählen</legend>
        <label>Kategorie <select name="KatID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['Kategorien'] as $key => $value) { ?>
            <option value="<?php echo $key; ?>"><?php echo htmlspecialchars($value); ?></option>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="Kategorie wählen">
    </fieldset>
</form>

In der Include-Datei zeigen wir dieses Template an wenn die Datei nicht mit der POST-Methode aufgerufen wurde.

<?php
$ret 
= array();
$ret['filename'] = 'admin_NewsKat_edit_select.tpl';
$ret['data'] = array();
if (
'POST' != $_SERVER['REQUEST_METHOD']) {
    
$sql 'SELECT
                ID,
                Name
            FROM
                News_Kategorie
            ORDER BY
                Name ASC'
;
    if (!
$result $db->query($sql)) {
        return 
$db->error;
    }
    
$Kategorien = array();
    while (
$row $result->fetch_assoc()) {
        
$Kategorien[$row['ID']] = $row['Name'];
    }
    
$ret['data']['Kategorien'] = $Kategorien;
    
$result->close();
    return 
$ret;
}
?>

Wenn wir nun eine Kategorie auswählen zeigen wir die Daten in einem weiteren Template admin_NewsKat_edit_show.tpl an.

<?php
/* Daten:
 *    KatID - Die ID von der Kategorie
 *    Name - Der Name der Kategorie
 */
?><form action="index.php?section=admin&amp;cat=NewsKat&amp;action=edit" method="post">
    <fieldset>
        <legend>Kategorie bearbeiten</legend>
        <label>Name: <input type="text" name="Name" value="<?php echo htmlspecialchars($data['Name']); ?>" /></label>
        <input type="submit" name="formaction" value="Kategorie speichern" />
        <input type="hidden" name="KatID" value="<?php echo $data['KatID']; ?>" />
    </fieldset>
</form>

Anhand der benötigten Variablen wissen wir wie unserer Include-Datei aussehen muss.

<?php
    
// [...]
    
$ret['data']['Kategorien'] = $Kategorien;
    
$result->close();
    return 
$ret;
}
if (!isset(
$_POST['formaction'], $_POST['KatID'])) {
    return 
INVALID_FORM;
}
if (
'' == $KatID trim($_POST['KatID'])) {
    return 
EMPTY_FORM;
}
$sql 'SELECT
            ID,
            Name
        FROM
            News_Kategorie
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$KatID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->bind_result($KatID$Name);
if (!
$stmt->fetch()) {
    return 
'Es wurde keine News mit der angegebenen ID gefunden.';
}
$stmt->close();
if (
$_POST['formaction'] == 'Kategorie speichern') {
    
// todo
} else {
    
$ret['data']['KatID'] = $KatID;
    
$ret['data']['Name'] = $Name;
    
$ret['filename'] = 'admin_NewsKat_edit_show.tpl';
    return 
$ret;
}
?>

Wenn der Admin auf Kategorie speichern klickt speichern wie den neuen Namen ab, solange er nicht doppel oder leer ist.

<?php
// [...]
if ($_POST['formaction'] == 'Kategorie speichern') {
    if (!isset(
$_POST['Name'])) {
        return 
INVALID_FORM;
    }
    if (
'' == $Name trim($_POST['Name'])) {
        return 
EMPTY_FORM;
    }
    
$sql 'SELECT
                ID
            FROM
                News_Kategorie
            WHERE
                Name = ? AND
                ID != ?'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('si'$Name$KatID);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    if (
$stmt->fetch()) {
        return 
'Es ist bereits eine Kategorie mit den Namen vorhanden.';
    }
    
$stmt->close();
    
$sql 'UPDATE
                News_Kategorie
            SET
                Name = ?
            WHERE
                ID = ?'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('si'$Name$KatID);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$stmt->close();
    return 
showInfo('Die Kategorie wurde bearbeitet.');
} else {
// [...]
?>

5. Kategorie löschen

Wie beim Bearbeiten schreiben wir ein Template welches eine Auswahlliste aller Kategorien bereitstellt. Das Template ist fast identisch wie beim Bearbeiten.

<?php
/* Daten:
 *   Kategorien - Ein Array mit allen bereits vorhandenen Kategorien. Bei einem Arrayelement
 *                ist der Schlüssel die ID und der Wert der Name der Kategorie.
 */
?><form action="index.php?section=admin&amp;cat=NewsKat&amp;action=del" method="post">
    <fieldset>
        <legend>Kategorie wählen</legend>
        <label>Kategorie <select name="KatID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['Kategorien'] as $key => $value) { ?>
            <option value="<?php echo $key; ?>"><?php echo htmlspecialchars($value); ?></option>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="Kategorie löschen">
    </fieldset>
</form>

In der Include-Datei laden wir erstmal alle Kategorien in ein Array und zeigen das Template an.

<?php
$ret 
= array();
$ret['filename'] = 'admin_NewsKat_del.tpl';
$ret['data'] = array();
$sql 'SELECT
            ID,
            Name
        FROM
            News_Kategorie
        ORDER BY
            Name ASC'
;
if (!
$result $db->query($sql)) {
    return 
$db->error;
}
$Kategorien = array();
while (
$row $result->fetch_assoc()) {
    
$Kategorien[$row['ID']] = $row['Name'];
}
$ret['data']['Kategorien'] = $Kategorien;
if (
'POST' != $_SERVER['REQUEST_METHOD']) {
    return 
$ret;
}
?>

Beim Löschen müssen wir aufpassen das wir keine Kategorie löschen zu denen noch Newsbeiträge gehören. Daher schreiben wir einige Abfragen ob wir die News auch wirklich löschen können.

<?php
// [...]
if ('POST' != $_SERVER['REQUEST_METHOD']) {
    return 
$ret;
}
if (!isset(
$_POST['formaction'], $_POST['KatID'])) {
    return 
INVALID_FORM;
}
if (
'' == $KatID trim($_POST['KatID'])) {
    return 
EMPTY_FORM;
}
$sql 'SELECT
            ID
        FROM
            News_Kategorie
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$KatID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->bind_result($KatID);
if (!
$stmt->fetch()) {
    return 
'Es wurde keine Kategorie mit der angegebenen ID gefunden.';
}
$stmt->close();

$sql 'SELECT
            ID
        FROM
            News
        WHERE
            KatID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$KatID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
if (
$stmt->fetch()) {
    return 
'Es gibt noch Newsbeiträge die diese Kategorie verwenden.';
}
$stmt->close();

$sql 'DELETE FROM
            News_Kategorie
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$KatID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->close();
return 
showInfo('Die Kategorie wurde gelöscht.');
?>

6. News hinzufügen

Beim hinzufügen (und bearbeiten) einer News müssen wir uns überlegen wie wir die Formulare aufbauen. Neben der eigentlichen News müssen z.B. auch die Newslinks angegeben werden. Es gibt verschiedene Möglichkeiten wie man das machen kann.

So hoffnungslos es auch scheinen mag, es gibt ne Lösung genannt Session. Wir bereiten die Newserstellung vor indem wir erst alle Daten in einer Session speichern und dann erst in die Datenbank einfügen wenn wir fertig sind. So wird die Datenbank nicht vorher mit ungenutzten Müll gefüttert sondern alle Daten liegen erstmal in der Session. Wenn der Vorgang abgebrochen wird verfällt die Session eh nach einiger Zeit.

Zur Vorbereitung der Session setzen wir die session.use_only_cookies-Einstellung auf 1, damit die Session-ID nur per Cookie übermittelt wird. Dies machen wir in der index.php-Datei nach dem einstellen des Error-Reportings.

<?php
error_reporting
(E_ALL);
ini_set('display_errors'1);
ini_set('session.use_only_cookies'1);

// [...]
?>

Die Template-Datei sieht nun sehr überladen aus.

<?php
/* Daten:
 *    Titel - Der Titel der News
 *    Inhalt - Der Text der News
 *    KatID - Die ID der aktuell gewählten Kategorie
 *    Kategorien - Ein Array mit allen Kategorien. Bei einem Arrayelement ist der Schlüssel
 *                 die ID und der Wert der Name der Kategorie.
 *    Links - Ein Array mit den Links die zu der News gehört. Bei einem Arrayelement ist der
 *            Schlüssel eine fortlaufende Nummer, der Wert entspricht einem assoziativen
 *            Array mit den Schlüssel 'URL' und 'Beschreibung' mit den entsprechenden Werten.
 */
?><form action="index.php?section=admin&amp;cat=News&amp;action=add" method="post">
    <fieldset>
        <legend>News hinzufügen</legend>
        <label>Titel <input type="text" name="Titel" value="<?php echo htmlspecialchars($data['Titel']); ?>" /></label>
        <label>Inhalt <textarea name="Inhalt" cols="40" rows="10"><?php echo htmlspecialchars($data['Inhalt']); ?></textarea></label>
        <label>Kategorie <select name="KatID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['Kategorien'] as $key => $value) {
                      if ($data['KatID'] == $key) { ?>
            <option value="<?php echo $key; ?>" selected="selected"><?php echo htmlspecialchars($value); ?></option>
            <?php     } else { ?>
            <option value="<?php echo $key; ?>"><?php echo htmlspecialchars($value); ?></option>
            <?php     }
                  } ?>
                </select>
            </label>
        <fieldset>
            <legend>Newslinks</legend>
            <?php if (count($data['Links'])) { ?>
            <ul>
                <?php foreach ($data['Links'] as $key => $value) { ?>
                <li><label>
                    <input type="checkbox" name="LinkID[]" value="<?php echo $key; ?>"/>
                        <?php echo htmlspecialchars($value['Beschreibung']); ?></label> - 
                        <a href="<?php echo htmlspecialchars($value['URL']); ?>"><?php echo htmlspecialchars($value['URL']); ?></a>
                </li>
                <?php } ?>
            </ul>
            <input type="submit" name="formaction" value="Markierte Links löschen" />
            <?php } else { ?>
            <p class="info">
                Es sind momentan keine Links hinzugefügt.
            </p>
            <?php } ?>
            <fieldset>
                <legend>Neuen Link hinzufügen</legend>
                <label>URL: <input type="text" name="URL" /></label>
                <label>Beschreibung: <input type="text" name="Beschreibung" /></label>
                <input type="submit" name="formaction" value="Link hinzufügen" />
            </fieldset>
        </fieldset>
        <input type="submit" name="formaction" value="News hinzufügen" />
    </fieldset>
</form>

Wie man sieht wird das Template mit diversen Werten gefüllt und das Template selbst enthält mehrere Submit-Buttons mit unterschiedlichen Beschriftungen für entsprechend unterschiedliche Aktionen. All diese Aktionen müssen wir in unserem PHP-Skript abfragen. Außerdem müssen wir eine Session starten und alle Felder vorinitialisieren.

<?php
$ret 
= array();
$ret['filename'] = 'admin_News_add.tpl';
$ret['data'] = array();

$sql 'SELECT
            ID,
            Name
        FROM
            News_Kategorie
        ORDER BY
            Name ASC'
;
if (!
$result $db->query($sql)) {
    return 
$db->error;
}
$Kategorien = array();
while (
$row $result->fetch_assoc()) {
    
$Kategorien[$row['ID']] = $row['Name'];
}
$ret['data']['Kategorien'] = $Kategorien;

session_start();
if (!isset(
$_SESSION['News']) OR 'POST' != $_SERVER['REQUEST_METHOD']) {
    
$_SESSION['News'] = array();
    
$_SESSION['News']['Titel'] = '';
    
$_SESSION['News']['Inhalt'] = '';
    
$_SESSION['News']['KatID'] = 0;
    
$_SESSION['News']['Links'] = array();
} else {
    
// [...]
}
$ret['data']['Titel'] = $_SESSION['News']['Titel'];
$ret['data']['Inhalt'] = $_SESSION['News']['Inhalt'];
$ret['data']['KatID'] = $_SESSION['News']['KatID'];
$ret['data']['Links'] = $_SESSION['News']['Links'];
return 
$ret;
?>

Falls ein Formularknopf verwendet wird prüfen wir zuerst ob alle Formularfelder vorhanden ist, egal ob wir sie in diesem Aufruf verwenden oder nicht. Danach speichern wir stehts die Felder Titel, Inhalt und KatID in der Session.

<?php
// [...]
} else {
    
// Aufruf der POST und Session vorinitialisiert
    
if (!isset($_POST['formaction'], $_POST['Titel'], $_POST['Inhalt'],
            
$_POST['KatID'], $_POST['URL'], $_POST['Beschreibung'])) {
        return 
INVALID_FORM;
    }

    
// speichern der allgemeinen newsdaten
    
$_SESSION['News']['Titel'] = $_POST['Titel'];
    
$_SESSION['News']['Inhalt'] = $_POST['Inhalt'];
    
$_SESSION['News']['KatID'] = $_POST['KatID'];
}
// [...]
?>

Wenn wir einen Link hinzufügen wollen prüfen wir die beiden Felder URL und Beschreibung und erweitern das Array.

<?php
    
// [...]
    // speichern der allgemeinen newsdaten
    
$_SESSION['News']['Titel'] = $_POST['Titel'];
    
$_SESSION['News']['Inhalt'] = $_POST['Inhalt'];
    
$_SESSION['News']['KatID'] = $_POST['KatID'];

    if (
'Link hinzufügen' == $_POST['formaction']) {
        if (
'' == $URL trim($_POST['URL']) OR
                
'' == $Beschreibung trim($_POST['Beschreibung'])) {
            return 
EMPTY_FORM;
        }
        
$_SESSION['News']['Links'][] = array('URL' => $URL'Beschreibung' => $Beschreibung);
    }
}
// [...]
?>

Wenn wir Links löschen wollen durchlaufen wir das Array und löschen die entsprechenden Arrayelemente aus der Liste.

<?php
        
// [...]
        
$_SESSION['News']['Links'][] = array('URL' => $URL'Beschreibung' => $Beschreibung);
    }
    if (
'Markierte Links löschen' == $_POST['formaction']) {
        if (!isset(
$_POST['LinkID'])) {
            return 
EMPTY_FORM;
        }
        if (!
is_array($_POST['LinkID'])) {
            return 
INVALID_FORM;
        }
        foreach (
$_POST['LinkID'] as $IDs) {
            unset(
$_SESSION['News']['Links'][$IDs]);
        }
    }
}
// [...]
?>

Der spaßige Teil ist die Aktion News hinzufügen. Zuerst prüfen wir ob alle Texte eingegeben sind, dann ob die gewählte Kategorie auch existiert und fügen dann die News und die Links in die Datenbank ein.

<?php
        
// [...]
        
foreach ($_POST['LinkID'] as $IDs) {
            unset(
$_SESSION['News']['Links'][$IDs]);
        }
    }
    if (
'News hinzufügen' == $_POST['formaction']) {
        if (
'' == $Titel trim($_SESSION['News']['Titel']) OR
                
'' == $Inhalt trim($_SESSION['News']['Inhalt']) OR
                
'' == $KatID trim($_SESSION['News']['KatID'])) {
            return 
EMPTY_FORM;
        }
        
$Links $_SESSION['News']['Links'];

        
// gucken ob es die Kategorie gibt
        
$sql 'SELECT
                    ID
                FROM
                    News_Kategorie
                WHERE
                    ID = ?'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }
        
$stmt->bind_param('i'$KatID);
        if (!
$stmt->execute()) {
            return 
$stmt->error;
        }
        
$stmt->bind_result($KatID);
        if (!
$stmt->fetch()) {
            return 
'Es wurde keine Kategorie mit der angegebenen ID gefunden.';
        }
        
$stmt->close();

        
$sql 'INSERT INTO
                    News(Titel, Inhalt, Datum, KatID, AutorID)
                VALUES
                    (?, ?, NOW(), ?, ?)'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }
        
$stmt->bind_param('ssii'$Titel$Inhalt$KatID$UserID);
        if (!
$stmt->execute()) {
            return 
$stmt->error;
        }
        
$NewsID $stmt->insert_id;
        
$stmt->close();

        
$sql 'INSERT INTO
                    News_Link(NewsID, URL, Beschreibung)
                VALUES
                    (?,?,?)'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }  
        foreach (
$Links as $Link) {
            
$stmt->bind_param('iss'$NewsID$Link['URL'], $Link['Beschreibung']);
            if (!
$stmt->execute()) {
                return 
$stmt->error;
            }
        }
        
$stmt->close();
        unset(
$_SESSION['News']); // Sessiondaten löschen, brauchen wir nicht mehr.
        
return showInfo('Die News wurde hinzugefügt.');
    }
}
// [...]
?>

7. News bearbeiten

Wenn wir eine News bearbeiten benutzen wir den selben Formularaufbau wie beim Hinzufügen. Wir müssen nur die Session anders vorinitialisieren. Statt leere Strings und Arrays füllen wir die Session mit einem Datensatz aus der News-Tabelle.

Zuerst schreiben wir den einfachen Fall wo wir eine News über eine Dropdown-Liste auswählen. Die admin_News_edit_select.tpl-Datei sieht wie folgt aus.

<?php
/*
 * Daten:
 *    News - Ein Array mit allen Newsbeiträgen. Bei einem Arrayelement ist der Schlüssel
 *           Die ID der News und der Wert ist ein assoziatives Array mit den folgenden
 *           Werten:
 *               Datum - Das Datum wann die News geschrieben wurde
 *               Titel - Der Titel der News, ungekürzt.
 */
?><form action="index.php?section=admin&amp;cat=News&amp;action=edit" method="post">
    <fieldset>
        <legend>News wählen</legend>
        <label>News: <select name="NewsID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['News'] as $key => $value) { ?>
            <option value="<?php echo $key; ?>">(<?php echo htmlspecialchars($value['Datum']); ?>)
                <?php echo htmlspecialchars($value['Titel']); ?></option>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="News wählen" />
    </fieldset>
</form>

Der erste Teil des PHP-Skripts sieht wie folgt aus.

<?php
$ret 
= array();
$ret['filename'] = 'admin_News_edit_select.tpl';
$ret['data'] = array();
if (
'POST' != $_SERVER['REQUEST_METHOD']) {
    
$sql 'SELECT
                ID,
                Titel,
                Datum
            FROM
                News
            ORDER BY
                Datum DESC'
;
    if (!
$result $db->query($sql)) {
        return 
$db->error;
    }
    
$News = array();
    while (
$row $result->fetch_assoc()) {
        
$News[$row['ID']] = array('Datum' => $row['Datum'], 'Titel' => $row['Titel']);
    }
    
$ret['data']['News'] = $News;
} else {
    
// [...]
}
return 
$ret;
?>

Da wir fast die gleiche Formular fürs Bearbeiten benutzen wie fürs Hinzufügen einer News können wir die bereits vorhandene Template-Datei kopieren und in admin_News_edit_details.tpl speichern.

<?php
/* Daten:
 *    Titel - Der Titel der News
 *    Inhalt - Der Text der News
 *    KatID - Die ID der aktuell gewählten Kategorie
 *    Kategorien - Ein Array mit allen Kategorien. Bei einem Arrayelement ist der Schlüssel
 *                 die ID und der Wert der Name der Kategorie.
 *    Links - Ein Array mit den Links die zu der News gehört. Bei einem Arrayelement ist der
 *            Schlüssel eine fortlaufende Nummer, der Wert entspricht einem assoziativen
 *            Array mit den Schlüssel 'URL' und 'Beschreibung' mit den entsprechenden Werten.
 */
?><form action="index.php?section=admin&amp;cat=News&amp;action=edit" method="post">
    <fieldset>
        <legend>News bearbeiten</legend>
        <label>Titel <input type="text" name="Titel" value="<?php echo htmlspecialchars($data['Titel']); ?>" /></label>
        <label>Inhalt <textarea name="Inhalt" cols="40" rows="10"><?php echo htmlspecialchars($data['Inhalt']); ?></textarea></label>
        <label>Kategorie <select name="KatID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['Kategorien'] as $key => $value) {
                      if ($data['KatID'] == $key) { ?>
            <option value="<?php echo $key; ?>" selected="selected"><?php echo htmlspecialchars($value); ?></option>
            <?php     } else { ?>
            <option value="<?php echo $key; ?>"><?php echo htmlspecialchars($value); ?></option>
            <?php     }
                  } ?>
                </select>
            </label>
        <fieldset>
            <legend>Newslinks</legend>
            <?php if (count($data['Links'])) { ?>
            <ul>
                <?php foreach ($data['Links'] as $key => $value) { ?>
                <li><label>
                    <input type="checkbox" name="LinkID[]" value="<?php echo $key; ?>"/>
                        <?php echo htmlspecialchars($value['Beschreibung']); ?></label> - 
                        <a href="<?php echo htmlspecialchars($value['URL']); ?>"><?php echo htmlspecialchars($value['URL']); ?></a>
                </li>
                <?php } ?>
            </ul>
            <input type="submit" name="formaction" value="Markierte Links löschen" />
            <?php } else { ?>
            <p class="info">
                Es sind momentan keine Links hinzugefügt.
            </p>
            <?php } ?>
            <fieldset>
                <legend>Neuen Link hinzufügen</legend>
                <label>URL: <input type="text" name="URL" /></label>
                <label>Beschreibung: <input type="text" name="Beschreibung" /></label>
                <input type="submit" name="formaction" value="Link hinzufügen" />
            </fieldset>
        </fieldset>
        <input type="submit" name="formaction" value="News bearbeiten" />
    </fieldset>
</form>

In der Include-Datei müssen wir nun entsprechend auf die Submit-Buttons reagieren. Zuerst müssen wir jedoch die Session füllen.

<?php
    
// [...]
} else {
    if (!isset(
$_POST['formaction'])) {
        return 
INVALID_FORM;
    }
    
$ret['filename'] = 'admin_News_edit_details.tpl';
    
session_start();
    if (!isset(
$_SESSION['News']) OR 'News wählen' == $_POST['formaction']) {
        if (!isset(
$_POST['formaction'], $_POST['NewsID'])) {
            return 
INVALID_FORM;
        }
        if (
'' == $NewsID trim($_POST['NewsID'])) {
            return 
EMPTY_FORM;
        }
        
$sql 'SELECT
                    ID,
                    Titel,
                    Inhalt,
                    KatID
                FROM
                    News
                WHERE
                    ID = ?'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }
        
$stmt->bind_param('i'$NewsID);
        if (!
$stmt->execute()) {
            return 
$stmt->error;
        }
        
$stmt->bind_result($NewsID$Titel$Inhalt$KatID);
        if (!
$stmt->fetch()) {
            return 
'Es wurde keine News mit dieser ID gefunden.';
        }
        
$stmt->close();
        
$_SESSION['News'] = array();
        
$_SESSION['News']['ID'] = $NewsID;
        
$_SESSION['News']['Titel'] = $Titel;
        
$_SESSION['News']['Inhalt'] = $Inhalt;
        
$_SESSION['News']['KatID'] = $KatID;

        
$sql 'SELECT
                    URL,
                    Beschreibung
                FROM
                    News_Link
                WHERE
                    NewsID = ?'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$stmt->error;
        }
        
$stmt->bind_param('i'$NewsID);
        if (!
$stmt->execute()) {
            return 
$stmt->error;
        }
        
$Links = array();
        
$stmt->bind_result($URL$Beschreibung);
        while (
$stmt->fetch()) {
            
$Links[] = array('URL' => $URL'Beschreibung' => $Beschreibung);
        }
        
$stmt->close();
        
$_SESSION['News']['Links'] = $Links;
    }

    
$sql 'SELECT
                ID,
                Name
            FROM
                News_Kategorie
            ORDER BY
                Name ASC'
;
    if (!
$result $db->query($sql)) {
        return 
$db->error;
    }
    
$Kategorien = array();
    while (
$row $result->fetch_assoc()) {
        
$Kategorien[$row['ID']] = $row['Name'];
    }
    
$ret['data']['Kategorien'] = $Kategorien;
    
$ret['data']['Titel'] = $_SESSION['News']['Titel'];
    
$ret['data']['Inhalt'] = $_SESSION['News']['Inhalt'];
    
$ret['data']['KatID'] = $_SESSION['News']['KatID'];
    
$ret['data']['Links'] = $_SESSION['News']['Links'];
}
return 
$ret;
?>

Dann kommt der gleiche Programmcode zum Speichern der aktuellen Inhalte und zum Verwalten der Links.

<?php
        
// [...]
        
$stmt->close();
        
$_SESSION['News']['Links'] = $Links;
    }
    if (isset(
$_POST['Titel'], $_POST['Inhalt'], $_POST['KatID'])) {
        
// speichern der allgemeinen newsdaten
        
$_SESSION['News']['Titel'] = $_POST['Titel'];
        
$_SESSION['News']['Inhalt'] = $_POST['Inhalt'];
        
$_SESSION['News']['KatID'] = $_POST['KatID'];
    }
    
    if (
'Markierte Links löschen' == $_POST['formaction']) {
        if (!isset(
$_POST['LinkID'])) {
            return 
EMPTY_FORM;
        }
        if (!
is_array($_POST['LinkID'])) {
            return 
INVALID_FORM;
        }
        foreach (
$_POST['LinkID'] as $IDs) {
            unset(
$_SESSION['News']['Links'][$IDs]);
        }
    }

    if (
'Link hinzufügen' == $_POST['formaction']) {
        if (
'' == $URL trim($_POST['URL']) OR
                
'' == $Beschreibung trim($_POST['Beschreibung'])) {
            return 
EMPTY_FORM;
        }
        
$_SESSION['News']['Links'][] = array('URL' => $URL'Beschreibung' => $Beschreibung);
    }

    
$sql 'SELECT
                ID,
                Name
            FROM
                News_Kategorie
            ORDER BY
                Name ASC'
;
    
// [...]
?>

Und zum Schluss der Programmteil zum Speichern der News.

<?php
        
// [...]
        
$_SESSION['News']['Links'][] = array('URL' => $URL'Beschreibung' => $Beschreibung);
    }

    if (
'News bearbeiten' == $_POST['formaction']) {
        if (
'' == $Titel trim($_SESSION['News']['Titel']) OR
                
'' == $Inhalt trim($_SESSION['News']['Inhalt']) OR
                
'' == $KatID trim($_SESSION['News']['KatID'])) {
            return 
EMPTY_FORM;
        }
        
$Links $_SESSION['News']['Links'];

        
// gucken ob es die Kategorie gibt
        
$sql 'SELECT
                    ID
                FROM
                    News_Kategorie
                WHERE
                    ID = ?'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }
        
$stmt->bind_param('i'$KatID);
        if (!
$stmt->execute()) {
            return 
$stmt->error;
        }
        
$stmt->bind_result($KatID);
        if (!
$stmt->fetch()) {
            
$stmt->close();
            return 
'Es wurde keine Kategorie mit der angegebenen ID gefunden.';
        }
        
$stmt->close();

        
// newsdaten speichern
        
$sql 'UPDATE
                    News
                SET
                    Titel = ?,
                    Inhalt = ?,
                    KatID = ?
                WHERE
                    ID = ?'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }
        
$stmt->bind_param('ssii'$Titel$Inhalt$KatID$_SESSION['News']['ID']);
        if (!
$stmt->execute()) {
            return 
$stmt->error;
        }
        
$stmt->close();

        
// alte links löschen
        
$sql 'DELETE FROM
                    News_Link
                WHERE
                    NewsID = ?'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }
        
$stmt->bind_param('i'$_SESSION['News']['ID']);
        if (!
$stmt->execute()) {
            return 
$stmt->error;
        }
        
$stmt->close();

        
// neue links hinzufügen
        
$sql 'INSERT INTO
                    News_Link(NewsID, URL, Beschreibung)
                VALUES
                    (?,?,?)'
;
        if (!
$stmt $db->prepare($sql)) {
            return 
$db->error;
        }  
        foreach (
$Links as $Link) {
            
$stmt->bind_param('iss'$_SESSION['News']['ID'], $Link['URL'], $Link['Beschreibung']);
            if (!
$stmt->execute()) {
                return 
$stmt->error;
            }
        }
        
$stmt->close();
        unset(
$_SESSION['News']);
        return 
showInfo('Die News wurde bearbietet.');
    }

    
$sql 'SELECT
                ID,
                Name
            FROM
                News_Kategorie
            ORDER BY
                Name ASC'
;
?>

8. News löschen

Eine News zu löschen geht bedeutend einfacher da wir nur eine News auswählen brauchen und dann die Kommentare und Links der News sowie die News selbst löschen.

<?php
/*
 * Daten:
 *    News - Ein Array mit allen Newsbeiträgen. Bei einem Arrayelement ist der Schlüssel
 *           Die ID der News und der Wert ist ein assoziatives Array mit den folgenden
 *           Werten:
 *               Datum - Das Datum wann die News geschrieben wurde
 *               Titel - Der Titel der News, ungekürzt.
 */
?><form action="index.php?section=admin&amp;cat=News&amp;action=del" method="post">
    <fieldset>
        <legend>News löschen</legend>
        <label>News: <select name="NewsID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['News'] as $key => $value) { ?>
            <option value="<?php echo $key; ?>">(<?php echo htmlspecialchars($value['Datum']); ?>)
                <?php echo htmlspecialchars($value['Titel']); ?></option>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="News löschen" />
    </fieldset>
</form>

Die Include-Datei beginnt so ähnlich wie die beim Bearbeiten.

<?php
$ret 
= array();
$ret['filename'] = 'admin_News_del.tpl';
$ret['data'] = array();
if (
'POST' != $_SERVER['REQUEST_METHOD']) {
    
$sql 'SELECT
                ID,
                Titel,
                Datum
            FROM
                News
            ORDER BY
                Datum DESC'
;
    if (!
$result $db->query($sql)) {
        return 
$db->error;
    }
    
$News = array();
    while (
$row $result->fetch_assoc()) {
        
$News[$row['ID']] = array('Datum' => $row['Datum'], 'Titel' => $row['Titel']);
    }
    
$ret['data']['News'] = $News;
    return 
$ret;
}
?>

Nachdem wir eine News ausgewählt haben löschen wir diese.

<?php
    
// [...]
    
return $ret;
}
if (!isset(
$_POST['formaction'], $_POST['NewsID'])) {
    return 
INVALID_FORM;
}
if (
'' == $NewsID trim($_POST['NewsID'])) {
    return 
EMPTY_FORM;
}
$sql 'SELECT
            ID
        FROM
            News
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$NewsID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->bind_result($NewsID);
if (!
$stmt->fetch()) {
    return 
'Es wurde keine News mit der ID gefunden.';
}
$stmt->close();

// links löschen
$sql 'DELETE FROM
            News_Link
        WHERE
            NewsID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$NewsID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->close();

// kommentarie löschen
$sql 'DELETE FROM
            News_Kommentar
        WHERE
            NewsID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$NewsID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->close();

// news löschen
$sql 'DELETE FROM
            News
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$NewsID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->close();

return 
showInfo('Die News wurde gelöscht.');
?>

9. News anzeigen

Nachdem wir unsere Newskategorien und News hinzufügen können wollen wir sie auch auf unserer Seite anzeigen lassen. Dazu schreiben wir unsere Template-Datei news.tpl.

<?php
/* Daten
 *    News - Ein Array mit Newsbeiträgen mit den folgendem Aufbau:
 *        ID - Die ID der News
 *        Autor - Der Name des Autors der die News geschrieben hat
 *        Datum - Das Datum der Veröffentlichung
 *        Titel - Der Titel der News
 *        Inhalt - Der Text der News
 *        Anzahl - Die Anzahl der Newskommentare
 *        Links - Ein Array mit Links mit den folgendem Aufbau:
 *            URL - Die URL vom Link
 *            Beschreibung - Der Bezeichner vom Link
 */
?><h1>News</h1>
<?php if (count($data['News'])) { 
    foreach ($data['News'] as $News) { ?>
    <h2><?php echo htmlspecialchars($News['Titel']); ?></h2>
    <div class="newsheader">Geschrieben von <?php echo htmlspecialchars($News['Autor']); ?> um
        <?php echo htmlspecialchars($News['Datum']); ?></div>
    <p>
        <?php echo nl2br(htmlspecialchars($News['Inhalt'])); ?>
    </p>
    <?php if (count($News['Links'])) { ?>
    <div class="links">
        Links:
        <ul>
            <?php foreach ($News['Links'] as $Link) { ?>
            <li><a href="<?php echo $Link['URL']; ?>"><?php echo htmlspecialchars($Link['Beschreibung']); ?></a></li>
            <?php } ?>
        </ul>
    </div>
    <?php } else { ?>
    <p class="info">
        Keine Links vorhanden.
    </p>
    <?php } ?>
    <div class="comments">
        <a href="index.php?section=newscomments&amp;ID=<?php echo $News['ID']; ?>">Kommentare (<?php echo $News['Anzahl']; ?>)</a>
    </div>
<?php }
} else { ?>
<p class="info">
    Es sind keine News vorhanden.
</p>
<?php } ?>

Wenn wir uns angucken wie die Template-Daten aussehen müssen stoßen wir an einige kleine und große Probleme wie wir die Daten elegenant aus der Datenbank auslesen.

Um den Benutzernamen des Autors auszulesen verwenden wir ein einfachen JOIN auf die Tabelle Users. Für die Anzahl der Kommentare zu einer News müssen wir uns was einfallen lassen. Eine einfache Möglichkeit wäre innerhalb einer while-Schleife, die die Datensätze aus der Newstabelle ausliest, eine MySQL-Anfrage abzuschicken die die Kommentare der News ausliest und davon dann die Anzahl bestimmen. Mit einem JOIN und einem GROUP BY geht dies jedoch viel eleganter.

10. SELECT-Anfragen gruppieren und Spezialfunktionen verwenden

In einer SELECT-Anfrage kann man mehrere Datensätze zu einem Datensatz zusammenfassen. Dazu wird das Schlüsselwort GROUP BY verwendet. Danach gibt man z.B. die Spalte an, nach der die Datensätze zusammengefasst werden.

Beispieltabelle
Foo Bar
3 6
3 10
5 9
5 11
5 12
2 3

Wenn wir diese Tabelle nach der Spalte Foo gruppieren enthalten wir die folgende Ergebnistabelle.

Gruppierung nach Foo
Foo
3
5
2

Jetzt stellt sich die Frage was passiert wenn wir trotzdem weiterhin den Wert Bar auslesen, also weiterhin in der Anfrage SELECT Foo, Bar FROM ... stehen haben.

Gruppierung nach Foo mit Spalte Bar
Foo Bar
3 ?
5 ?
2 ?

Die Fragezeichen deuten an dass es ggf. nicht eindeutig ist was ausgelesen wird. So könnte es z.B. der Bar-Wert aus dem letzen Datensatz genommen wird, oder der erste, oder sogar ein zufälliger Wert. In MySQL gibt es jedoch eine Menge Funktionen die man mit GROUP BY verwenden kann. Diese Funktionen beziehen sich dabei auf die Werte die dann du einer Gruppierung gehören. In unserem Beispiel sind das die Werte (6,10) für die Gruppierung von Foo=3, (9,11,12) für die Gruppierung von Foo=5 und (3) für die Gruppierung von Foo=2. Anstatt nun den Wert Bar abzufragen könnten wir das Maximum aus den Gruppierungen mit MAX(Bar) wählen oder den Durchschnitt mit AVG(Bar).

Gruppierung nach Foo mit weiteren Funktionen
Foo "Zusammengefaste Werte von Bar" MAX(Bar) AVG(Bar)
3 (6,10) 10 8
5 (9,11,12) 12 10.6667
2 (3) 3 3

Für uns ist die MySQL-Funktion COUNT() interessant die uns sagt wieviele Datensätze das GROUP BY für einen Wert zusammengefasst hat.

Gruppierung nach Foo mit weiteren Funktionen
Foo "Zusammengefaste Werte von Bar" MAX(Bar) AVG(Bar) COUNT(Bar)
3 (6,10) 10 8 2
5 (9,11,12) 12 10.6667 3
2 (3) 3 3 1

11. Entwickeln der SELECT-Anfrage für die News

In unserer SELECT-Anfrage starten wir bei der Tabelle News und lesen da erstmal die unproblematischen Daten aus.

SELECT
    News.ID,
    News.Titel,
    News.Inhalt,
    News.Datum
FROM
    News;

Nun machen wir ein JOIN auf die Users-Tabelle um den Benutzernamen vom Autor auszulesen.

SELECT
    News.ID,
    User.Username,
    News.Titel,
    News.Inhalt,
    News.Datum
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID;

Nun müssen wir irgendwie aus der News_Kommentar-Tabelle die Anzahl der Kommentare zu einer News auslesen. Daher bilden wir zuerst ein JOIN auf die News_Kommentar-Tabelle, dabei verketten wir News.ID mit News_Kommentar.NewsID.

SELECT
    News.ID,
    User.Username,
    News.Titel,
    News.Inhalt,
    News.Datum
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID
JOIN
    News_Kommentar ON
    News.ID = News_Kommentar.NewsID;

Wenn wir diesen Query zum testen in phpMyAdmin eingeben sehen wir folgendes: nichts. Obwohl wir Newsdatensätze durch die Testerei vom NewsAdd-Bereich aus dem Adminbereich haben werden nun keine Datensätze mehr angezeigt. Der Grund dafür ist dass wir keine Kommentare haben, also gibt es auch keine Verbindungsmöglichkeit. Bei den anderen Tabellen wie Users ist dies kein Problem, denn da existieren ja z.B. die Benutzerdatensätze. Aber das keine News mehr angezeigt werden ist inakzeptabel. Jedoch ist die Lösung für unser Problem extrem einfach, wir ändern das JOIN in ein LEFT JOIN um.

SELECT
    News.ID,
    User.Username,
    News.Titel,
    News.Inhalt,
    News.Datum
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID
LEFT JOIN
    News_Kommentar ON
    News.ID = News_Kommentar.NewsID;

Dieses LEFT sorgt dafür das auf jedenfall der Datensatz aus der linken Tabelle (hier der Verbund von News und Users) angezeigt wird, auch wenn es keine passende Newskommentare gibt. Wenn dies für ein Datensatz der Fall ist wird für die zweite Tabelle angenommen dass der Datensatz existiert jedoch alle Werte NULL sind. In phpMyAdmin testen wir dies einmal indem wir alle Spalten aus der News_Kommentar-Tabelle auslesen.

SELECT
    News.ID,
    User.Username,
    News.Titel,
    News.Inhalt,
    News.Datum,
    News_Kommentar.ID,
    News_Kommentar.Datum,
    News_Kommentar.Inhalt,
    News_Kommentar.NewsID,
    News_Kommentar.AutorID
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID
LEFT JOIN
    News_Kommentar ON
    News.ID = News_Kommentar.NewsID;

Wie man in der Ausgabe in phpMyAdmin sieht hat MySQL für jeden Datensatz einen Pseudo-Datensatz generiert wo alle Werte NULL sind. Diese NULL-Werte sind später von Bedeutung. Jedoch nehmen wir wieder die ganzen News_Kommentar.*-Werte aus der Anfrage raus.

SELECT
    News.ID,
    User.Username,
    News.Titel,
    News.Inhalt,
    News.Datum
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID
LEFT JOIN
    News_Kommentar ON
    News.ID = News_Kommentar.NewsID;

Wenn wir diese Anfrage ausführen kann es passieren das eine News mehrfach angezeigt wird, je nach dem wieviele Kommentare zu einer News vorhanden sind. Wenn es z.B. 5 Kommentare zu einer News gibt wird diese News entsprechend 5 mal angezeigt weil MySQL durch die Bedingung News.ID = News_Kommentar.NewsID 5 Verkettungen gefunden hat. Dies ist jedoch nicht das was wir wollen, wir haben die News nur einmal veröffentlicht, nicht 5 mal. Hier kommt unser GROUP BY ins Spiel. Wir gruppieren dabei die Spalte News.ID.

SELECT
    News.ID,
    User.Username,
    News.Titel,
    News.Inhalt,
    News.Datum
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID
LEFT JOIN
    News_Kommentar ON
    News.ID = News_Kommentar.NewsID
GROUP BY
    News.ID;

Obwohl wir nach News.ID gruppieren lesen wir weiterhin die gleichen Werte wie User.Username oder News.Inhalt aus. Dies ist auch kein Problem da die Werte eh für eine bestimmte News-ID die gleichen sind. Im Hinterkopf behalten wir jedoch das für gleiche News-IDs unterschiedliche Newskommentare zusammengefasst wurden. Mit der COUNT-Funktion von MySQL fragen wir nun ab wieviele Datensätze zusammengefasst wurden.

SELECT
    News.ID,
    User.Username,
    News.Titel,
    News.Inhalt,
    News.Datum,
    COUNT(News_Kommentar.ID) AS Anzahl
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID
LEFT JOIN
    News_Kommentar ON
    News.ID = News_Kommentar.NewsID
GROUP BY
    News.ID;

Nun liefert diese Anfrage die Anzahl der Kommentare zurück. Es sieht jedoch komisch aus dass er für die Newsbeiträge die keine Kommentare enthalten die Anzahl auf 0 errechnet. Dies klingt zwar logisch, aber grade wurde gesagt MySQL hat einen Pseudo-Datensatz mit NULL-Werten erzeugt. Somit müsste die COUNT()-Funktion diesen Datensatz finden und zählen. Und das genau macht sie, denn in der Funktionsbeschreibung zu COUNT() steht folgendes.

COUNT(expr) - Returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement.

Das wichtige ist der non-NULL-Teil denn er gibt an das NULL-Werte beim Zählen ignoriert werden. Und da News_Kommentar.ID bei nicht vorhandenen Datensätze NULL ist liefert der Aufruf von COUNT(News_Kommentar.ID) entsprechend 0.

Zum Schluss geben wir der Spalte User.Username ein Alias auf Autor und sortieren die News nach der Datum spalte.

SELECT
    News.ID,
    User.Username AS Autor,
    News.Titel,
    News.Inhalt,
    News.Datum,
    COUNT(News_Kommentar.ID) AS Anzahl
FROM
    News
JOIN
    User ON
    News.AutorID = User.ID
LEFT JOIN
    News_Kommentar ON
    News.ID = News_Kommentar.NewsID
GROUP BY
    News.ID
ORDER BY
    News.Datum ASC;

Somit haben wir die Anfrage die wir an die Datenbank senden können und sie liefert uns die News mit dem Name des Autors und der Anzahl der Kommentare.

12. News laden und anzeigen

Diese Anfrage senden wir nun mit der query()-Methode an die Datenbank und lesen die News aus. Die Include-Datei heißt dabei news.php und muss entsprechend im $dateien-Array definiert werden.

<?php
$ret 
= array();
$ret['filename'] = 'news.tpl';
$ret['data'] = array();
$sql 'SELECT
            News.ID,
            User.Username AS Autor,
            News.Titel,
            News.Inhalt,
            News.Datum,
            COUNT(News_Kommentar.ID) AS Anzahl
        FROM
            News
        JOIN
            User
        ON
            News.AutorID = User.ID
        LEFT JOIN
            News_Kommentar
        ON
            News.ID = News_Kommentar.NewsID
        GROUP BY
            News.ID
        ORDER BY
            News.Datum DESC'
;
if (!
$result $db->query($sql)) {
    return 
$db->error;
}
$News = array();
?>

Während wir die News auslesen fragen wir innerhalb der noch zu schreibenen While-Schleife die Links der News ab und speichern sie gleich mit ab.

<?php
// [...]
$News = array();
$sql 'SELECT
            URL,
            Beschreibung
        FROM
            News_Link
        WHERE
            NewsID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
while (
$row $result->fetch_assoc()) {
    
$stmt->bind_param('i'$row['ID']);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$Links = array();
    
$stmt->bind_result($URL$Beschreibung);
    while (
$stmt->fetch()) {
        
$Links[] = array('URL' => $URL,
                         
'Beschreibung' => $Beschreibung);
    }
    
$row['Links'] = $Links;
    
$News[] = $row;
}
$stmt->close();
$result->close();
$ret['data']['News'] = $News;
return 
$ret;
?>

Somit ist schonmal das Anzeigen der News fertig, fehlt noch der Bereich für die Newskommentare.

13. Anzeigen und schreiben von Newskommentaren

In der Template-Datei für die News-Anzeige sehen wir dass die URL index.php?section=newscomments&ID=... aufgerufen wird. Für die Kommentarfunktion schreiben wir zuerst die Template-Datei newscomments.tpl.

<?php
/* Daten
 *     ID - Die ID der News
 *     Autor - Der Name des Autors der die News geschrieben hat
 *     Datum - Das Datum der Veröffentlichung
 *     Titel - Der Titel der News
 *     Inhalt - Der Text der News
 *     Links - Ein Array mit Links mit den folgendem Aufbau:
 *         URL - Die URL vom Link
 *         Beschreibung - Der Bezeichner vom Link
 *     Kommentare - Ein Array mit Newskommentare
 *         ID - Die ID vom Kommentar
 *         Autor - Der Name des Autors der den Kommentar geschrieben hat
 *         Inhalt - Der Text vom Kommentar
 *         Datum - Das Datum wann der Kommentar abgegeben wurde
 */
?><h1>News</h1>
<h2><?php echo htmlspecialchars($data['Titel']); ?></h2>
<div class="newsheader">Geschrieben von <?php echo htmlspecialchars($data['Autor']); ?> um
    <?php echo htmlspecialchars($data['Datum']); ?></div>
<p>
    <?php echo nl2br(htmlspecialchars($data['Inhalt'])); ?>
</p>
<?php if (count($data['Links'])) { ?>
<div class="links">
    Links:
    <ul>
        <?php foreach ($data['Links'] as $Link) { ?>
        <li><a href="<?php echo $Link['URL']; ?>"><?php echo htmlspecialchars($Link['Beschreibung']); ?></a></li>
        <?php } ?>
    </ul>
</div>
<?php } else { ?>
<p class="info">
    Keine Links vorhanden.
</p>
<?php } ?>
<h3>Kommentare</h3>
<?php if (count($data['Kommentare'])) { ?>
<?php     foreach ($data['Kommentare'] as $Kommentar) { ?>
<div class="comment">
    <?php echo htmlspecialchars($Kommentar['Autor']); ?> schrieb um <?php echo htmlspecialchars($Kommentar['Datum']); ?>:
    <p>
        <?php echo nl2br(htmlspecialchars(preg_replace('~\S{30}~', '\0 ', $Kommentar['Inhalt']))); ?>
    </p>
</div>
<?php     } ?>
<?php } else { ?>
<p class="info">
    Keine Kommentare vorhanden
</p>
<?php } ?>
<?php if (getUserID($db)) { ?>
<form action="index.php?section=newscomments&amp;ID=<?php echo $data['ID']; ?>" method="post">
    <fieldset>
        <legend>Kommentar schreiben</legend>
        <label>Kommentar: <textarea name="Kommentar" cols="40" rows="10"></textarea></label>
        <input type="submit" name="formaction" value="Kommentar schreiben" />
    </fieldset>
</form>
<?php } else { ?>
<p class="info">
    Um Kommentare schreiben zu können müssen sie sich anmelden.
</p>
<?php } ?>

In der Include-Datei newscomments.php gucken wir zuerst ob es eine News gibt und lesen dann alle Daten aus. Vergisst nicht das $dateien-Array zu bearbeiten.

<?php
$ret 
= array();
$ret['filename'] = 'newscomments.tpl';
$ret['data'] = array();
if (!isset(
$_GET['ID'])) {
    return 
'Benutzen sie nur Links von der Homepage.';
}
if (
'' == $ID trim($_GET['ID'])) {
    return 
'Benutzen sie nur Links von der Homepage.';
}
$sql 'SELECT
            News.ID,
            User.Username AS Autor,
            News.Titel,
            News.Inhalt,
            News.Datum
        FROM
            News
        JOIN
            User ON
            News.AutorID = User.ID
        WHERE
            News.ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$ID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->bind_result($NewsID$Autor$Titel$Inhalt$Datum);
if (!
$stmt->fetch()) {
    return 
'Es wurde keine News mit der angegebenen ID gefunden.';
}
$stmt->close();

if (
'POST' == $_SERVER['REQUEST_METHOD']) {
    
// [...]
    // todo
}
$sql 'SELECT
            URL,
            Beschreibung
        FROM
            News_Link
        WHERE
            NewsID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$NewsID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$Links = array();
$stmt->bind_result($URL$Beschreibung);
while (
$stmt->fetch()) {
    
$Links[] = array('URL' => $URL,
                     
'Beschreibung' => $Beschreibung);
}
$stmt->close();

$sql 'SELECT
            News_Kommentar.ID,
            User.Username AS Autor,
            News_Kommentar.Inhalt,
            News_Kommentar.Datum
        FROM
            News_Kommentar
        JOIN
            User ON
            News_Kommentar.AutorID = User.ID
        WHERE
            News_Kommentar.NewsID = ?
        ORDER BY
            News_Kommentar.Datum ASC'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$NewsID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$Kommentare = array();
$stmt->bind_result($KomID$KomAutor$KomInhalt$KomDatum);
while (
$stmt->fetch()) {
    
$Kommentare[] = array('ID' => $KomID,
                          
'Autor' => $KomAutor,
                          
'Inhalt' => $KomInhalt,
                          
'Datum' => $KomDatum);
}
$stmt->close();
$ret['data']['ID'] = $NewsID;
$ret['data']['Autor'] = $Autor;
$ret['data']['Titel'] = $Titel;
$ret['data']['Inhalt'] = $Inhalt;
$ret['data']['Datum'] = $Datum;
$ret['data']['Links'] = $Links;
$ret['data']['Kommentare'] = $Kommentare;
return 
$ret;
?>

Wenn wir das Formular abschicken speichern wir einfach die Eingaben ab.

<?php
// [...]
$stmt->close();

if (
'POST' == $_SERVER['REQUEST_METHOD']) {
    if (!isset(
$_POST['formaction'], $_POST['Kommentar'])) {
        return 
INVALID_FORM;
    }
    if (!
$UserID getUserID($db)) {
        return 
NOT_LOGGED_IN;
    }
    if (
'' == $Kommentar trim($_POST['Kommentar'])) {
        return 
EMPTY_FORM;
    }
    
$sql 'SELECT
                ID
            FROM
                News_Kommentar
            WHERE
                NewsID = ? AND
                AutorID = ? AND
                Inhalt = ?'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('iis'$NewsID$UserID$Kommentar);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    if (
$stmt->fetch()) {
        return 
'Sie haben bereits den Kommentar hinzugefügt.';
    }
    
$stmt->close();

    
$sql 'INSERT INTO
                News_Kommentar(NewsID, AutorID, Inhalt, Datum)
            VALUES
                (?, ?, ?, NOW())'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('iis'$NewsID$UserID$Kommentar);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$stmt->close();
    return 
showInfo('Ihr Kommentar wurde hinzugefügt.');
}
$sql 'SELECT
            URL,
            Beschreibung
        FROM
            News_Link
        WHERE
            NewsID = ?'
;
// [...]
?>

Mit der SELECT-Abfrage überprüfen wir ob der Kommentar bereits hinzugefügt wurde, also eine Art von Mini-Spamschutz.

14. Newskommentar bearbeiten

Admins sollten weiterhin die Möglichkeit haben einen Newskommentar zu bearbeiten oder sogar zu löschen. Daher fügen wir für unserem Adminbereich das Recht NewsKom hinzu. Da es Sinnfrei ist neue Kommentare über das Adminmenu hinzuzufügen legen wir die Datei admin_NewsKom_add.php an die nur eine Fehlermeldung zurückliefert.

<?php
return 'Sie können keine Newskommentare über das Adminmenu hinzufügen.';
?>

Wir werden mehrere Template-Dateien anlegen um eine News auszuwählen, um ein Kommentar auszuwählen und dann um den Kommentar zu bearbeiten.

<?php
/* Daten:
 *    News - Ein Array mit allen News im System.
 *        ID - Die ID der News
 *        Titel - Der Titel der News
 *        Datum - Das Datum wann die News geschrieben wurde
 */
?><form action="index.php?section=admin&amp;cat=NewsKom&amp;action=edit" method="post">
    <fieldset>
        <legend>News wählen</legend>
        <label>News: <select name="NewsID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['News'] as $value) { ?>
            <option value="<?php echo $value['ID']; ?>">(<?php echo htmlspecialchars($value['Datum']); ?>)
                <?php echo htmlspecialchars($value['Titel']); ?></option>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="News wählen" />
    </fieldset>
</form>

Dieses Template (admin_NewsKom_edit_select_news.tpl) zeigen wir dann an wenn die URL mit der GET-Methode aufgerufen wurde.

<?php
$ret 
= array();
$ret['filename'] = 'admin_NewsKom_edit_select_news.tpl';
$ret['data'] = array();
if (
'POST' != $_SERVER['REQUEST_METHOD']) {
    
$sql 'SELECT
                ID,
                Titel,
                Datum
            FROM
                News
            ORDER BY
                Datum DESC'
;
    if (!
$result $db->query($sql)) {
        return 
$db->error;
    }
    
$News = array();
    while (
$row $result->fetch_assoc()) {
        
$News[] = $row;
    }
    
$result->close();
    
$ret['data']['News'] = $News;
    return 
$ret;
}
// [...]
?>

Wenn eine News ausgewählt wurde zeigen wir die Kommentare an und wählen dann einen aus. Die Template-Datei admin_NewsKom_edit_select_comment.tpl sieht wie folgt aus.

<?php
/* Daten:
 *    Kommentare - Ein Array mit allen Kommentare der zuvor gewählten News.
 *        ID - Die ID vom Kommentar
 *        Datum - Das Datum der Veröffentlichung
 *        Autor - Der Autor der den Kommentar geschrieben hat
 *        Inhalt - Der Kommentar selbst
 */
?><form action="index.php?section=admin&amp;cat=NewsKom&amp;action=edit" method="post">
    <fieldset>
        <legend>Kommentar wählen</legend>
        <label>Kommentar: <select name="KommentarID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['Kommentare'] as $Kommentar) { ?>
            <option value="<?php echo $Kommentar['ID']; ?>">(<?php echo htmlspecialchars($Kommentar['Datum']); ?>)
            [<?php echo htmlspecialchars($Kommentar['Autor']); ?>]
            <?php echo htmlspecialchars(substr($Kommentar['Inhalt'], 0, 60).'...'); ?>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="Kommentar wählen" />
    </fieldset>
</form>

Und mit folgendem PHP-Code zeigen wir es an.

<?php
// [...]
    
$ret['data']['News'] = $News;
    return 
$ret;
}
if (!isset(
$_POST['formaction'])) {
    return 
INVALID_FORM;
}
if (
'News wählen' == $_POST['formaction']) {
    if (!isset(
$_POST['NewsID'])) {
        return 
INVALID_FORM;
    }
    if (
'' == $NewsID trim($_POST['NewsID'])) {
        return 
EMPTY_FORM;
    }
    
$sql 'SELECT
                ID
            FROM
                News
            WHERE
                ID = ?'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('i'$NewsID);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$stmt->bind_result($NewsID);
    if (!
$stmt->fetch()) {
        return 
'Es wurde keine News mit der angegebenen ID gefunden.';
    }
    
$stmt->close();

    
$sql 'SELECT
                News_Kommentar.ID,
                News_Kommentar.Datum,
                User.Username AS Autor,
                News_Kommentar.Inhalt
            FROM
                News_Kommentar
            JOIN
                User ON
                News_Kommentar.AutorID = User.ID
            WHERE
                News_Kommentar.NewsID = ?
            ORDER BY
                Datum DESC'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('i'$NewsID);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$Kommentare = array();
    
$stmt->bind_result($ID$Datum$Autor$Inhalt);
    while (
$stmt->fetch()) {
        
$Kommentare[] = array('ID' => $ID,
                              
'Datum' => $Datum,
                              
'Autor' => $Autor,
                              
'Inhalt' => $Inhalt);
    }
    
$stmt->close();
    
$ret['filename'] = 'admin_NewsKom_edit_select_comment.tpl';
    
$ret['data']['Kommentare'] = $Kommentare;
    return 
$ret;
}
// [...]
?>

Danach zeigen wir nun endlich das Formular an um ein Kommentar bearbeiten zu können.

<?php
/* Daten
 *    ID - Die ID vom Kommentar
 *    Inhalt - Der Inhalt vom Kommentar
 */
?><form action="index.php?section=admin&amp;cat=NewsKom&amp;action=edit" method="post">
    <fieldset>
        <legend>Kommentar bearbeiten</legend>
        <label>Kommentar: <textarea name="Inhalt" cols="40" rows="8"><?php echo htmlspecialchars($data['Inhalt']); ?></textarea></label>
        <input type="submit" name="formaction" value="Kommentar speichern" />
        <input type="hidden" name="ID" value="<?php echo $data['ID']; ?>" />
    </fieldset>
</form>

Der PHP-Code sieht wie folgt aus.

<?php
// [...]
    
$ret['data']['Kommentare'] = $Kommentare;
    return 
$ret;
}
if (
'Kommentar wählen' == $_POST['formaction']) {
    if (!isset(
$_POST['KommentarID'])) {
        return 
INVALID_FORM;
    }
    if (
'' == $KommentarID trim($_POST['KommentarID'])) {
        return 
EMPTY_FORM;
    }
    
$sql 'SELECT
                ID,
                Inhalt
            FROM
                News_Kommentar
            WHERE
                ID = ?'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('i'$KommentarID);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$stmt->bind_result($ID$Inhalt);
    if (!
$stmt->fetch()) {
        return 
'Es wurde kein Kommentar mit der angegebenen ID gefunden.';
    }
    
$stmt->close();
    
$ret['data']['ID'] = $ID;
    
$ret['data']['Inhalt'] = $Inhalt;
    
$ret['filename'] = 'admin_NewsKom_edit_change.tpl';
    return 
$ret;
}
// [...]
?>

Nachdem wir den Inhalt geändert haben speichern wir diesen in der Datenbank ab.

<?php
// [...]
    
$ret['filename'] = 'admin_NewsKom_edit_change.tpl';
    return 
$ret;
}
if (!isset(
$_POST['ID'], $_POST['Inhalt'])) {
    return 
INVALID_FORM;
}
if (
'' == $Inhalt trim($_POST['Inhalt']) OR
        
'' == $ID trim($_POST['ID'])) {
    return 
EMPTY_FORM;
}
$sql 'SELECT
            ID
        FROM
            News_Kommentar
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$ID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->bind_result($ID);
if (!
$stmt->fetch()) {
    return 
'Es wurde kein Kommentar mit der angegebenen ID gefunden.';
}
$stmt->close();

$sql 'UPDATE
            News_Kommentar
        SET
            Inhalt = ?
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('si'$Inhalt$ID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->close();
return 
showInfo('Der Kommentar wurde bearbeitet.');
?>

Jetzt können wir Kommentare bearbeiten.

15. Kommentare löschen

Fürs löschen können wir die selben Auswahlformulare verwenden wie fürs Bearbeiten. Wir müssen nur die URLS und Submitbuttons verändern.

<?php
/* Daten:
 *    News - Ein Array mit allen News im System.
 *        ID - Die ID der News
 *        Titel - Der Titel der News
 *        Datum - Das Datum wann die News geschrieben wurde
 */
?><form action="index.php?section=admin&amp;cat=NewsKom&amp;action=del" method="post">
    <fieldset>
        <legend>News wählen</legend>
        <label>News: <select name="NewsID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['News'] as $value) { ?>
            <option value="<?php echo $value['ID']; ?>">(<?php echo htmlspecialchars($value['Datum']); ?>)
                <?php echo htmlspecialchars($value['Titel']); ?></option>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="News wählen" />
    </fieldset>
</form>
<?php
/* Daten:
 *    Kommentare - Ein Array mit allen Kommentare der zuvor gewählten News.
 *        ID - Die ID vom Kommentar
 *        Datum - Das Datum der Veröffentlichung
 *        Autor - Der Autor der den Kommentar geschrieben hat
 *        Inhalt - Der Kommentar selbst
 */
?><form action="index.php?section=admin&amp;cat=NewsKom&amp;action=del" method="post">
    <fieldset>
        <legend>Kommentar wählen</legend>
        <label>Kommentar: <select name="ID">
            <option value="0">Bitte wählen</option>
            <?php foreach ($data['Kommentare'] as $Kommentar) { ?>
            <option value="<?php echo $Kommentar['ID']; ?>">(<?php echo htmlspecialchars($Kommentar['Datum']); ?>)
            [<?php echo htmlspecialchars($Kommentar['Autor']); ?>]
            <?php echo htmlspecialchars(substr($Kommentar['Inhalt'], 0, 60).'...'); ?>
            <?php } ?>
            </select></label>
        <input type="submit" name="formaction" value="Kommentar löschen" />
    </fieldset>
</form>
<?php
$ret 
= array();
$ret['filename'] = 'admin_NewsKom_del_select_news.tpl';
$ret['data'] = array();
if (
'POST' != $_SERVER['REQUEST_METHOD']) {
    
$sql 'SELECT
                ID,
                Titel,
                Datum
            FROM
                News
            ORDER BY
                Datum DESC'
;
    if (!
$result $db->query($sql)) {
        return 
$db->error;
    }
    
$News = array();
    while (
$row $result->fetch_assoc()) {
        
$News[] = $row;
    }
    
$result->close();
    
$ret['data']['News'] = $News;
    return 
$ret;
}
if (!isset(
$_POST['formaction'])) {
    return 
INVALID_FORM;
}
if (
'News wählen' == $_POST['formaction']) {
    if (!isset(
$_POST['NewsID'])) {
        return 
INVALID_FORM;
    }
    if (
'' == $NewsID trim($_POST['NewsID'])) {
        return 
EMPTY_FORM;
    }
    
$sql 'SELECT
                ID
            FROM
                News
            WHERE
                ID = ?'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('i'$NewsID);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$stmt->bind_result($NewsID);
    if (!
$stmt->fetch()) {
        return 
'Es wurde keine News mit der angegebenen ID gefunden.';
    }
    
$stmt->close();

    
$sql 'SELECT
                News_Kommentar.ID,
                News_Kommentar.Datum,
                User.Username AS Autor,
                News_Kommentar.Inhalt
            FROM
                News_Kommentar
            JOIN
                User ON
                News_Kommentar.AutorID = User.ID
            WHERE
                News_Kommentar.NewsID = ?
            ORDER BY
                Datum DESC'
;
    if (!
$stmt $db->prepare($sql)) {
        return 
$db->error;
    }
    
$stmt->bind_param('i'$NewsID);
    if (!
$stmt->execute()) {
        return 
$stmt->error;
    }
    
$Kommentare = array();
    
$stmt->bind_result($ID$Datum$Autor$Inhalt);
    while (
$stmt->fetch()) {
        
$Kommentare[] = array('ID' => $ID,
                              
'Datum' => $Datum,
                              
'Autor' => $Autor,
                              
'Inhalt' => $Inhalt);
    }
    
$stmt->close();
    
$ret['filename'] = 'admin_NewsKom_del_select_comment.tpl';
    
$ret['data']['Kommentare'] = $Kommentare;
    return 
$ret;
}
if (!isset(
$_POST['ID'])) {
    return 
INVALID_FORM;
}
if (
'' == $ID trim($_POST['ID'])) {
    return 
EMPTY_FORM;
}
$sql 'SELECT
            ID
        FROM
            News_Kommentar
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$ID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->bind_result($ID);
if (!
$stmt->fetch()) {
    return 
'Es wurde kein Kommentar mit der angegebenen ID gefunden.';
}
$stmt->close();

$sql 'DELETE FROM
            News_Kommentar
        WHERE
            ID = ?'
;
if (!
$stmt $db->prepare($sql)) {
    return 
$db->error;
}
$stmt->bind_param('i'$ID);
if (!
$stmt->execute()) {
    return 
$stmt->error;
}
$stmt->close();
return 
showInfo('Der Kommentar wurde gelöscht.');
?>

Nun ist unser neues Newsskript fertig.

Fragen zum Kapitel

Keine Fragen zum Kapitel vorhanden

Zurück zu Weiter zu
Copyright © bei den OPs von #php.de/QuakeNet Valid XHTML 1.0 Strict Valid CSS!