URL-Umschreibung mit PHP

Lesezeit: 8 Minuten

URL Umschreibung mit PHP
Jazerix

Ich habe eine URL, die so aussieht:

url.com/picture.php?id=51

Wie würde ich vorgehen, um diese URL zu konvertieren in:

picture.php/Some-text-goes-here/51

Ich denke, WordPress macht das gleiche.

Wie mache ich freundliche URLs in PHP?

  • Sie müssen viel in der Konfiguration der Apache-Dateien optimieren … geben Sie ein Beispiel dafür, was Sie tatsächlich brauchen? Wie fügt man diesen Text ein? Ist es vordefiniert oder wird es dynamisch erstellt? Geben Sie so viele Informationen wie möglich an, um die richtige Antwort zu erhalten … und ja, die URL könnte etwas aussagekräftiger sein 🙂

    – Benutzer123_456

    5. Mai 2013 um 20:45 Uhr


  • Warum PHP? Apachen mod_rewrite ist alles, was Sie dafür brauchen, und es gibt viele Fragen dazu hier auf SO. Und wenn Sie “denken”, dass WordPress dasselbe tut, warum schaust du nicht einfach nach? 😉

    – Nietontanne

    5. Mai 2013 um 20:45 Uhr


  • lesen mod_rewrite

    Benutzer1646111

    5. Mai 2013 um 20:46 Uhr

  • Warum tust du das? Ist das Ziel, die URLs umzuschreiben, wenn ja, verwenden Sie .htaccess oder etwas Ähnliches. Wenn das Ziel nur darin besteht, die Zeichenfolge zu ändern, erhält $_GET nur die Abfragezeichenfolge ?

    – adeneo

    5. Mai 2013 um 20:47 Uhr


  • Der Text wäre der Titel eines Bildes und dann die ID nach dem Schrägstrich 🙂 Ich muss mir ansehen, was Apaches mod_rewrite zu bieten hat. Hoffe es ist nicht zu schwer 😀

    – Jazerix

    5. Mai 2013 um 20:48 Uhr

URL Umschreibung mit PHP
Niels Keurentjes

Sie können dies im Wesentlichen auf 2 Arten tun:

Die .htaccess-Route mit mod_rewrite

Fügen Sie eine Datei namens hinzu .htaccess in Ihrem Stammordner und fügen Sie so etwas hinzu:

RewriteEngine on
RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1

Dadurch wird Apache angewiesen, mod_rewrite für diesen Ordner zu aktivieren, und wenn er nach einer URL gefragt wird, die dem regulären Ausdruck entspricht, schreibt er ihn um im Inneren was Sie wollen, ohne dass der Endbenutzer es sieht. Einfach, aber unflexibel, wenn Sie also mehr Leistung benötigen:

Die PHP-Route

Fügen Sie stattdessen Folgendes in Ihre .htaccess ein: (beachten Sie den führenden Schrägstrich)

FallbackResource /index.php

Dadurch wird es angewiesen, Ihre auszuführen index.php für alle Dateien, die es normalerweise nicht auf Ihrer Site finden kann. Dort kannst du dann zum Beispiel:

$path = ltrim($_SERVER['REQUEST_URI'], "https://stackoverflow.com/");    // Trim leading slash(es)
$elements = explode("https://stackoverflow.com/", $path);                // Split path on slashes
if(empty($elements[0])) {                       // No path elements means home
    ShowHomepage();
} else switch(array_shift($elements))             // Pop off first item and switch
{
    case 'Some-text-goes-here':
        ShowPicture($elements); // passes rest of parameters to internal function
        break;
    case 'more':
        ...
    default:
        header('HTTP/1.1 404 Not Found');
        Show404Error();
}

Auf diese Weise machen es große Websites und CMS-Systeme, weil es viel mehr Flexibilität beim Parsen von URLs, konfigurations- und datenbankabhängigen URLs usw. ermöglicht .htaccess wird aber gut gehen.

  • Anstatt es fest zu codieren, könnten Sie einfach Regex verwenden, um die Zeichenfolge vollständig zu ignorieren. Mit anderen Worten, es zählt nur der ID-Teil. Geht zu picture.php/invalid-text/51 würde auch an die gleiche Stelle umleiten. Sie können auch eine Überprüfung hinzufügen, um zu sehen, ob die Zeichenfolge korrekt ist, und falls nicht, erneut an die richtige Stelle umleiten. So habe ich es auf einer meiner Seiten mit htaccess gemacht.

    – Mike

    5. Mai 2013 um 21:09 Uhr

  • Praktisch für kleinere Websites, aber nicht wirklich praktisch, wenn Sie parsen müssen /blog/25 ebenso gut wie /picture/51 und /download/684. Außerdem gilt es als sehr schlechte Praxis (und Sie werden von Google PR bestraft!), wenn nicht alle zufällig generierten URLs ordnungsgemäß 404 zurückgeben.

    – Niels Keurentjes

    5. Mai 2013 um 21:12 Uhr

  • auf meinem System war das zumindest FallbackResource /index.php (beachten Sie den führenden Schrägstrich)

    – Jack James

    31. Januar 2014 um 14:46 Uhr


  • @olli: Der Kommentar zu schlechten Praktiken bezieht sich speziell auf “keine Rückgabe von 404 für nicht vorhandene URLs”, was von der Lösung in der Antwort selbst gelöst wird. Was die erste Frage angeht – FallbackResource tritt nur bei Dateien ein, die nicht wirklich im Dateisystem vorhanden sind, daher die Zurückfallen. Wenn Sie also eine Datei haben /static/styles.css und bezeichne es als http://mydomain.tld/static/styles.css Der Code wird nie ausgeführt, sodass er wie erwartet und transparent funktioniert.

    – Niels Keurentjes

    15. Juni 2014 um 10:56 Uhr


  • du solltest benutzen if($elements[0] === NULL) stattdessen als $elements wird immer noch eine Zählung von eins zurückgeben, auch wenn es leer ist.

    – Feuer im Weltraum

    8. Februar 2016 um 22:00 Uhr

URL Umschreibung mit PHP
Daniel

Wenn Sie nur die Route ändern möchten für picture.php dann fügen Sie eine Umschreiberegel hinzu .htaccess wird Ihren Bedürfnissen entsprechen, aber wenn Sie die URL-Umschreibung wie in WordPress wünschen, ist PHP der richtige Weg. Hier ist ein einfaches Beispiel für den Anfang.

Ordnerstruktur

Es gibt zwei Dateien, die im Stammordner benötigt werden, .htaccess und index.phpund es wäre gut, den Rest zu platzieren .php Dateien in einem separaten Ordner, wie z inc/.

root/
  inc/
  .htaccess
  index.php

.htaccess

RewriteEngine On
RewriteRule ^inc/.*$ index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

Diese Datei hat vier Direktiven:

  1. RewriteEngine – Aktivieren Sie die Rewriting-Engine
  2. RewriteRule – Zugriff auf alle Dateien in verweigern inc/ Ordner, leiten Sie alle Anrufe an diesen Ordner um index.php
  3. RewriteCond – direkten Zugriff auf alle anderen Dateien (wie Bilder, CSS oder Skripte) erlauben
  4. RewriteRule – alles andere umleiten index.php

index.php

Da nun alles auf index.php umgeleitet wird, wird dort festgestellt, ob die URL korrekt ist, alle Parameter vorhanden sind und ob der Typ der Parameter korrekt ist.

Um die URL zu testen, brauchen wir eine Reihe von Regeln, und das beste Werkzeug dafür ist ein regulärer Ausdruck. Durch die Verwendung regulärer Ausdrücke töten wir zwei Fliegen mit einem Schlag. URL, um diesen Test zu bestehen, muss alle erforderlichen Parameter haben, die auf zulässige Zeichen getestet werden. Hier sind einige Beispiele für Regeln.

$rules = array( 
    'picture'   => "/picture/(?'text'[^/]+)/(?'id'\d+)",    // '/picture/some-text/51'
    'album'     => "/album/(?'album'[\w\-]+)",              // '/album/album-slug'
    'category'  => "/category/(?'category'[\w\-]+)",        // '/category/category-slug'
    'page'      => "/page/(?'page'about|contact)",          // '/page/about', '/page/contact'
    'post'      => "/(?'post'[\w\-]+)",                     // '/post-slug'
    'home'      => "https://stackoverflow.com/"                                      // "https://stackoverflow.com/"
);

Als Nächstes bereiten Sie die Anforderungs-URI vor.

$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), "https://stackoverflow.com/" );
$uri = "https://stackoverflow.com/" . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), "https://stackoverflow.com/" );
$uri = urldecode( $uri );

Nachdem wir nun die Anforderungs-URI haben, besteht der letzte Schritt darin, uri auf Regeln für reguläre Ausdrücke zu testen.

foreach ( $rules as $action => $rule ) {
    if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) {
        /* now you know the action and parameters so you can 
         * include appropriate template file ( or proceed in some other way )
         */
    }
}

Eine erfolgreiche Übereinstimmung wird, da wir benannte Teilmuster in Regex verwenden, die füllen $params Array fast genauso wie PHP das füllt $_GET Reihe. Wenn Sie jedoch eine dynamische URL verwenden, $_GET Das Array wird ohne Überprüfung der Parameter gefüllt.

    /picture/some+text/51

    Array
    (
        [0] => /picture/some text/51
        [text] => some text
        [1] => some text
        [id] => 51
        [2] => 51
    )

    picture.php?text=some+text&id=51

    Array
    (
        [text] => some text
        [id] => 51
    )

Diese wenigen Codezeilen und ein grundlegendes Wissen über reguläre Ausdrücke reichen aus, um mit dem Aufbau eines soliden Routing-Systems zu beginnen.

Vollständige Quelle

define( 'INCLUDE_DIR', dirname( __FILE__ ) . '/inc/' );

$rules = array( 
    'picture'   => "/picture/(?'text'[^/]+)/(?'id'\d+)",    // '/picture/some-text/51'
    'album'     => "/album/(?'album'[\w\-]+)",              // '/album/album-slug'
    'category'  => "/category/(?'category'[\w\-]+)",        // '/category/category-slug'
    'page'      => "/page/(?'page'about|contact)",          // '/page/about', '/page/contact'
    'post'      => "/(?'post'[\w\-]+)",                     // '/post-slug'
    'home'      => "https://stackoverflow.com/"                                      // "https://stackoverflow.com/"
);

$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), "https://stackoverflow.com/" );
$uri = "https://stackoverflow.com/" . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), "https://stackoverflow.com/" );
$uri = urldecode( $uri );

foreach ( $rules as $action => $rule ) {
    if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) {
        /* now you know the action and parameters so you can 
         * include appropriate template file ( or proceed in some other way )
         */
        include( INCLUDE_DIR . $action . '.php' );

        // exit to avoid the 404 message 
        exit();
    }
}

// nothing is found so handle the 404 error
include( INCLUDE_DIR . '404.php' );

  • Wie lest ihr die Parameter? Es funktioniert nicht mit $post_id = htmlentities($_GET[‘post’]);

    – andrebruton

    20. Juni 2014 um 6:52 Uhr

  • @Danijel Kann ich einen vollständigen Quellcode haben? Ich habe den obigen Code ausprobiert, aber es wurde nur Text ausgegeben, CSS hat keinen Effekt. Danke.

    – 4 Deckung verlassen

    28. August 2017 um 17:21 Uhr

Dies ist eine .htaccess-Datei, die fast alle an die index.php weiterleitet

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_URI} !-l
RewriteCond %{REQUEST_FILENAME} !\.(ico|css|png|jpg|gif|js)$ [NC]
# otherwise forward it to index.php
RewriteRule . index.php

dann liegt es an Ihnen, $_SERVER zu analysieren[“REQUEST_URI”] und route zu picture.php oder was auch immer

  • Apache führte die ein FallbackResource Direktive vor ein paar Hauptversionen, was jetzt der bevorzugte Weg ist, dieses Verhalten mit geringeren Leistungskosten zu implementieren, da es nicht die gesamte Rewriting-Engine starten muss. Dokumentation hier. Ihre Regeln sind auch fehlerhaft, weil Sie nicht auf Verzeichnisse verweisen (!-d) und alle Erweiterungsfilter sind veraltet – die -f sollte sie schon fangen.

    – Niels Keurentjes

    5. Mai 2013 um 21:03 Uhr


PHP ist nicht das, wonach Sie suchen, sehen Sie sich das an mod_rewrite

Obwohl bereits beantwortet, und die Absicht des Autors ist es, eine App vom Typ Front-Controller zu erstellen, aber ich poste eine wörtliche Regel für das gestellte Problem. falls jemand das gleiche problem hat.

RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)/([\d]+)$ $1?id=$3 [L]

Oben sollte für die URL funktionieren picture.php/Some-text-goes-here/51. ohne eine index.php als Redirect-App zu verwenden.

  • Ich muss wissen, welche URL wir in href schreiben müssen? weil ich 404 bekomme

    – Fragenbank

    31. August 2019 um 5:55 Uhr

  • Ich muss wissen, welche URL wir in href schreiben müssen? weil ich 404 bekomme

    – Fragenbank

    31. August 2019 um 5:55 Uhr

993560cookie-checkURL-Umschreibung mit PHP

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy