WordPress multidomainfähig machen – Eine WordPress-Installation für mehrere Blogs

Die Überlegung ist simpel: Ich besitze mehrere Blogs zu unterschiedlichen Themen, die ich auf demgleichen Server mit Verwendung der WordPress-Blogsoftware und Verwendung der gleichen Datenbank hoste. Jeder Blog basiert auf seiner eigenen WordPress-Installation und ist in seinem eigenen Ordner hinterlegt. Das bedeutet aber auch: Jeden Blog einzeln auf neue WordPress-Installationen und für jeden Blog jedes einzelne Plugin bei Updates aktualisieren. Eine Menge Administrationsaufwand…

Dabei geht es viel einfacher. Warum nicht eine einzelne WordPress-Installation für mehrere Blogs und Domains nutzen? Die WordPress-Installation also multidomainfähig machen. So muss nur ein einziges WordPress-System muss aktualisiert werden und alle meine Blogs arbeiten mitder neuesten Version.

1. Schritt – alle WordPress-Installationen auf die gleiche Version updaten

Damit die Zusammenführung reibungslos funktioniert müssen zunächst alle vorhandenen WordPress-Installationen ein letztes mal auf die aktuellste – oder zumindest gleiche – Version aktualisiert werden.

2. Schritt – einen neue WordPress-Installation in neuem Verzeichnis anlegen

Sind alle WordPress-Installationen auf die gleiche Version aktualisiert worden müssen wir eine komplett neue WordPress-Installation anlegen. Dazu laden wir die benötigte WordPress-Version herunter und entpacken sie auf unseren Server in einem neuen Verzeichnis. Achtung: Die Installation selbst muss nicht ausgeführt werden. Lediglich die Dateien müssen auf den Server entpackt werden.

3. Schritt – eine neue Datenbank anlegen (optional)

Um die neue Installation von allen vorherigen zu trennen empfehle ich eine neue Datenbank anzulegen. Das muss aber nicht sein. Die WordPress-Installation kann auch in einer bereits vorhanden Datenbank arbeiten.

3. Schritt – die wp-config.php anpassen

Der Trick ist einfach: WordPress nutzt für die Datenbank einen Table_Prefix. Dieser wird in der wp-config.php festgelegt und kann von uns beliebig verändert werden. Folgende Änderungen an der Variablendeklaration von $table_prefix müssen an der wp-config vorgenommen werden:

$table_prefix = str_replace(array('.', '-' ), '_', $_SERVER['HTTP_HOST'] ) . '_';
$table_prefix = str_replace(array('www_'), '', $table_prefix);

Unser Table_Prefix wird jetzt also gemäß unserer aufgerufenen Domain ausgewählt. Striche und Punkte werden in Unterstriche übersetzt, das “www” entfernt. Beispiel:

  • “www.mein-cooler-blog.de” wird auf die Tabellen mit dem Table_Prefix “mein_cooler_blog_de_” basieren
  • “www.meinblog.com” wird auf die Tabellen mit dem Table_Prefix “meinblog_com_” basieren
  • “blog.meine-domain.de” wird auf die Tabellen mit dem Table_Prefix “blog_meine_domain_de_” basieren

Dazu müssen die Verbindungsdaten der (neu erstellten) Datenbank wie gewohnt in der wp-config.php angepasst werden.

4. Schritt – alle wp-content Ordner übertragen

Sämtliche wp-content Ordner aus den alten WordPress-Installationen müssen in die neue Installation übertragen werden. Dabei werden alle Bilder, Medien, Plugins und Skins mit übertragen.

5. Schritt – die Datenbanktabellen umziehen

In diesem Schritt müssen alle Datenbanktabellen der einzelnen WordPress-Installationen in die (neu erstellte) Datenbank umgezogen werden. Das lässt sich mit php_MyAdmin recht leicht lösen (allerdings wird der Table_Prefix nicht geändert und muss manuel geändert werden):

Umzug einer Datenbank in phpMyAdminDas PHP-Skript macht dagegen alles vollautomatisch und ändert den Table_Prefix gleich mit:

<?php
function echoOk($msg) { echo('[OK]    ' . $msg . "\n"); }
?><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Datenbank-Umzug</title>
<style>
    div.form label, div.form input {
        display: block;
    }
    div.form label {
        margin: 10px 0 5px 0;
    }
    div.form input {
        margin: 5px 0 10px 0;
    }
</style>
</head>
<body>
<?php
    $formElements = array('server', 'username', 'password',
        'database', 'newdatabase',
        'tableprefix', 'newtableprefix');
    $showForm = false;
    foreach($formElements as $element) {
        if(!isset($_POST[$element])) {
            $showForm = true;
        }
    }
    if($showForm) {
?>
<div class="form">
    <form action="" method="post">
        <fieldset>
            <label for="server">Datenbank-Server</label>
            <input type="text" name="server" />
            <label for="username">Benutzername</label>
            <input type="text" name="username" />
            <label for="password">Passwort</label>
            <input type="password" name="password" />
        </fieldset>
        <fieldset>
            <label for="database">Ursprüngliche Datenbank</label>
            <input type="text" name="database" />
            <label for="newdatabase">Neue Datenbank</label>
            <input type="text" name="newdatabase" />
            <label for="tableprefix">Ursprünglicher Table_Prefix</label>
            <input type="text" name="tableprefix" />
            <label for="newtableprefix">Neuer Table_Prefix</label>
            <input type="text" name="newtableprefix" />
        </fieldset>
        <fieldset>
            <p>ACHTUNG: Dieses Skript sendet manche der eingegebenen Daten ungefiltert an die Datenbank und überschreibt bereits existierende Tabellen beim Umzug!</p>
            <input type="submit" />
        </fieldset>
    </form>
</div>
<?php } else {
    echo('<pre>');
    try {

        $con = mysql_connect($_POST['server'], $_POST['username'], $_POST['password']);
        if(!$con) {
            throw new Exception('Verbindung mit Server nicht möglich. ' . mysql_error());
        } else {
            echoOk('Mit \'' . htmlentities($_POST['server']) . '\' verbunden.');
        }

        if(!mysql_select_db($_POST['database'], $con)) {
            throw new Exception('Auswahl der Datenbank nicht möglich. ' . mysql_error());
        } else {
            echoOk('Aktuelle Datenbank \'' . htmlentities($_POST['database']) . '\'.');
        }

        $res = mysql_query('SHOW TABLES IN `' . $_POST['database'] . '` LIKE \'' . $_POST['tableprefix'] . '%\'', $con);
        if(!$res) {
            throw new Exception('Fehler bei Datenbankabfrage. ' . mysql_error());
        } else {
            while($result = mysql_fetch_row($res)) {
                $tables[] = $result[0];
                $newTables[] = str_replace($_POST['tableprefix'], $_POST['newtableprefix'], $result[0]);
            }
            $numTables = count($tables);
            if($numTables > 0) {
                echoOk($numTables . ' Tabellen mit Table_Prefix \'' . htmlentities($_POST['tableprefix']) . '\' in Datenbank \'' . htmlentities($_POST['database']) . '\' gefunden.');
            } else {
                throw new Exception('Keine Tabellen mit Table_Prefix \'' . htmlentities($_POST['tableprefix']) . '\' gefunden.');
            }
        }

        foreach($tables as $num => $table) {
            $res = mysql_query('DROP TABLE IF EXISTS `' . $_POST['newdatabase'] . '`.`' . $newTables[$num] . '`', $con);
            if(!$res) {
                throw new Exception('Fehler bei Datenbankabfrage: ' . mysql_error());
            }
            $res = mysql_query('CREATE TABLE `' . $_POST['newdatabase'] . '`.`' . $newTables[$num] . '` LIKE `' . $_POST['database'] . '`.`' . $table . '`');
            if(!$res) {
                throw new Exception('Fehler bei Datenbankabfrage: ' . mysql_error());
            }
            $res = mysql_query('INSERT INTO `' . $_POST['database'] . '`.`' . $table . '` SELECT * FROM `' . $_POST['newdatabase'] . '`.`' . $newTables[$num] . '`');
            if(!$res) {
                throw new Exception('Fehler bei Datenbankabfrage: ' . mysql_error());
            } else {
                $process = round($num / $numTables * 100);
                if($process < 10) {
                    $process = ' ' . $process;
                }
                if($process < 100) {
                    $process = ' ' . $process;
                }
                echoOk('[' . $process . '%] Tabelle \'' . htmlentities($table) . '\' nach \'' . htmlentities($newTables[$num]) . '\' kopiert.');
            }
        }
        echoOk('[100%] ' . $numTables . ' Tabellen kopiert.');

        if(!mysql_close($con)) {
            throw new Exception('Verbindung mit Server konnte nicht geschlossen werden.');
        } else {
            echoOk('Verbindung mit Server geschlossen.');
        }

    } catch(Exception $e) {
        echo('[ERROR] ' . $e->getMessage() . "\n");
    }
    echo('</pre>');
} ?>
</body>
</html>

Das Skript zum schnellen Umzug von mysql Tabellen kann auch hier heruntergeladen werden: PHP Skript zum schnellen Umzug von mysql Tabellen

6. Schritt – Domain ändern

Letzter Schritt: Die Domain muss jetzt nur noch auf den Speicherplatz der neuen WordPress-Installation umgestellt werden.

Troubleshooting bei “kaputten” Umlauten

Sollten Umlaute nicht funktionieren, empfehle ich diesen Blogpost: Den Inhalt einer mysql Datenbank in utf8 umwandeln

Share

Leave a Comment