URL herschrijven met PHP

Ik heb een URL die eruitziet als:

url.com/picture.php?id=51

Hoe zou ik die URL kunnen converteren naar:

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

Ik denk dat WordPress hetzelfde doet.

Hoe maak ik gebruiksvriendelijke URL’s in PHP?


Antwoord 1, autoriteit 100%

Je kunt dit in wezen op 2 manieren doen:

De .htaccess-route met mod_rewrite

Voeg een bestand toe met de naam .htaccessin je hoofdmap en voeg zoiets als dit toe:

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

Dit zal Apache vertellen om mod_rewrite voor deze map in te schakelen, en als het een URL wordt gevraagd die overeenkomt met de reguliere expressie, herschrijft het het internnaar wat je wilt, zonder dat de eindgebruiker het ziet. Makkelijk, maar inflexibel, dus als je meer kracht nodig hebt:

De PHP-route

Plaats in plaats daarvan het volgende in uw .htaccess: (let op de schuine streep)

FallbackResource /index.php

Dit zal het vertellen om uw index.phpuit te voeren voor alle bestanden die het normaal niet op uw site kan vinden. Daarin kun je dan bijvoorbeeld:

$path = ltrim($_SERVER['REQUEST_URI'], '/');    // Trim leading slash(es)
$elements = explode('/', $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();
}

Dit is hoe grote sites en CMS-systemen het doen, omdat het veel meer flexibiliteit biedt bij het ontleden van URL’s, configuratie- en database-afhankelijke URL’s enz. Voor sporadisch gebruik zullen de hardcoded herschrijfregels in .htaccessdoe het echter goed.


Antwoord 2, autoriteit 29%

Als u alleen de route voor picture.phpwilt wijzigen, dan zal het toevoegen van een herschrijfregel in .htaccessaan uw behoeften voldoen, maar als u wilt dat de URL wordt herschreven als in WordPress dan is PHP de weg. Hier is een eenvoudig voorbeeld om mee te beginnen.

Mappenstructuur

Er zijn twee bestanden die nodig zijn in de hoofdmap, .htaccessen index.php, en het zou goed zijn om de rest van de .phpbestanden in een aparte map, zoals inc/.

root/
  inc/
  .htaccess
  index.php

.htaccess

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

Dit bestand heeft vier richtlijnen:

  1. RewriteEngine– schakel de herschrijfengine in
  2. RewriteRule– weiger toegang tot alle bestanden in de map inc/, stuur elke aanroep naar die map om naar index.php
  3. RewriteCond– geef directe toegang tot alle andere bestanden (zoals afbeeldingen, css of scripts)
  4. RewriteRule– stuur iets anders om naar index.php

index.php

Omdat alles nu wordt omgeleid naar index.php, wordt er bepaald of de url correct is, alle parameters aanwezig zijn en of het type parameters correct is.

Om de url te testen hebben we een set regels nodig, en de beste tool daarvoor is een reguliere expressie. Door reguliere expressies te gebruiken, doden we twee vliegen in één klap. Url, om deze test te doorstaan, moeten alle vereiste parameters zijn getest op toegestane tekens. Hier zijn enkele voorbeelden van regels.

$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'      => "/"                                      // '/'
);

Het volgende is om de verzoek-uri voor te bereiden.

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

Nu we het verzoek uri hebben, is de laatste stap het testen van uri op regels voor reguliere expressies.

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 )
         */
    }
}

Succesvolle match zal, aangezien we benoemde subpatronen gebruiken in regex, de $paramsarray bijna hetzelfde vullen als PHP de $_GETarray vult. Wanneer u echter een dynamische url gebruikt, wordt de $_GET-array gevuld zonder enige controle van de parameters.

/foto/sommige+tekst/51
  Array
  (
    [0] => /foto/wat tekst/51
    [tekst] => wat tekst
    [1] => wat tekst
    [id] => 51
    [2] => 51
  )
  picture.php?text=some+text&id=51
  Array
  (
    [tekst] => wat tekst
    [id] => 51
  )

Deze paar regels code en een basiskennis van reguliere expressies is voldoende om een ​​solide routeringssysteem te bouwen.

Volledige bron

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'      => "/"                                      // '/'
);
$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' );
$uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' );
$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' );

Antwoord 3, autoriteit 3%

dit is een .htaccess-bestand dat bijna alles doorstuurt naar index.php

# 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

dan is het aan jou om $_SERVER[“REQUEST_URI”] te ontleden en door te sturen naar picture.php of wat dan ook


Antwoord 4, autoriteit 3%

PHP is niet wat je zoekt, bekijk mod_rewrite


Antwoord 5

Hoewel reeds beantwoord, en de intentie van de auteur is om een app voor de front controller te maken, maar ik post de letterlijke regel voor het probleem. Als iemand het probleem heeft voor hetzelfde.

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

hierboven moet werken voor URL picture.php/Some-text-goes-here/51. zonder een index.php te gebruiken als een omleidingsapp.

Other episodes