WP-Funktionen: home_url und site_url – Unterschied und Verwendung


Formulare in WP richtig adressieren

Die WP-Funktion home_url() liefert die URL der Website, unter der die Website erreichbar ist und die Funktion site_url() die “WordPress-Adresse”. Ob sich die URL der Website (Adresse der Website oder einfach nur URL der Domain, falls die Startseite bzw. die Index-Seite von WordPress erreichbar ist, wenn nur die Domain in die Browserzeile eingegeben wird) von der “WordPress-Adresse” unterscheiden, hängt nicht von der Funktionalität beider Funktionen ab, sondern von der Installation und Erreichbarkeit Ihrer WordPress-Website. Die Beispiele auf dieser Seite sollen ein wenig zum besseren Verständnis und zur leichteren Unterscheidung beitragen.

Beispiel 1: Angenommen Sie haben einen Blog unter der Domain “www.example.com” eingerichtet und im Dashboard unter “Einstellungen -> Allgemein” bei den Punkten “WordPress Adresse (URL) ” und “Seiten-Adresse (URL) ” ebenfalls nur www.example.com angegeben, so werden beide Funktionen das gleiche (nicht dasselbe) Ergebnis liefern.

Ein kleines Plugin für einen kleinen Test:

<?php
/*--------------------------------------------------------------------------------------------
 Plugin Name: Testausgabe home_url und site_url
 Plugin URI:  http://www.coder-welten.com/wp-funktionen-home_url-und-site_url/
 Description: Ein einfaches Plugin fuer kleine Testausgaben, Einbindung mit Short-Tag [testausgabe_home_site]
 Author:      Horst Müller
 Version:     1.00
 Author URI:  http://www.coder-welten.com
----------------------------------------------------------------------------------------------
*/
function kleine_testausgabe_home_site() {

    $test  = "<ul>\n";
    $test .= "<li>get_bloginfo(\"url\"): "  .get_bloginfo("url")  ."</li>\n";
    $test .= "<li>get_bloginfo(\"wpurl\"): ".get_bloginfo("wpurl")."</li>\n";
    $test .= "<li>home_url(): "             .home_url()           ."</li>\n";
    $test .= "<li>site_url(): "             .site_url()           ."</li>\n";
    $test .= "</ul>\n";

    return $test;
}
add_shortcode("testausgabe_home_site", "kleine_testausgabe_home_site");
?>

Ausgabe 1:

get_bloginfo("url"):   http://www.example.com
get_bloginfo("wpurl"): http://www.example.com
home_url():            http://www.example.com
site_url():            http://www.example.com

Eine andere Ausgabe würden Sie erhalten, wenn Sie den Blog nicht im Root sondern in einem Unterverzeichnis installieren würden, den Blog jedoch so einrichten, dass dieser unter der Domain erreichbar ist, ohne dieses Unterverzeichnis bei einem Aufruf mit anzuzeigen. Dazu müsste lediglich die index.php vom Unterverzeichnis ins Root-Verzeichnis (oberste Ebene Ihres Webspaces) verschoben werden, gegebenenfalls auch noch die zugehörige htaccess-Datei und die Einstellungen im Dashboard entsprechend angepasst werden (siehe Bild).

Einstellungen im Dashboard

Einstellungen im Dashboard für die Webadresse bzw. Erreichbarkeit unter Domain ohne Anzeige des Unterverzeichnisses.

Bei einer derartigen Installation, bei die Startseite des Blogs nur unter der jeweiligen Domain erreichbar ist, der Blog jedoch in einem Unterverzeichnis liegt, würde sich die Ausgabe des kleinen Plugins wie folgt ändern und die WP-Funktion home_url() würde nicht mehr das gleiche Ergebnis wie die WP-Funktion site_url() liefern. Der Unterschied zwischen den Funktionen würde ersichtlich  werden (siehe Ausgabe 2).

Ausgabe 2:

get_bloginfo("url"):   http://www.example.com
get_bloginfo("wpurl"): http://www.example.com/wordpress
home_url():            http://www.example.com
site_url():            http://www.example.com/wordpress

Praktische Beispiele

Nachfolgend einige praktische Beispiele zur Verwendung von home_url() und site_url(), wobei die Beispiele sich auf eine Installation beziehen, bei der WordPress unter
www.example.com/wordpress/ eingerichtet wurde, jedoch unter der Domain
www.example.com erreichbar ist.

WordPress Adresse: www.example.com/wordpress/
Seiten-Adresse: www.example.com

Beispiel I

Als erstes nur eine Testausgabe, um festzustellen, was im Quelltext nach dem Parsen als Wert im action-Attribut enthalten ist. Das jeweilige Ergebnis ist den Kommentaren entnehmbar.

Code-Listing Beispiel 1: Ausgabe action-Attribut:

<?php
/**
 Plugin Name: Testausgabe action
 Description: Einbindung mit Short-Tag [testausgabe_action]
 Version:     Beta 0.01
*/
function kleine_test_action() {

    $form  = "action=\"".esc_url($_SERVER["PHP_SELF"])."\"\n";
    /**
      Ausgabe im Quelltext:
      action="/index.php"
      Kann so zumindest wohl kaum funktionieren
    */

    $form .= "action=\"".esc_url(site_url("/testseite/"))."\"\n";
    /**
      Ausgabe im Quelltext:
      action="http://www.example.com/wordpress/testseite/"
      Bei Versand wird ein 404 HTTP-Statuscode und die Fehlerseite ausgelöst.
    */

    $form .= "action=\"/testseite/\"\n";
    /**
      Ausgabe im Quelltext:
      action="/testseite/"
      Funktioniert, doch war nicht Zielsetzung des Tests
    */

    $form .= "action=\"".esc_url(home_url("/testseite/"))."\"\n";
    /**
      Ausgabe im Quelltext:
      action="http://www.example.com/testseite/"
    */

    $form .= "action=\"".esc_url($_SERVER["REQUEST_URI"])."\"\n";
    /**
      Ausgabe im Quelltext:
      action="/testseite/"
      Wäre ebenfalls eine Alternative, in Verbindung mit oder ohne $_SERVER["HTTP_HOST"]
    */
    return $form;
}
add_shortcode("testausgabe_action", "kleine_test_action");

?>

Beispiel II

Im zweiten Beispiel befindet sich ein Formular auf der Seite /wp-funktionen-home_url-und-site_url/. Dieses soll nach erfolgter Auswahl einen Integer-Wert per Post an die eigene Seite senden. Im Normalfall könnte ein Programmierer diese Aufgabe mit PHP_SELF erledigen oder er fügt nur den Namen der entsprechenden Seite als Wert im Attribut Action ein. Doch wie die erste Testausgabe ergab, so würde PHP_SELF zumindest Probleme bereiten. Von den WP-Funktionen eignet sich jedoch die Funktion home_url für diese Aufgabenstellung.

Die Funktion site_url würde hingegen nur einen 404 Not Found und die Fehlerseite auslösen.

Code-Listing Beispiel 2: Formular und Versand

<?php
/*--------------------------------------------------------------------------------------------
 Plugin Name: Testausgabe Formular
 Plugin URI:  http://www.coder-welten.com/wp-funktionen-home_url-und-site_url/
 Description: Ein einfaches Plugin fuer kleine Testausgaben, Einbindung mit Short-Tag [testausgabe_formular]
 Author:      Horst Müller
 Version:     Beta 0.02
 Author URI:  http://www.coder-welten.com
----------------------------------------------------------------------------------------------
*/
function kleine_testausgabe_formular() {

    $form = "<form action=\"".esc_url(home_url("/wp-funktionen-home_url-und-site_url/"))."\" method=\"post\">\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"20\" /> 20\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"40\" /> 40\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"60\" /> 60\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"80\" /> 80\n".
            "\t<input type=\"submit\" value=\" Testen \" />\n".
            "</form>\n";

    $ausgabe = 0;

    if (isset($_POST["ergebniss"]) and !empty($_POST["ergebniss"])) {

        $ergebniss = preg_replace("/[^0-9]/", "", $_POST["ergebniss"]);

        switch ($ergebniss) {
            case "20":
                $ausgabe = "ist 20";
                break;
            case "40":
                $ausgabe = "ist 40";
                break;
            case "60":
                $ausgabe = "ist 60";
                break;
            case "80":
                $ausgabe = "ist 80";
                break;
        }
    } else {
        $ausgabe = "Bisher traf keine verwertbare Post ein!";
    }
    return $form.$ausgabe;
}
add_shortcode("testausgabe_formular", "kleine_testausgabe_formular");

?>

Beispiel III

Anders wie beim zweiten Beispiel würde die Angelegenheit aussehen, wenn die Post an eine Datei gesendet werden soll, die im Verzeichnis wordpress/ (oder in einem anderen Verzeichnis) angelegt wurde und somit existiert. In diesem Fall sollten die in der htaccess notierten Bedingungen nicht mehr zutreffen und die existierende Datei aufgerufen werden.

# Erfülle Regel nur dann, wenn Datei oder Verzeichnis nicht existiert.

RewriteCond %{REQUEST_FILENAME} !-f  
RewriteCond %{REQUEST_FILENAME} !-d

Für einen kleinen Test wurde eine erreichbare Datei (posteingang.php) im Verzeichnis von WordPress abgelegt und als Plugin nur ein Formular verwendet, welches an diese neu angelegte Seite adressiert wurde. In diesem Fall ist die Funktion site_url() das Mittel der Wahl.

Code-Listing Beispiel 3: (bestehend aus 2 Dateien)

<?php
/*--------------------------------------------------------------------------------------------
 Plugin Name: Postversand
 Plugin URI:  http://www.coder-welten.com/wp-funktionen-home_url-und-site_url/
 Description: Ein einfaches Plugin fuer kleine Testausgaben, Einbindung mit Short-Tag [postversand]
 Author:      Horst Müller
 Version:     Beta 0.03
 Author URI:  http://www.coder-welten.com
----------------------------------------------------------------------------------------------
*/
function kleiner_postversand() {

    $form = "<form action=\"".esc_url(site_url("/posteingang.php"))."\" method=\"post\">\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"20\" /> 20\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"40\" /> 40\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"60\" /> 60\n".
            "\t<input type=\"radio\" name=\"ergebniss\" value=\"80\" /> 80\n".
            "\t<input type=\"submit\" value=\" Testen \" />\n".
            "</form>\n";

    return $form;
}
add_shortcode("postversand", "kleiner_postversand");
?>

Die Datei posteingang.php wurde für den Test ablegt unter /wordpress/posteingang.php. Auf eine Absicherung der Ausgabe mit htmlspecialchars wurde bei diesen Tests verzichtet. In allen Fällen, bei denen es sich nicht nur um kleinere Tests handelt, sollte jedoch grundsätzlich eine Absicherung der Ausgabe erfolgen.
Für die Absicherung eignen sich neben den PHP-Funktionen htmlspecialchars und htmlentities ebenfalls WP-Funktionen, wie die Funktion esc_html() oder esc_attr().

Die Datei posteingang.php wurde abgelegt unter /wordpress/posteingang.php

<!DOCTYPE html>
<html>
<head>
<title>Posteingang</title>
</head>

<body>
<?php
$ausgabe = 66;

if (isset($_POST["ergebniss"]) and !empty($_POST["ergebniss"])) {

    $ergebniss = preg_replace("/[^0-9]/", "", $_POST["ergebniss"]);

    switch ($ergebniss) {
        case "20":
            $ausgabe = "ist 20";
            break;
        case "40":
            $ausgabe = "ist 40";
            break;
        case "60":
            $ausgabe = "ist 60";
            break;
        case "80":
            $ausgabe = "ist 80";
            break;
    }
} else {
    $ausgabe = "Bisher traf keine verwertbare Post ein!";
}
echo $ausgabe;
?>
</body>
</html>

Beispiel 4

Beim letzten Beispiel (Beispiel 3) handelte es sich nur um einen Test, doch neue Dateien werden wohl die wenigsten im Stammverzeichnis von WordPress anlegen. Häufiger kommt es hingegen vor, dass neue Dateien zusammen mit einem Plugin angelegt werden. Für einen weiteren Test wurden aus diesem Grund drei kleine CSS-Dateien unter /wordpress/wp-content/plugins/ abgelegt, zusammen mit einem kleinen Plugin, welches diese beiden CSS-Dateien zum HTML-Header hinzufügen sollte. Der Inhalt dieser beiden CSS-Testdateien ist bedeutungslos und sollte nur der Unterscheidung dienen.

Beispiel 4 (bestehend aus vier einzelnen Dateien, so insgesamt 3 x teststyle-01-bis-03.css):

/* teststyle-01.css abgelegt unter /wordpress/wp-content/plugins/teststyle-01.css */

.testclass01 {margin:0px}
/* teststyle-02.css abgelegt unter /wordpress/wp-content/plugins/teststyle-02.css */

.testclass02 {padding:0px}

Für diese Aufgabenstellung erwies sich die Funktion site_url ebenfalls als geeignet, besser jedoch die Funktion plugins_url, die Funktion home_url hingegen als ungeeignet (siehe Kommentare im Beispiel).

<?php
/*--------------------------------------------------------------------------------------------
 Plugin Name: Test-Einbindungen
 Plugin URI:  http://www.coder-welten.com/wp-funktionen-home_url-und-site_url/
 Description: Ein einfaches Plugin fuer Testeinbindungen
 Author:      Horst Müller
 Version:     Beta 0.01
 Author URI:  http://www.coder-welten.com
----------------------------------------------------------------------------------------------
*/
function einbinden_von_css_dateien() {

    echo "<link rel=\"stylesheet\" type=\"text/css\" ".
    "href=\"".esc_url(home_url("/wp-content/plugins/teststyle-01.css"))."\" />\n";
    /**
      Ausgabe im Quelltext:
      ... www.example.com/wp-content/plugins/teststyle-01.css ...
      Fehler, da nicht erreichbar
    */

    echo "<link rel=\"stylesheet\" type=\"text/css\" ".
    "href=\"".esc_url(site_url("/wp-content/plugins/teststyle-02.css"))."\" />\n";
    /**
      Ausgabe im Quelltext:
      ... www.example.com/wordpress/wp-content/plugins/teststyle-02.css ...
      Würde funktionieren, da die teststyle-02.css erreichbar ist
    */

    echo "<link rel=\"stylesheet\" type=\"text/css\" ".
    "href=\"".esc_url(plugins_url("teststyle-03.css", __FILE__))."\" />\n";
    /**
      Ausgabe im Quelltext:
      ... www.example.com/wordpress/wp-content/plugins/teststyle-03.css ...
      Um Dateien zu laden ist diese Funktion besser geeignet!
    */
}
add_action("wp_head", "einbinden_von_css_dateien");

?>

Die vorausgehenden Beispiele auf dieser Seite sollten helfen, den Unterschied zwischen den beiden Funktionen hervorzuheben. Welche von den beiden WP-Funktionen sich für einen spezielle Aufgabenstellung eignet und welche nicht, hängt hingegen von der Aufgabenstellung ab.

Verwendbare Parameter

Als zusätzliche Parameter können der Pfad ($path) als auch das zu verwendende Protokoll ($scheme) angegeben werden. Der Pfad besteht im einfachsten Fall aus einem / Slash für das Root-Verzeichnis. Falls Parameter verwendet werden, so müsse die Werte für beide Parametern als String übergeben werden. Bei den Rückgabewerten beider Funktionen handelt es sich ebenfalls um Strings, die mit echo ausgegeben werden können.

$path (string) (optional)
$scheme (string) (optional)

Standardwert ($path): None
Standardwert ($scheme): null

Mögliche Protokoll-Werte

home_url ($scheme): http und https
site_url ($scheme): http, https, login, login_post und admin

(Wobei die letzten Angaben mit „login, login_post und admin“ nur der Function Reference/site_url von WordPress entnommen wurden und lediglich die folgenden Ausgaben getestet wurden.)

Rückgabewerte

home_url – “Adresse der Seite im Web” (Strings)
site_url – “WordPress-Adresse” (Strings)

Beispiel für die Verwendung von Parametern:

<?php
/**
 Plugin Name: Testausgabe Parameter
 Description: Einbindung mit Short-Tag [testausgabe_mit_parameter]
*/
function kleiner_parameter_test() {

    $param  = home_url()."\n";
    $param .= home_url("/")."\n";
    $param .= home_url("/testseite/", "https")."\n\n";

    $param .= site_url()."\n";
    $param .= site_url("/")."\n";
    $param .= site_url("testseite/", "https")."\n";

    return $param;
}
add_shortcode("testausgabe_mit_parameter", "kleiner_parameter_test");

/**
  Ausgabe im Quelltext:

  http://www.example.com
  http://www.example.com/
  https://www.example.com/testseite/

  http://www.example.com/wordpress
  http://www.example.com/wordpress/
  https://www.example.com/wordpress/testseite/
*/
?>

Beide Funktionen sind in der Datei wp-includes/link-template.php definiert.

Eine Zusammenfassung in Stichpunkten

Eine kurze Zusammenfassung in Stichpunkten und weitere Hinweise.

Eine Datei wie testausgaben-fuer-formulare.php existiert nicht, es wurde nur ein Beitrag mit dem Titel ‘Testausgaben für Formulare’ und dem Slug ‘testausgaben-fuer-formulare’ gespeichert und als Einstellung für Permalinks wurde Beitragsname gewählt:

<?php
$form = "<form action=\"".esc_url(home_url("/testausgaben-fur-formulare/"))."\" method=\"post\">\n".
        //... input Elemente
        "</form>\n";
?>

Eine Datei wie posteingang.php existiert zum Beispiel in einem Verzeichnis /extern:

<?php
$form = "<form action=\"".esc_url(site_url("/extern/posteingang.php"))."\" method=\"post\">\n".
        //... input Elemente
        "</form>\n";
?>

Für das Laden von Dateien aus dem Plugin-Verzeichnis sind andere WP-Funktionen, wie zum Beispiel plugins_url, besser geeignet:

<?php
$bild = "<img src=\"".esc_url(plugins_url("/images/bild.jpg", __FILE__))."\" alt=\"Ein Bild\">";

/** 
 Ausgabe im Quelltext:

 <img src="http://www.example.com/wordpress/wp-content/plugins/images/bild.jpg" alt="Ein Bild">
*/
?>

Weitere Hinweise

Eine alternative Verwendung von einfachen Anführungszeichen erleichtert gegebenenfalls die Arbeit und verbessert die Lesbarkeit vom Code. Die Möglichkeiten zur Formatierung und Ausrichtung des Quelltextes verringern sich hingegen bei der Benutzung von einfachen Anführungszeichen, wodurch die Lesebarkeit des fertig gerenderten HTML-Quelltextes abnimmt.

Das nachfolgende Beispiel gilt für alle Listings auf dieser Seite:

<?php
$bild = '<img src="'.esc_url(plugins_url('images/bild.jpg', __FILE__)).'" alt="Ein Bild">';
?>

Hinweise zur Sicherheit

In den Beispielen wurde die Ausgabe der URL durchgehend mit esc_url() abgesichert, was überflüssig erscheinen mag, solange die URL der Seite direkt eingetragen wird. Doch besser ist es sich an diese Schreibweise zu gewöhnen, als eine Mindestabsicherung einmal zu vergessen, wenn die URL der Seite als Wert einer Variablen übergeben wird. Wurde dieser Wert dann von einem schlecht gesicherten Formular übermittelt oder aus einer bereits durch SQL-Injection kompromittierten Datenbank abgerufen, könnte der Schaden beträchtlich sein.

<?php
/*--------------------------------------------------------------------------------------------
 Plugin Name: Testausgabe URL
 Description: Ein einfaches Plugin fuer Testeinbindungen mit Shortcode [testausgabe_url]
 ---------------------------------------------------------------------------------------------
*/
function testausgabe_url_mit_esc() {

    /* -- $url von einem ungesicherten Formular oder von einer kompromittierten Datenbank --*/

    $url = "seite.html?para=<script>alert('XSS')</script>";

    $form  = "action=\"".home_url($url)."\"\n";
    $form .= "action=\"".esc_url(home_url($url))."\"\n";

    return $form;
}
add_shortcode("testausgabe_url", "testausgabe_url_mit_esc");

/**
 Ausgabe im Quelltext:

 action="http://www.example.com/seite.html?para=<script>alert('XSS')</script>"
 action="http://www.example.com/seite.html?para=scriptalert(&#039;XSS&#039;)/script"
*/
?>

Dieses Beispiel ist nur als kleiner Fingerzeig gedacht, den Punkt Sicherheit bei der Programmierung eigener Plugins möglichst nicht zu vernachlässigen.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *