Benutzer-Werkzeuge

Webseiten-Werkzeuge


webdev:php:stuff:url-routing

URL Routing

Zur Zeit sind Frameworks in aller Munde. Was fast alle dieser Artgenossen mitbringen ist ein URL-Routing. Framworks, die nach dem MVC-Pattern ihren Dienst erledigen, werden die Controller über die URL angesprochen.

Beispiel

http://example.com/application/user/profile/

oder

http://example.com/application/index.php?q=/user/profile

Das Framework würde anhand dieser URL den Controller user aufrufen und die Methode profile ausführen, welches die View an den Benutzer ausliefert. Jedes Framework handhabt das etwas anders.

Eigenbau: Beispielfunktion

Eine einfache Funktion zum Parsen des GET-Parameter, in diesem Fall q (index.php?q=/test/123/456/feed.xml)

example.url-routing.php
function route($routes=array()){
 
        foreach($routes as $route){
            $replaceKeys = preg_replace("#@(\w+)#","(?P<$1>\w+)",$route);
            $replaceKeys = str_replace("/","\/",$replaceKeys);
            if(preg_match("#^".$replaceKeys."\/?$#","/".$_REQUEST["q"],$params)){
                return $params;
 
            }
        }
        return false;
}

q wird geprüft, ob es mit einem regulären Ausdruck, der Route übereinstimmt. Die Parameter bekommt man als Array zurück, entweder mit Index und, wenn angegeben, assoziativ. Die gewünschten Parameter starten bei Index 1, 0 enthält die gematchte Route. Wie man unten sehen kann, gibt es mehrere Möglichkeiten, die Werte zu erfassen:

  • regulärer Ausdruck zb (\w+),Zugriff über Index
  • regulärer Ausdruck mit benannter Capture-Gruppe (?P<item>\w+), Zugriff über Schlüssel (item)
  • benannter Subtreffer zb @item, Zugriff über Schlüssel (item)

Beide letzteren Möglichkeiten unterscheiden sich an der Feinjustierung, während man einen genauen regulären Ausdruck definieren kann, matcht letztes Beispiel alles innerhalb ([\w\s-_]+).

// Ein paar Routen
 
$routes[] = "/test/@item/@bugnr";
$routes[] = "/test/(?P<userid>.*)/@project/feed.xml";
$routes[] = "/test";
$routes[] = "/test/(?P<userid>.*)/@project/feed.(\w{3})";
 
// Gucken was rauskommt
print_r(route($routes));
GET:

http://example.com/~spielzeug/index.php?q=test/home/123

Matcht die erste Route "/test/@item/@bugnr":

Array
(
    [0] => /test/home/123
    [item] => home
    [1] => home
    [bugnr] => 123
    [2] => 123
)

GET:

http://example.com/~spielzeug/index.php?q=test/54321/wiki/feed.xml

Treffer bei der zweiten Route "/test/(?P<userid>.*)/@project/feed.xml":

Array
(
    [0] => /test/54321/wiki/feed.xml
    [userid] => 54321
    [1] => 54321
    [project] => wiki
    [2] => wiki
)

GET:

http://example.com/~spielzeug/index.php?q=test/

3. Route erzielt Treffer "/test"

Array
(
    [0] => /test
)

GET:

http://example.com/~spielzeug/index.php?q=test/54321/wiki/feed.xml

4. Route==Treffer

Array
(
    [0] => /test/54321/wiki/feed.xml
    [userid] => 54321
    [1] => 54321
    [project] => wiki
    [2] => wiki
    [3] => xml
)

Mittels mod_rewrite und dem Apache Server können die URLs auch freundlicher gestaltet werden. Die .htaccess würde wir folgt aussehen:

RewriteEngine On
RewriteBase /~spielzeug/

# wenn keine Datei oder Verzeichnis mit diesem Namen vorhanden ist, dann die Regel ausführen
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
 
RewriteRule (.*) index.php?q=$1 [L,QSA]

Die URLs würden demnach zb so beschriftet:

http://example.com/~spielzeug/test/54321/wiki/feed.xml
Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
webdev/php/stuff/url-routing.txt · Zuletzt geändert: 2016/08/07 15:08 von haiko

hello, world