Suchfunktion integrieren

Wir wollen nun für unsere Datenverwaltungsprogramm eine Suchfunktion integrieren. Die Grundlagen haben wir bereits im Kapitel „SQL-Anweisungen vorbereiten, Werte „binden“ und SQL-Query ausführen“ unter http://www.php-kurs.com/db-sql-prepare-bind.htm kennen gelernt.

Dort haben wird den folgenden Code entwickelt:

$suche_nach = "%{$suchbegriff}%";
$suche = $db->prepare("SELECT vorname, nachname 
                       FROM kontakte 
                       WHERE nachname LIKE ? OR vorname LIKE ?");
$suche->bind_param('ss', $suche_nach, $suche_nach);
$suche->execute();
$suche->bind_result($vorname, $nachname);
while ($suche->fetch()) {
    echo "<li>";
    echo $vorname .' '. $nachname;
}

Für unsere Anwendung werden wir diesen nun anpassen. Wir wollen bei der Suche automatisch im Feld „vorname“, „nachname“ und „anmerkung“ suchen.

Im Vorfeld benötigen wir ein Formularfeld für die Suche, wo der Nutzer seine Eingaben machen kann. Dieses platzieren wir oberhalb der Tabelle:

?>
<form action="" method="get">
    suchen nach:
    <input type="hidden" name="aktion" value="suchen">
    <input type="text" name="suchbegriff" id="suchbegriff">
    <input type="submit" value="suchen">
</form>
<?php
if ( $modus_aendern == false ) {

Jetzt können wir über $_GET['suchbegriff'] auf die Suchanfrage vom Nutzer zugreifen. Im ersten Schritt fragen wir vor der allgemeinen Tabellenausgabe ab, ob eine Nutzeranfrage da ist und lassen diese auf dem Bildschirm ausgeben:

    if ( isset($_GET['suchbegriff']) and trim ($_GET['suchbegriff']) != '' )
    {
        $suchbegriff = trim ($_GET['suchbegriff']);
        echo "<p>Gesucht wird nach: <b>$suchbegriff</b></p>";

Dann packen wir um unsere Suchanfrage für die Teilsuche die entsprechenden „%“ vor und nach dem Suchbegriff

    if ( isset($_GET['suchbegriff']) and trim ($_GET['suchbegriff']) != '' )
    {
        $suchbegriff = trim ($_GET['suchbegriff']);
        echo "<p>Gesucht wird nach: <b>$suchbegriff</b></p>";
        $suche_nach = "%{$suchbegriff}%";

Jetzt wird typische 4er Schritt ausgeführt:

        $suche = $db->prepare("SELECT id, vorname, nachname, anmerkung, erstellt 
                     FROM kontakte 
                     WHERE nachname LIKE ? OR vorname LIKE ? OR anmerkung LIKE ?");
        $suche->bind_param('sss', $suche_nach,$suche_nach,$suche_nach);
        $suche->execute();
        $suche->bind_result($id, $vorname, $nachname, $anmerkung, $erstellt);

Die Ergebnisse sammeln wir per fetch() ein:

        $suche = $db->prepare("SELECT id, vorname, nachname, anmerkung, erstellt 
                     FROM kontakte 
                     WHERE nachname LIKE ? OR vorname LIKE ? OR anmerkung LIKE ?");
        $suche->bind_param('sss', $suche_nach,$suche_nach,$suche_nach);
        $suche->execute();
        $suche->bind_result($id, $vorname, $nachname, $anmerkung, $erstellt);
        while ($suche->fetch()) {
        }        

Und weißen die eingesammelten Daten einem Array in Form eines Objects zu. Das hört sich gerade umständlich an, aber wir wollen ja nicht in die bereits bestehende Ausgabefunktion eingreifen und diese erwartet genau diesen Aufbau!

        $suche = $db->prepare("SELECT id, vorname, nachname, anmerkung, erstellt 
                     FROM kontakte 
                     WHERE nachname LIKE ? OR vorname LIKE ? OR anmerkung LIKE ?");
        $suche->bind_param('sss', $suche_nach,$suche_nach,$suche_nach);
        $suche->execute();
        $suche->bind_result($id, $vorname, $nachname, $anmerkung, $erstellt);
        while ($suche->fetch()) {
            $daten[] = (object) array('id' => $id, 
                              'vorname'   => $vorname, 
                              'nachname'  => $nachname, 
                              'anmerkung' => $anmerkung, 
                              'erstellt'  => $erstellt);
        }      

Jetzt fehlt nicht mehr viel. Unser komplettes Einlesen der Tabellendaten wird nicht benötigt, wenn wie eine Suchanfrage haben. Daher können wir nun einfach den folgenden Teil in den else Bereich reinpacken. Unsere Daten liegen immer nun über $daten vor. Egal ob eine Suchanfrage vorliegt oder alles angezeigt werden soll.

if ( $modus_aendern == false ) {
    $daten = array();
    if ( isset($_GET['suchbegriff']) and trim ($_GET['suchbegriff']) != '' )
    {
        $suchbegriff = trim ($_GET['suchbegriff']);
        echo "<p>Gesucht wird nach: <b>$suchbegriff</b></p>"; 
        $suche_nach = "%{$suchbegriff}%";
        $suche = $db->prepare("SELECT id, vorname, nachname, anmerkung, erstellt 
                     FROM kontakte 
                     WHERE nachname LIKE ? OR vorname LIKE ? OR anmerkung LIKE ?");
        $suche->bind_param('sss', $suche_nach,$suche_nach,$suche_nach);
        $suche->execute();
        $suche->bind_result($id, $vorname, $nachname, $anmerkung, $erstellt);
        while ($suche->fetch()) {
            $daten[] = (object) array('id' => $id, 
                              'vorname'   => $vorname, 
                              'nachname'  => $nachname, 
                              'anmerkung' => $anmerkung, 
                              'erstellt'  => $erstellt);
        }
        $suche->close();
    }
    else
    {
        if ($erg = $db->query("SELECT *  FROM kontakte")) {
            if ($erg->num_rows) {
                while ($datensatz = $erg->fetch_object()) {
                    $daten[] = $datensatz;
                }
                $erg->free();
            }
        }
    }

Soweit scheint es ganz gut zu funktionieren. Allerdings wird bei der Suche im Formular zum Erfassen neuer Daten bereits bestehende Daten angezeigt. Hier sollten wir noch eine kleine Bereinigung durchführen!

if ( $modus_aendern == false ) {
    $daten = array();
    if ( isset($_GET['suchbegriff']) and trim ($_GET['suchbegriff']) != '' )
    {
        $suchbegriff = trim ($_GET['suchbegriff']);
        echo "<p>Gesucht wird nach: <b>$suchbegriff</b></p>"; 
        $suche_nach = "%{$suchbegriff}%";
        $suche = $db->prepare("SELECT id, vorname, nachname, anmerkung, erstellt 
                     FROM kontakte 
                     WHERE nachname LIKE ? OR vorname LIKE ? OR anmerkung LIKE ?");
        $suche->bind_param('sss', $suche_nach,$suche_nach,$suche_nach);
        $suche->execute();
        $suche->bind_result($id, $vorname, $nachname, $anmerkung, $erstellt);
        while ($suche->fetch()) {
            $daten[] = (object) array('id' => $id, 
                              'vorname'   => $vorname, 
                              'nachname'  => $nachname, 
                              'anmerkung' => $anmerkung, 
                              'erstellt'  => $erstellt);
        }
        $suche->close();
        $id        = '';
        $vorname   = '';
        $nachname  = '';
        $anmerkung = '';
        $erstellt  = '';        
    }
    else
    {
        if ($erg = $db->query("SELECT *  FROM kontakte")) {
            if ($erg->num_rows) {
                while ($datensatz = $erg->fetch_object()) {
                    $daten[] = $datensatz;
                }
                $erg->free();
            }
        }
    }

Allerdings „verlieren“ wir die Suchanfrage, wenn wir uns einen Datensatz ansehen und dann zurück zum Anzeigen der Tabelle gehen. Dieses Problem sollten wir Grundsätzlich angehen, da wir auch später eine Lösung für das Seitenweise anzeigen der Tabelle benötigen. Dieses Grundlegende Problem lösen wir im folgenden Kapitel.

Und nun der komplette Quellcode bis zu diesem Punkt:

<?php
require 'inc/db.php';
if (isset($_GET['aktion']) and $_GET['aktion'] == 'sicherheitsabfrage') {
    if ( isset($_GET['id'])) {
        $id_einlesen = (INT) $_GET['id'];
        echo '<h1>Sicherheitsabfrage Löschen</h1>';
        echo '<p>Soll der folgende Datensatz unwiderruflich gelöscht werden?</p>';
        echo '<p><a href="?aktion=loeschen&id='. $id_einlesen.'">endgültig löschen!!</a></p>';
        $_GET['aktion'] = 'anzeigen';
    }
}
if (isset($_GET['aktion']) and $_GET['aktion'] == 'anzeigen') {
    if ( isset($_GET['id'])) {
        $id_einlesen = (INT) $_GET['id'];
        if ($id_einlesen > 0) {
            echo "<h1>Daten anzeigen von $id_einlesen</h1>";
            $dseinlesen = $db->prepare("SELECT id, vorname, nachname, anmerkung, erstellt 
                                               FROM kontakte WHERE id = ? ");
            $dseinlesen->bind_param('i', $id_einlesen);
            $dseinlesen->execute();
            $dseinlesen->bind_result($id, $vorname, $nachname, $anmerkung, $erstellt);
            $dseinlesen->fetch();
            echo "<p>ID: <b> $id </b><br>";          
            echo "Vorname: <b> $vorname </b><br>";          
            echo "Nachname: <b> $nachname </b><br>";          
            echo "Anmerkung: <b> $anmerkung </b><br>";          
            echo "erstellt am: <b> $erstellt </b></p>";          
            echo '<p><a href="index.php">Tabelle anzeigen</a>';
            $dseinlesen->close();
            exit;   
        }
    }
}
if (isset($_GET['aktion']) and $_GET['aktion'] == 'loeschen') {
    // löschen von Datensatz
    if (isset($_GET['id'])) {
        $id = (INT) $_GET['id'];
        if ( $id > 0)
        {
            $loeschen = $db->prepare("DELETE FROM kontakte WHERE id=? LIMIT 1");
            $loeschen->bind_param('i', $id);
            if ($loeschen->execute()) {
                echo "<p>Datensatz $id wurde gelöscht</p>";
            }
        }
    }
}
if (isset($_POST['aktion']) and $_POST['aktion']=='speichern' ) {
    $vorname = "";
    if (isset($_POST['vorname'])) {
        $vorname = trim($_POST['vorname']);
    }
    $nachname = "";
    if (isset($_POST['nachname'])) {
        $nachname = trim($_POST['nachname']);
    }
    $anmerkung = "";
    if (isset($_POST['anmerkung'])) {
        $anmerkung = trim($_POST['anmerkung']);
    }
    if ( $vorname != '' or $nachname != '' or $anmerkung != '' ) 
    {
        // speichern
        $einfuegen = $db->prepare("INSERT INTO kontakte
            (vorname, nachname, anmerkung, erstellt)
            VALUES (?, ?, ?, NOW())");
        $einfuegen->bind_param('sss', $vorname, $nachname, $anmerkung);
        if ($einfuegen->execute()) {
            header('Location: index.php?aktion=feedbackgespeichert');
            die();
        }
        echo "<p>Daten werden gespeichert</p>";
    }
}
if (isset($_GET['aktion']) and $_GET['aktion'] == 'feedbackgespeichert') {
    echo '<p class="feedbackerfolgreich">Datensatz wurde gespeichert</p>'; 
}
$modus_aendern = false;
if (isset($_GET['aktion']) and $_GET['aktion'] == 'bearbeiten') {
    $modus_aendern = true;
}
if (isset($_POST['aktion']) and $_POST['aktion'] == 'korrigieren') {
    $id = "";
    if ( isset ($_POST['id'])) {
        $id = (INT) trim($_POST['id']);
    }
    $vorname = "";
    if (isset($_POST['vorname'])) {
        $vorname = trim($_POST['vorname']);
    }
    $nachname = "";
    if (isset($_POST['nachname'])) {
        $nachname = trim($_POST['nachname']);
    }
    $anmerkung = "";
    if (isset($_POST['anmerkung'])) {
        $anmerkung = trim($_POST['anmerkung']);
    }
    if ( $id != '' AND ( $vorname != '' or $nachname != '' or $anmerkung != '')) {
        $update = $db->prepare("UPDATE kontakte SET
                                vorname = ?, nachname = ?, anmerkung = ?
                                WHERE id = ? LIMIT 1");
        $update->bind_param("sssi", $vorname, $nachname, $anmerkung, $id);
        if ( $update->execute() ) {
            echo '<p class="feedbackerfolg">Datensatz wurde geändert</p>';
            $modus_aendern = false;
        }
    }
}
?>
<form action="" method="get">
    suchen nach:
    <input type="hidden" name="aktion" value="suchen">
    <input type="text" name="suchbegriff" id="suchbegriff">
    <input type="submit" value="suchen">
</form>
<?php
if ( $modus_aendern == false ) {
    $daten = array();
    if ( isset($_GET['suchbegriff']) and trim ($_GET['suchbegriff']) != '' )
    {
        $suchbegriff = trim ($_GET['suchbegriff']);
        echo "<p>Gesucht wird nach: <b>$suchbegriff</b></p>"; 
        $suche_nach = "%{$suchbegriff}%";
        $suche = $db->prepare("SELECT id, vorname, nachname, anmerkung, erstellt FROM kontakte WHERE nachname LIKE ? OR vorname LIKE ? OR anmerkung LIKE ?");
        $suche->bind_param('sss', $suche_nach,$suche_nach,$suche_nach);
        $suche->execute();
        $suche->bind_result($id, $vorname, $nachname, $anmerkung, $erstellt);
        while ($suche->fetch()) {
            $daten[] = (object) array('id' => $id, 
                              'vorname'   => $vorname, 
                              'nachname'  => $nachname, 
                              'anmerkung' => $anmerkung, 
                              'erstellt'  => $erstellt);
        }
        $suche->close();
        $id        = '';
        $vorname   = '';
        $nachname  = '';
        $anmerkung = '';
        $erstellt  = '';
    }
    else
    {
        if ($erg = $db->query("SELECT *  FROM kontakte")) {
            if ($erg->num_rows) {
                while ($datensatz = $erg->fetch_object()) {
                    $daten[] = $datensatz;
                }
                $erg->free();
            }
        }
    }
if ( ! count($daten) ) {
    echo "<p>Es liegen keine Daten vor :(</p>";
} else {
?>
<table>
    <thead>
        <tr>
            <th>Nutzeraktion</th>
            <th>ID</th>
            <th>Vorname</th>
            <th>Nachname</th>
            <th>Anmerkung(en)</th>
            <th>erstellt</th>
        </tr>
    </thead>
    <tbody>
        <?php
        foreach ($daten as $inhalt) {
        ?>
        <tr>
            <td>
                <a href="?aktion=anzeigen&id=<?php echo $inhalt->id; ?>">anzeigen</a> 
                <a href="?aktion=bearbeiten&id=<?php echo $inhalt->id; ?>">ändern</a> 
                <a href="?aktion=sicherheitsabfrage&id=<?php echo $inhalt->id; ?>">löschen</a>
            </td>
            <td><?php echo $inhalt->id; ?></td>
            <td><?php echo bereinigen($inhalt->vorname); ?></td>
            <td><?php echo bereinigen($inhalt->nachname); ?></td>
            <td><?php echo bereinigen($inhalt->anmerkung); ?></td>
            <td><?php echo $inhalt->erstellt; ?></td>
        </tr>
        <?php
        }
        ?>
    </tbody>
</table>
<?php
    }
} else {
    echo "<h1>Daten ändern</h1>";
    if ( isset($_GET['id'])) {
        $id_einlesen = (INT) $_GET['id'];
        if ($id_einlesen > 0) {
            $dseinlesen = $db->prepare("SELECT id, vorname, nachname, anmerkung 
                                               FROM kontakte WHERE id = ? ");
            $dseinlesen->bind_param('i', $id_einlesen);
            $dseinlesen->execute();
            $dseinlesen->bind_result($id, $vorname, $nachname, $anmerkung);
            while ($dseinlesen->fetch()) {
                // echo "<li>";
                // echo $id ." / ". $vorname . " ". $nachname;          
            }
        }
    }
}
if ( ! isset($vorname) ) {
    $vorname = '';
}
if ( ! isset($nachname) ) {
    $nachname = '';
}
if ( ! isset($anmerkung) ) {
    $anmerkung = '';
}
?>
<form action="" method="post">
    <p><label>Vorname: 
        <input type="text" name="vorname" id="vorname" value="<?php echo $vorname; ?>">
    </label></p>
    <p><label>Nachname:
        <input type="text" name="nachname" id="nachname" value="<?php echo $nachname; ?>">
    </label></p>
    <p><label>Anmerkung(en):
        <textarea name="anmerkung" id="anmerkung"><?php echo $anmerkung; ?></textarea>
        </label></p>
    <?php    
    if ($modus_aendern != true ) {
        echo '<input type="hidden" name="aktion" value="speichern">';
        echo '<p><input type="submit" value="speichern"></p>';
    }
    else
    {
        echo '<input type="hidden" name="aktion" value="korrigieren">';
        echo '<input type="hidden" name="id" value="'. $id .'">';
        echo '<p><input type="submit" value="ändern"></p>';
    }
    ?>
</form>