Zum Inhalt

MongoDB als Datenbank in PHP verwenden

Wie einfach sich der Umgang mit MongoDB bei der Arbeit in PHP gestaltet, will ich hier anhand kurzer Beispiele zeigen . Die Vorzüge dieser Dokument-Orientierten Datenbank werden schnell ersichtlich, wenn man sieht wie einfach gängige Abläufe umgesetzt werden können. Ein grosser Vorteil von MongoDB gegenüber SQL-Datenbanken kann auch die Geschwindigkeit liegen. Dies kommt gerade bei der Ausgabe von grossen Mengen Content zum tragen. In diesem Artikel geht es aber erst einmal um den Einstieg.

 

php-logo

Verbindung zur Datenbank

In einer *.php-Datei, vorzugsweise einer Konfigurations-Datei welche wir später überall einbinden können, legen wir zu Beginn erst mal alle benötigten Angaben fest:

$db_host = 'localhost';
$db_port = '27017';
$db_name = 'mydatabase';
$db_user = 'myusername';
$db_pass = 'mypassword';

Dann stellen wir eine Verbindung zum Server her. Dazu gibt es mehrere Varianten. Am schnellsten ist eine Verbindung per Unix-Socket – wird emfpohlen! Dabei muss der Port angegeben werden. Achtung: Authentifizierung ist in MongoDB per default ausgeschaltet. Muss also in der Config eingeschaltet werden (später mehr dazu). Hier erstmal eine Verbindung ohne Authentifizierung.

$mongo = new MongoClient("mongodb:///tmp/mongodb-" . $db_port . ".sock");

Als nächstes das selbe mit Authentifizierung. Hier muss eine Datenbank angefügt werden, sofern der Nutzer eingeschränkte Rechte hat. Als Admin kann die Kollektion auch später noch gewählt werden.

$mongo = new MongoClient("mongodb://" . $db_user . ":" . $db_pass . "@/tmp/mongodb-" . $db_port . ".sock/" . $db_name);

Nun noch eine Verbindung übers Netzwerk, das sieht dann so aus. Der Port kann am Schluss angefügt werden muss aber nicht, falls nicht wird der Standart-Port 27017 genommen. Das ganze einmal ohne und einmal  mit Authentifizierung.

$mongo = new MongoClient("mongodb://" . $db_host . ":" . $db_port);

$mongo = new MongoClient("mongodb://" . $db_user . ":" . $db_pass . "@" . $db_host . ":" . $db_port);

Diese Art der Verbindung ist etwas langsamer, jedoch können damit auch entfernte Server angesprochen werden.

Um zu prüfen ob die Verbindung erfolgreich war nun folgendes:

if ($mongo->connected) {
    echo "verbunden";
} else {
    echo "nicht verbunden";
}

Sinnvoll wäre bestimmt auch eine Art Fallback Lösung. Falls eine Verbindung über Unix-Socked fehlschlägt, soll eine Netzwerkverbindung aufgebaut werden. Hier nur mal ein möglicher Ansatz:

function moauco($arr) {
    /*
     * MongoDB Authentication Connect
     * 
     * Als erstes wird versucht eine Socket Verbindung aufzubauen
     * geht natürlich nur mit localhost, sonst wird eine
     * Netzwerkverbindung aufgebaut.
     * 
     * @param $arr erwartet ein Array mit: 
     * [user]=Benutzername
     * [pass]=Passwort
     * [db]=Datenbankname
     * optional:
     * [host] falls leer - localhost
     * [port] falls leer - 27017
     * @ToDo - mehrere Serververbindungen ermöglichen
     */

    if (isset($arr['user'], $arr['pass'], $arr['db'])) {

        $a = false;

        if (!isset($arr['host'])) {
            $arr['host'] = 'localhost';
        }
        if (!isset($arr['port'])) {
            $arr['port'] = '27017';
        }
        a:
        if ($arr['host'] === 'localhost' && $a !== true) {
            $dbmsg = $arr['user'] . ":" . $arr['pass'] . "@/tmp/mongodb-" . $arr['port'] . ".sock/" . $arr['db'];
        } else {
            $dbmsg = $arr['user'] . ":" . $arr['pass'] . "@" . $arr['host'] . ":" . $arr['port'] . "/" . $arr['db'];
        }
        // verbinden
        $m = new MongoClient("mongodb://" . $dbmsg);

        if ($m->connect() == 1) {
            return $m;
        } else {
            if ($a === true)
                return false;
            $a = true;
            goto a;
        }
    }else {
        return false;
    }
}

Es ist auch möglich zu mehreren Servern gleichzeitig zu verbinden, dazu mehr auf php.net.

Daten in MongoDB speichern

Falls wir bei der Verbindung noch keine Datenbank gewählt haben, können wir das jetzt machen. Folgende Möglichkeiten haben wir:

$database = $mongo->$db_name;
//oder
$database = $mongo->selectDB($db_name);

nun können wir auf eine Datenbank zugreifen und eine Kollektion erstellen. In SQL würde das einer Tabelle entsprechen. Folgende Möglichkeiten haben wir (Falls die Kollektion nicht existiert wird sie somit erstellt)

$collection = $mongo->$db_name->meinekollektion;
$collection = $mongo->selectCollection($db_name, "mycollection");

Nun können wir die Kollektion füllen – also Datensätze anlegen nehmen wir mal ein paar Hündchen.

$dobermann = array(
    'name' => 'Blacky',
    'farbe' => 'schwarz',
    'jahrgang' => 2012,
    'eigenschaften' => array(
        'lieb',
        'guter Wachhund',
        'verfressen'
    )
);
$collection->insert($dobermann);

$boxer = array(
    'name' => 'Brownie',
    'farbe' => 'braun',
    'jahrgang' => 2012,
    'eigenschaften' => array(
        'verspielt',
        'verfressen'
    ),
    'ausbildung' => 'Schutzhund'
);
/*
 * wir können auch prüfen ob das insert erfolgreich war
 */
$insert = $collection->insert($boxer);

if ($insert) {
    echo 'gespeichert';
}

Es werden einfach ganze Arrays abgelegt was sehr praktisch ist. Im optimalen Fall fällt eine Datenaufarbeitung wie man es vor SQL-Inserts kennt komplett weg. Wie man sieht kann die Struktur auch verändet werden. Man ist nicht wie in SQL an feste Strukturen gebunden.

Daten aus MongoDB auslesen

Nun lesen wir die Daten wieder aus. Dies entspricht praktisch einem SELECT * in SQL.

$hunde = $collection->find();

foreach ($hunde AS $hund) {
    // name und barbe haben alle
    echo '<p>' . $hund['name'] . " ist " . $hund['farbe'] . "</p>\n";

    // zu den Eigenschaften
    if (isset($hund['eigenschaften'])) {
        echo "<h6>Eigenschaften:</h6>\n<ul>";
        foreach ($hund['eigenschaften'] AS $eigenschaft) {
            echo "\t<li>" . $eigenschaft . "</li>\n";
        }
        echo "</ul>";
    }

    // spezielles noch falls da
    if (isset($hund['ausbildung'])) {
        echo "<p>Ausbildung: ";
        echo $ausbildung . "</p>\n";
    }
}

Auch gezielt suchen ist möglich:

$find = $collection->find(array("jahrgang"=>2012));

foreach ($find as $hund) {
    print_r($hund);
}

Wir können auch mit findOne arbeiten, somit bekommen wir nur das erste Vorkommen. Oder mit weiteren Methoden.

$findone = $collection->findOne(array("jahrgang"=>2012));
/*
 * es kann auch belibig limitiert werden
 */
$find = $collection->find(array("jahrgang"=>2012))->limit(2);
/*
 * oder zählen
 */
$find = $collection->find(array("jahrgang"=>2012))->count();
/*
 * sortieren 1=ASC, -1=DESC
 */
$find = $collection->find(array("jahrgang"=>2012))->sort(array("name"=>1));
/*
 * Skip etwa für aufzählungen
 */
$find = $collection->find(array("jahrgang"=>2012))->skip(1);
/*
 * debug
 */
$find = $collection->find(array("jahrgang"=>2012))->explain();

So können wir ein Update durchführen. Wichtig hier ist $set es verhält sich wie “as” in mysql.

$update = $collection->update(array("name" => "Blacky"), array('$set' => array("name" => "BlackDog")));

Und noch zum Löschen. Hier muss man vorsichtig sein – auch löschen geht bei MongoDB sehr schnell und direkt. Mit $collection->remove(); leeren wir die Ganze Kollektion. In SQL wäre das eine leere Tabelle. Natürlich kann man auch nur bestimmte Datensaätze löschen, dazu übergibt man ein Array mit Kriterium und Wert.

$collection->remove(); // Alles löschen
$delete = $collection->remove(array("name" => "Blacky"));

If ($delete == true) {
    echo "Blacky wurde gelöscht!";
}

Es ist auch möglich optionen zu übergeben dazu mehr auf php.net.

Weiterführende Links:

Veröffentlicht inLösungenTipp's

Neueste Beiträge

Themen: