URLs via mod_rewrite umschreiben (ähnlich wie bei Twitter)

  • Hallo,
    ich bin dabei ein neues Projekt zu programmieren und möchte nun von anfang an den htaccess/mod_rewrite kuddelmuddel fertigstellen, bevor ich überhaupt mit dem Rest in die Vollen gehe.


    Aktuell sieht mein Skript folgendes vor:
    Mittels dem URL Parameter "p" bestimme ich die aktuelle Seite.
    Beispiel: Mit "index.php?p=about" würde man auf der About Seite landen.


    Ich bin zwar kein mod_rewrite Pro aber ich bekomme es hin, dass ich diese Geschichte so umschreiben kann, dass man auch via "/about" auf die About Seite gelangen kann :)
    Allerdings denke ich nun einen Schritt weiter: Später wird es in diesem Projekt Userprofile geben. Wie zum Beispiel bei Twitter. Nun wäre es cool, wenn die User ihr Profil mittels "/username" ansteuern könnten.
    Beispiel: User "Max" will sein Profil ansurfen -> http://www.domain.com/max
    Die eigentliche URL wäre ja aber vermutlich dann diese: /index.php?p=profile&u=max


    Folgende Fragen stellen sich mir nun:
    1. Die About Seite (zum Beispiel) schließt es ja dann durch mein Vorhaben aus, dass es einen User mit dem Namen "about" gibt, richtig?
    2. Lässt sich das überhaupt so einrichten, dass Seiten und Profile gleich angeteuert werden (/seitenname bzw. /username) --- Twitter scheints ja auch so zu machen, nur kann ich mir nicht ganz erklären wie das geht.
    3. Wenn es sich so umsetzen lässt, wie würde das in diesem Fall funktionieren? Welche Rules muss ich schreiben?


    Bisher habe ich das mit den normalen Seiten so gemacht:

    Code
    1. RewriteEngine On
    2. RewriteRule ^([^.]+)$ /index.php?p=$1 [L]


    Würde mich sehr über Hilfe freuen. Bin bei diesem Thema echt davon abhängig, weil ich das echt nicht drauf hab :oops:

  • Ich würde keine weiteren mod-rewrite-Rules definieren, sondern einfach alles in $_GET['p'] schreiben, so wie du es schon hast.
    Die Parameter kannst du dann in PHP mit explode() passend zerlegen.
    In meinem selbstgeschriebenen kleinen MVC-Framework werden URLs i.d.R. z.B. so aufgebaut:


    http://www.meinedomain.de/controller/action/~/key1/value1/key2/value2 usw. mit beliebig vielen key-value-pairs.


    Mod_Rewrite schreibt mir alles nach der Domain in $_GET['request'], in diesem Fall wäre das der kursiv geschriebene Part. Controller und Action können weggelassen werden, es gibt einen Default-Controller und eine Default-Action welche von jedem Controller implementiert werden muss. Alles nach /~/ sind die Parameter die an die aufgerufene Action übergeben werden.


    In deinem Fall könntest du z.b. die URL so aufbauen: http://meinedomain.de/user/username


    Im Code verarbeitest du das dann z.B. so (vom Prinzip her):

    PHP
    1. $requestArr = explode("/",$_GET['p']);
    2. $view = array_shift($requestArr);
    3. switch(strtolower($view)) {
    4. case "user":
    5. $name = array_shift($requestArr);
    6. // User anzeigen
    7. break;
    8. // restliche cases + default
    9. }

    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook

  • Danke für die Info. Das klingt schonmal nicht schlecht. Das Einzige was mich stört ist, dass dann noch dieses doofe /user/ davor stehen muss. Allerdings kam mir bei deinem Vorschlag eine Idee, wie ich mein aktuelles Skript mit deiner Idee erweitern könnte. Ich habe ja meine Methode "getContent". In dieser Methode prüfe ich den "p" Parameter und gebe dementsprechend die Content-Dateien aus. Hier könnte ich es so machen, dass erst auf Username geprüft wird und wenn kein User gefunden wurde, dann prüfe ich auf Content-File. Wird auch kein Content-File gefunden, dann gibts halt ne 404 Meldung. Wenn ich jetzt keinen Denkfehler drin hab sollte das so klappen, dass ich Seiten und auch Profile mit *.de/seitenname bzw. *.de/username aufrufen kann. Korrigiert mich, fals ich hier falsch liege.

  • So kannst du das natürlich machen. Allerdings würde ich als erstes auf Content-File prüfen, und erst als zweites auf User. User-Profile sollten dir durch den Namen unter keinen Umständen deinen Content überschreiben können.

    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook

  • Ja das ist mir kurz danach auch eingefallen. Ich werde wohl auch noch eine Namensliste erstellen müssen, wo ich alle Seitennamen reserviere, damit diese nicht bei der Registration als Username verwendet werden können.


    Ich werde meine Methode vermutlich heute anpassen, dann poste ich dazu mal hier den Code. Das Thema interessiert bestimmt einige. Hab nämlich solche Art von Fragen in einigen Foren gefunden aber nie eine wirkliche Lösung dazu. Hab nur gelesen, dass Twitter das anscheinend irgendwie mit Ruby on Rails oder so macht.

  • Ja das ist mir kurz danach auch eingefallen. Ich werde wohl auch noch eine Namensliste erstellen müssen, wo ich alle Seitennamen reserviere, damit diese nicht bei der Registration als Username verwendet werden können.


    Das wäre wohl sinnvoll.
    Je nachdem um was für eine Seite es bei dir geht würde ich aber nochmal ganz genau überlegen ob es wirklich nötig ist die User-Profile über domain.de/username direkt aufrufen zu können, statt beispielsweise wie schon vorgeschlagen domain.de/user/username
    Es kann zum einen durchaus sein, dass deine Seite im Laufe der Zeit neuen Content mit neuen Seitennamen erhält, die du jetzt noch nicht absehen und daher auch nicht einplanen und abfangen kannst. Zum anderen finde ich persönlich die Variante mit /user/ zusätzlich in der URL sogar besser, weil viel aussagekräftiger. Je nachdem wie ein user sich nennt können URLs der Form domain.de/username sehr irreführend sein und Leute da völlig anderen Content als ein User-Profil erwarten. Und Besucher mögen in der Regel keine irreführenden URLs hinter denen sich etwas völlig anderes verbirgt als vermutet.

    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook

  • Da stimm ich dir soweit zu. Ich bin mir auch definitiv sicher, dass da noch einiges an Content kommen wird. Ich möchte die URLs deswegen gerne so machen, da es ähnlich wie Twitter auch ein Social Network wird. Zwar in winziger Form und eine komplett andere Art (für Autoren) aber dennoch finde ich solche URLs passend zu solchen Seiten. Hier geht es ja auch oft darum, dass man anderen Leuten mal schnell seine Profil URL schickt und das geht so am besten. Klar ein weiteres /user/ würde jetzt auch keinen stören aber ich finds irgendwie nicht so doll :D

  • 1. Ich kann mir nicht vorstellen, dass es im gesamten Netz keine Anleitung für RegularExpressions gibt, daher kann ich sie ja auch....


    @Topic:
    Deine User dürften auch keine Sonderzeichen (im Speziellen den /) benutzen, sonst helbt diene RegularExpression den kopletten Server aus.

    Code
    1. RewriteRule /([\w|\d|_|-)+/? index.php?p=user&u=$1


    example.com/Tobse123 und example.com/Tobse123/ geht dann, example.com/T_obse-123 auch, example.com/S[om]e*Crazy*N$ame/ nicht.


    Das sollte funktionieren.

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.


    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

  • Danke, das werde ich heute Abend mal ausprobieren! Sieht vielversprechend aus. Sonderzeichen bereits für Usernamen ausgeschlossen (a-z, A-Z, 0-9 und _ geht). Sollte somit mit dieser RegEx kein Problem geben, wenn ich dich richtig verstanden hab.


    Kann ich deine Zeile mit meiner Kombinieren? ->


    Code
    1. RewriteRule ^([^.]+)$ /index.php?p=$1 [L]
    2. RewriteRule /([\w|\d|_|-)+/? index.php?p=user&u=$1


    Damit ich Seiten und Benutzer gleich aufrufen kann...

  • nein, das wird nicht funktionieren, da die erste bereits alles abfängt, was auch für die zweite zutrifft. Ich würde es so machen:

    Code
    1. RewriteRule ^/([\w|\d|_]+)/? page_select.php?arg=$1


    page_select.php:

    PHP
    1. $_GET['arg'] abfrufen
    2. prüfen, ob es eine seite ist
    3. NEIN:
    4. $_GET['p'] = "user";
    5. $_GET['u'] = $_GET['arg'];
    6. index.php includen

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.


    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!