[Erledigt] mod_rewrite richtig anwenden (dynamisch)

Hallo ihr Lieben,

ich habe da einmal eine Frage. Auf modrewrite.de habe ich mir ein Beispiel angesehen und nachgemacht, welches auch gut funktioniert.

RewriteEngine on RewriteRule ^([a-z0-9]+)$ index.php?page=$1
So sieht das aus. Meine URL hat immer den Aufbau http://localhost/?page=home
Nun kann ich problemlos http://localhost/home aufrufen und er zeigt mir schön die Startseite an, genau so wie ich es haben will.
Meine Frage ist nun, muss ich nun ALLE Links auf meiner Seite extra anpassen? Zur Zeit verlinke ich z.B. bei einem Formular einfach mit ?page=. Muss ich da nun überall alle Dateien bearbeiten oder kann mod_rewrite das automatisch erkennen?

Ferner gibt es bei meiner URL ab und zu noch eine Erweiterung, wenn z.B. ein Eintrag bearbeitet wird. Dann sieht die URL wie folgt aus: http://localhost/?page=home&mode=&id=
Wie kriege ich das noch mit unter, da dies ja nicht immer vorhanden ist.

Danke im Voraus für Hilfe!

Es gibt die Möglichkeit die Links beim Aufruf weiterzuleiten, aber sinnvoller ist es, wenn du alle Adressen veränderst.

Oh weia, das sind aber sehr viele.

Und was mache ich genau, wenn ich mein System dann mal auf einen anderen Server packe der mod_rewrite nicht zulässt? Dann kann ich alles wieder rückgängig machen, gell?

Natürlich musst du.

mod_rewrite schreibt Requests um, die den Server erreichen.
Mit HTML und darin enthaltenen Links hat es nicht das geringste zu tun.

mod_rewrite verfügbar zu haben, ist bei heutigen Hosting-Paketen eigentlich Standard.

Nagut, Standard ist geil.

Weiß dann jemand, wie ich meinen Code anpassen muss, damit ich noch zwei optionale GET-Übergaben mit anhängen kann?
So läuft es bei mir im Moment

RewriteEngine on RewriteRule ^([a-z0-9]+)$ index.php?page=$1
Möchte nun, dass ich an die URL noch &mode=edit&id=2 anhängen kann, wobei sich edit auch ändert, mal zu add, mal zu delete etc.

Meine bisherigen Versuche sind leider gescheitert :smiley:

Danke euch erstmal!

Stichwort: Flag QSA

Hey,

ich versuche nun schon längere Zeit das zu erstellen, leider ohne Erfolg. Kann mir vllt. jemand behilflich sein, wie ich das schaffe, dass nicht immer alle $_GET-Übergaben pflicht sind?

DANKE

Die .htaccess könnte z.B. so aussehen:

RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([a-z0-9]+)$ index.php?page=$1 [NC,QSA,L]

Übrigens kannst du die URLs in deinem Code variable gestalten, sodass du per define die Verwendung von mod_rewrite festlegen kannst, z.B.: [code]define(‘USE_REWRITE’, true);
define(‘SITE_ROOT’, ‘/’);

function url($page, $variables=null) {
if (USE_REWRITE) {
return SITE_ROOT . ‘page . (empty($variables) ? ‘’ : (’?’.$variables));
} else {
return SITE_ROOT . ‘index.php?page=’. $page . (empty($variables) ? ‘’ : (’&’.$variables));
}
}[/code]

In Zeile 6 sollte es doch $page sein?

Die Variables sollte man als Array übergeben somit müssen diese im Nachhinein nicht immer geändert werden.
Das Protokoll HTTP 1.1 verlangt eine absolute URL zum Beispiel bei Location. Somit wäre nicht schlecht wenn die Funktion auch eine absolute Url ausgibt.

Hier wäre eine etwas erweiterte Lösung die automatisch feststellt ob mod_rewrite verfügbar ist:

[code]<?php
define (‘SITE_ROOT’, $_SERVER[‘SERVER_NAME’]);

$url = function($page, $vars=array(), $protocol = ‘http://’) {
$modules = apache_get_modules();

if ( in_array('mod_rewrite', $modules) ) {
    $url = SITE_ROOT . "/$page";
    if( is_array($vars) ) {
        foreach($vars as $var) {
            $url .= "/$var";
        }
    }
} else {
    $url = SITE_ROOT . "/index.php?page=$page";
    if( is_array($vars) ) {
        foreach($vars as $var => $value) {
            $url .= "&$var=$value";
        }
    }
}
return $protocol . $url;

};

// Ausgabe
echo $url(‘article’, array(‘show’=>‘123’, ‘sort’=>‘asc’));

?>[/code]
apache_get_modules() geht nur wenn PHP als Apache module läuft und anonyme Funktionen sind erst mit PHP5.3.0 verfügbar. Somit müssten alle anderen auf die etwas klassischere Variante zurückgreifen:

[code]<?php
define(‘MOD_REWRITE’, true);
define (‘SITE_ROOT’, $_SERVER[‘SERVER_NAME’]);

function url($page, $vars=array(), $protocol = ‘http://’) {
$modules = apache_get_modules();

if (MOD_REWRITE) {
    $url = SITE_ROOT . "/$page";
    if( is_array($vars) ) {
        foreach($vars as $var) {
            $url .= "/$var";
        }
    }
} else {
    $url = SITE_ROOT . "/index.php?page=$page";
    if( is_array($vars) ) {
        foreach($vars as $var => $value) {
            $url .= "&$var=$value";
        }
    }
}
return $protocol . $url;

}

// Ausgabe
echo url(‘article’, array(‘show’=>‘123’, ‘sort’=>‘asc’));

?>[/code]Wenn du jetzt deine htaccess noch anpasst:

Sollte alles wie gewünscht funktionieren.

Ja, das sollte SITE_ROOT . $page heißen.

Ich hatte bewusst auf apache_get_modules verzichtet, weil das z.B. bei CGI oder IIS nicht funktioniert und die absolute URL kann man in SITE_ROOT eintragen wenn man will. Das war einfach so kurz wie möglich.
Deine Schleife zum Zusammenbau der URL für mod_rewrite ist ebenfalls nicht ganz OK. Was machst du, wenn mal zufällig die Parameter in einer anderen Reihenfolge im Array stehen? Daher habe ich das nur als Querystring angehängt.

Hey,
danke euch, nun läuft es so wie ich es will! :wink:

@progandy
Ich wollte eigentlich nicht dich korrigieren :slight_smile:
Ich wollte dem TE einen erweiterten weg aufzeigen. Da die Frage im Raum war. "was machen wenn der Webspace wechselt und wie er mit den weiteren $_GET umgeht.

Stimmt an den CGI Weg hab ich garnicht mehr gedacht. Aber in der Regel laufen auf den Shared Webspace Apache Module.
Darauf sollte ich noch hinweisen.

Wie das Array ankommt ist ja egal da er sich ja nur den Wert raus nimmt. Wie die URL verarbeitet werden soll steht ja in seiner htaccess. Somit muss er sich vorher klar werden wie er mit dem ganzen umgehen will. Es hätte ja wenig Sinn wenn er extra über htaccess seine Links optimieren will und dann sowieso ins alte Muster zurück fällt.

[quote=“ausschliessi”]@progandy
Ich wollte eigentlich nicht dich korrigieren :slight_smile:[/quote] Das ist schon klar :wink:

Naja, schreibe einmal:
url(“test”, array(“id” => 1, “action” => “edit”);
Ergebnis: test/1/edit
url(“test”, array(“action” => “edit”, “id” => 1);
Ergebnis: test/edit/1
Das sollte aber beides mal die gleiche URL geben oder nicht?

[quote]Aber in der Regel laufen auf den Shared Webspace Apache Module.[/quote] bplaced verwendet CGI so weit ich weiß :wink:

Stimmt hier läufts als CGI… Ich hätts voher besser nachgeschaut…

Beim ersten Ergebnis wird ihm sein PHP Script in der Regel einen Fehler liefern da es den Wert nicht finden wird und darum habe ich die htacces auch klar über ([0-9]+)/(asc|desc) definiert.

Es muss nicht CGI sein, es gibt da viel mehr Methoden PHP einzubinden.

Hat eigentlich schon einer von euch an diese Methode gedacht?

index.php/Test

So braucht man gar kein mod_rewrite.
Funktioniert allerdings nur beim Apachen, nginx verwendet RegEx um den Request-String zu filtern und ~ .php passt einfach nicht auf so eine URL. Lighttpd und andere hab ich nicht probiert.

Ja, das habe ich auch schon mal gesehen, glaube bei so einem Wiki-System ist das so. Finde ich aber überhaupt nicht schön. Das ist total ungewohnt für mich :smiley:
Die Lösungen hier funktionieren ja auch, aber danke!