htaccess und mod_rewrite ("url mapping")

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • htaccess und mod_rewrite ("url mapping")

    Hey. Ich dachte da das ganze ja keine Programmiersprache ist, sondern eine Konfigurationsdatei, passt das ganze eher hier rein.

    Habe gerade Dynambee Beitrag zum URL Mapping gelesen. Da ich nie wusste wie das funktioniert, konnte ich es also auch nicht anwenden. Habe mich jetzt durchgegoogelt, bis ich etwas gefunden habe, was das ganze recht gut erklärt.
    Verstanden habe ich es. Der Link wird Suchmaschienen optimiert angezeigt, intern aber umgewandelt.


    Also meine Links sehen einerseits so aus.
    webseite.de/index.php?action=forum
    oder auch so
    webseite.de/index.php?action=forum&id=67

    Nun meine .htaccess Datei sieht jetzt so aus

    Quellcode

    1. Options +FollowSymLinks
    2. RewriteEngine on
    3. RewriteBase /path/
    4. RewriteRule ^([0-9a-zA-Z_]+)$ index.php?action=$1


    Mit dem Link: http://webseite.de/index.php?action=forum ist durch die .htaccess Datei jetzt ja dies möglich: http://webseite.de/forum

    Da ich aber jetzt nicht soo die Ahnung habe, bekomme ich die "RewriteRule" nicht dynamisch erweitert, dass ich den zweiten Link auch benutzen kann. Sprich mit id am ende webseite.de/index.php?action=forum&id=67

    Ändere ich das per hand in :

    Quellcode

    1. ^([0-9a-zA-Z_]+)$ index.php?action=$1&id=67

    Funktioniert das ganze logischerweise.


    Aber wie bekomme ich es hin, dass ich die Seiten so aufrufen kann:

    webseite.de/forum/67

    oder
    webseite.de/index.php?action=xy&id1=5&id2=4&id3=6
    in
    webseite.de/xy/5/4/6
    umgewandelt wird.

    Wenn das ganze überhaupt machbar ist!
    Bin für jede Hilfestellung dankbar. :)
  • Hey danke schonmal. :) Hab das ganze jetzt zwar so versucht: (jetzt mit meiem wert in der url)

    Quellcode

    1. RewriteRule ^([0-9a-zA-Z_]+)\/([0-9a-zA-Z_]+)$ index.php?action=$1&id=$2


    Jedoch wird das komplette Design der Seite so gar nicht geladen. Es steht nur Text da. Die CSS Datei wird also Ignoriert.
    Versteh ich nicht so wirklich. Ich warte einfach mal bis du wieder kommst, und ein wenig mehr mit dazu erzählen kannst :P

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Snowflake ()

  • Bei mir sieht die Eingangsregel zum Dispatcher so aus:

    Quellcode

    1. RewriteEngine On
    2. RewriteCond %{REQUEST_FILENAME} -s [OR]
    3. RewriteCond %{REQUEST_FILENAME} -l [OR]
    4. RewriteCond %{REQUEST_FILENAME} -d
    5. RewriteRule ^.*$ - [NC,L]
    6. RewriteRule ^.*$ /index.php [NC,L]


    Der Dispatcher (bei mir "Router") zerpflückt dann die URI und leitet die Anfrage entsprechend weiter. Die Regel prüft im Prinzip nur, ob die Datei physisch wirklich existiert (dann die Datei, z.B. ein Bild, anzeigen) oder ob sie nicht exisitiert, wodurch die Anfrage an die index.php weitergeleitet wird. Bei mir sehen URI's immer so aus:

    seite.de/modul/aktion/var/wert/var2/wert2
  • Snowflake schrieb:

    Jedoch wird das komplette Design der Seite so gar nicht geladen. Es steht nur Text da. Die CSS Datei wird also Ignoriert.
    Versteh ich nicht so wirklich. Ich warte einfach mal bis du wieder kommst, und ein wenig mehr mit dazu erzählen kannst :P


    Gib die Pfade zu den CSS-Dateien und den Bildern mal voll an:

    /pfad/ur/css/datei.css und nicht ./pfad/datei.css

    Da du nun mit "virtuellen Unterordnern" arbeitest, sucht der Server nun in den falschen Verzeichnissen nach Deinen Dateien. Die absoluten Pfade korrigieren das.
  • Hey auch schonmal danke. Also das mit dem CSS Problem hat sich erledigt. Das ist wenn man so schlampig arbeitet und nur den dateiname angibt.. Also das mit dem kompletten Path war die lösung.

    Der Aufbau wie du arbeitest gefällt mir auch. Mit diesem Dispatcher habe ich mich noch nie auseinander gesetzt. Kannte das wort vorher auch gar nicht um ehrlich zu sein.
    Leider finde ich per google keine weiteren Informationen über den Dispatcher ("Router"), Also das ganze ist doch eine PHP Klasse oder sehe ich das falsch?






    Da ich ja auch lernen möchte und nicht nur eine Lösung...Also wenn du dynambee lust hast mir deine Methode zu erklären wäre auch super.
    Also ich hab die RewriteRule jetzt soweit, dass sie funktioniert.

    Quellcode

    1. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z]+)$ index.php?action=$1&id=$2


    Jedoch bräuchte ich jetzt noch eine kleine Hilfestellung wie ich alle möglichen Szenarien mit RewriteRule abdenken kann.

    Einfach die ganzen RewruteRule untereinander setzen..

    Quellcode

    1. RewriteRule ^([0-9a-zA-Z_]+)$ index.php?action=$1
    2. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z]+)$ index.php?action=$1&id=$2
    3. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z]+)/([0-9a-zA-Z]+)$ index.php?action=$1&id=$2&tid=$3

    und alle anderen möglichen URL Kombinationen die mein Script benötigt..?
    • Wenn Du alle Regeln untereinander schreibst, musst Du bedenken, dass die erste Regel, auf die die aktuelle URI zutrifft, auch genommen wird. mod_rewrite versucht nicht, die "passendste" Regel zu finden, first hit and out.
    • Der Router zerteilt im Prinzip nur Die übergebene URI in ihre Bestandteile, prüft auf fehlende Elemente usw. und leitet die Daten dann an den zuständigen Controller weiter. Bist Du mit dem Grundkonzept von MVC vertraut?

    Ein Codebeispiel zum Router (quasi eine Minimalversion als proof-of-concept):

    Quellcode

    1. # class Router usw.
    2. # Anstelle von "/" kannst Du natürlich auch andere Zeichen als Trennzeichen verwenden, aber
    3. # "/" hat sich als guter Standard etabliert, da es der Ordnerstruktur im Denken der User entspricht.
    4. $requestURI = explode('/', $_SERVER['REQUEST_URI']);
    5. $scriptName = explode('/', $_SERVER['SCRIPT_NAME']);
    6. $size = sizeof($scriptName);
    7. for($i= 0; $i < $size; $i++)
    8. {
    9. if($requestURI[$i] == $scriptName[$i] OR ($requestURI[$i] == "" OR $scriptName[$i] == ""))
    10. {
    11. unset($requestURI[$i]);
    12. }
    13. }
    14. $routeData = array_values($requestURI);
    15. var_dump($routeData);
    Alles anzeigen
  • Hey philippgerard. Achso okay. Das habe ich mir schon fast gedacht, dass die erste Regel standartmäßig benutzt wird mod_rewrite sich nicht die passende Regel raussucht.
    Also meinte dynambee eigentlich das gleiche was du mir gerade versuchst zu erklären wenn ich das richtig verstehe.



    Also mit dem Grundkonzept von MVC leider nicht. Habe mich gerade mal versuch ein wenig darin einzulesen. Ich hoffe mal, dass es nicht all zu schwer wird.
    Dann sollte ich vllt mal ein bisschen rumspielen und versuchen ob ich meine Seitenaufrufe so hinbekomme mit dem ganzen neuen Sachen von denen ich noch nicht so den Peil habe :P

    Aber schonmal danke für dein Codebeispiel. Das versteh ich schonmal aufjedenfall.

    Zum großen Teil werde ich dann mit dem controller von MVC arbeiten, oder?
  • Richtig, philippgerard versucht dir das gleiche klar zumachen, was ich in sehr knapper Weise versucht habe. MVC ist kein Zuckerschlecken. Bis man die richtige Anwendung raus hat, dauert es doch ein wenig länger. Einfach mal bei ausgewachsenen MVC-Frameworks spicken :P

    MVC existiert eigentlich nur aus der Gesamtheit von Model, View, Controller. Die Rollenverteilung sollte also verteilt sein ;)
    MfG dynambee
  • sers! ich möchte dir mal ein beispiel geben wie das bei mir ausschaut (bin zwar auch erst neu in mod_rewrite)

    ich habe zwei gets einmal für die kategorie (a) und einmal für den inhalt (b)
    also meine url z.B.
    http://localhost/M4rc3L-XCN/News/Test oder http://localhost/M4rc3L-XCN/News/Test/ oder http://localhost/M4rc3L-XCN/Produkte/XCN-TS_Control
    wird intern zu:
    http://localhost/M4rc3L-XCN/index.php?a=News&b=Test

    dann habe ich noch eine extra funktion wenn jemand was falsches eingibt
    z.B. http://localhost/M4rc3L-XCN/News/Test/abc/gg
    dann leitet er auf die index.php zurück


    Hier der Code dazu:

    Quellcode

    1. RewriteEngine on
    2. #rewrite auf get a und b
    3. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z_-]+)/$ index.php?a=$1&b=$2
    4. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z_-]+)$ index.php?a=$1&b=$2
    5. # rewrite auf index get a
    6. RewriteRule ^([0-9a-zA-Z_]+)$ index.php?a=$1
    7. RewriteRule ^([0-9a-zA-Z_]+)/$ index.php?a=$1
    8. # umleiten auf startseite wenn andere ordner gewählt
    9. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z_-]+)/(.*)$ index.php


    mfg
    Beste Grüße,
    M4rc3L-XCN
  • Hey danke schonmal für die viele Gedult :) Also wenn ihr jetzt noch lust und nerven habt mir vllt bisschen zu helfen. Also ich hab da ein beispiel gefunden. Ich find mit beispielen versteht man das ganze oft ein wenig leichter, jedenfalls am anfang.
    URL Dispatcher

    So ich kopiere die dateien in mein Root verzeichnis und halte mich an die Verzeichnis-Struktur wie auf der Seite angezeigt

    Dann startet man den Dispatcher:

    Quellcode

    1. <?php
    2. /**
    3. * The url dispatcher invokes the controller that is configured for the given
    4. * URL in application.ini.
    5. */
    6. require_once('../core/core.php');
    7. $dispatcher = &new Dispatcher();
    8. $dispatcher->dispatch($_SERVER['REQUEST_URI']);
    9. ?>


    Da ich erstmal mit der Beispiel-konfiguration arbeite, lasse ich die Application.ini so wie sie ist:

    Quellcode

    1. ; Application configuration. Matches URL patterns paired with parameter types
    2. ; to a Controller.
    3. [demo/*]
    4. controller = Demo
    5. parameters = int year, int month, mixed title
    6. [/]
    7. controller = Frontpage
    8. [*]
    9. controller = Demo
    Alles anzeigen


    Der URL aufruf wäre ja dann z.b.
    localhost/demo/2009

    Die rückgabe ist aber eine leere Seite.
    Dann habe ich mir mal die funktionen vom Dispatcher angeschaut:
    Dispatcher Class

    Die funktionen sind mir soweit eigentlich klar, denke ich jedenfalls. Die aufgerufene funktion dispatch() startet eine Foreach schleife, wenn die URL nicht das Root verzeichnis ist.

    Quellcode

    1. foreach ($this->applications as $application => $config) {


    Lasse ich mir jetzt $this->applications einzeln ausgeben, bekomme ich auch nichts ausgegeben, also ist $this->applications wohl leer und somit hat die forschleife auch nichts zu tun.
    Also findet der aufruf der von $this-invoke() gar nicht statt.


    Könntet ihr so pauschal sagen ohne die Klasse zu kennen, ob ich ein fehler mache beim arbeiten damit?
  • M4rc3L-XCN schrieb:

    sers! ich möchte dir mal ein beispiel geben wie das bei mir ausschaut (bin zwar auch erst neu in mod_rewrite)

    Hier der Code dazu:

    Quellcode

    1. RewriteEngine on
    2. #rewrite auf get a und b
    3. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z_-]+)/$ index.php?a=$1&b=$2
    4. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z_-]+)$ index.php?a=$1&b=$2
    5. # rewrite auf index get a
    6. RewriteRule ^([0-9a-zA-Z_]+)$ index.php?a=$1
    7. RewriteRule ^([0-9a-zA-Z_]+)/$ index.php?a=$1
    8. # umleiten auf startseite wenn andere ordner gewählt
    9. RewriteRule ^([0-9a-zA-Z_]+)/([0-9a-zA-Z_-]+)/(.*)$ index.php


    mfg



    Hey danke auch an dir. Ich mache mal zwei beiträge der übersichtlichkeit halber.
    Dein Code verstehe ich jetzt nicht so ganz, dass er funktioniert.

    Denn philippgerard sagt doch eben noch
    mod_rewrite versucht nicht, die "passendste" Regel zu finden, first hit and out.

    Und du definierst mehrere RewriteRules.
  • das kommt immer darauf an wie du es anordnest...

    also erste regeln mit pfad "/news/test/" nein?
    => "/news/test" nein?
    => "/news/" nein?
    => "/news" ....
    die letzte regel trifft ja nur zu wenn mehr als zwei angaben sind also z.B. "/news/test/1234jk"

    daher fragt er zuerst wenn zwei angaben sind, falls nicht dann prüfe ob ein eintrag ist
    und die letzte dient nur dazu wenn es mehr als zwei sind dass er nicht gleich einen 404error ausgibt
    Beste Grüße,
    M4rc3L-XCN
  • Wenn nur eine Regel angewendet werden soll, solltest du noch ein [L] hinter jeder Regel einfügen.
    Siehe manual: httpd.apache.org/docs/2.0/mod/mod_rewrite.html

    'last|L' (last rule)
    Stop the rewriting process here and don't apply any more rewrite rules. This corresponds to the Perl last command or the break command in C. Use this flag to prevent the currently rewritten URL from being rewritten further by following rules. For example, use it to rewrite the root-path URL ('/') to a real one, e.g., '/e/www/'.
  • Hey. Sorry konnte jetzt erst wieder weiter arbeiten. Habe das ganze nun erfolgreich getestet dank d0nut und M4rc3L-XCN. Also die Variante funktioniert einwandfrei.

    Rein interessehalber würde ich das problem mit dem Url Dispatcher der auf MVC aufbaut lösen.
    Also wenn jemanden noch etwas einfallen sollte, wieso das ganze nicht arbeitet, ich bin dankbar wenn er mir helfen kann.

    Ich bin das ganze Script nocheinmal durchgegangen und konnte kein Fehler finden. Zumal ich ja erstmal nur die reine Demo testen wollte.