146 votes

Réécriture d'URL avec PHP

Donc, fondamentalement, j'ai cette URL qui ressemble à ceci:

 url.com/picture.php?id=51
 

Comment ferais-je pour convertir cette URL en

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

Je pense que Wordpress fait la même chose. J'ai besoin de faire cela en PHP. Comment pourrais-je m'y prendre?

197voto

Niels Keurentjes Points 19255

Vous pouvez le faire de 2 façons:

L' .htaccess route avec le mod_rewrite

Ajouter un fichier appelé .htaccess dans votre dossier racine, et d'ajouter quelque chose comme ceci:

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

Cela indique à Apache pour activer le mod_rewrite pour ce dossier, et s'il se fait poser une URL correspondant à l'expression régulière, il réécrit en interne à ce que vous voulez, sans que l'utilisateur le voir. Facile, mais inflexible, donc si vous avez besoin de plus de puissance:

Le PHP itinéraire

Placez le code suivant dans votre .htaccess à la place:

FallbackResource index.php

Cela indiquera à exécuter votre index.php pour tous les fichiers qu'il ne peut normalement trouver sur votre site. De là, vous pouvez alors, par exemple:

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

C'est la façon dont les grands sites et les CMS (systèmes de le faire, car il permet beaucoup plus de souplesse dans l'analyse des Url, de configuration et la base de données dépendante de l'Url, etc. Pour sporadiques de l'utilisation de la codé en dur règles de réécriture en .htaccess fera l'affaire.

58voto

Danijel Points 3408

Si vous souhaitez uniquement modifier l'itinéraire picture.php puis l'ajout de la règle de réécriture en .htaccess sera répondre à vos besoins, mais, si vous voulez la réécriture d'URL comme dans Wordpress, alors PHP est le chemin. Ici est simple exemple pour commencer.

Structure de dossier

Il y a deux fichiers qui sont nécessaires dans le dossier racine, .htaccess et index.php, et il serait bon de placer le reste de l' .php fichiers dans le dossier séparé, comme inc/.

root/
  inc/
  .htaccess
  index.php

.htaccess

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

Ce fichier a quatre directives:

  1. RewriteEngine - activer le moteur de réécriture
  2. RewriteRule - refuser l'accès à tous les fichiers dans inc/ le dossier, de rediriger un appel pour que le dossier index.php
  3. RewriteCond - de permettre un accès direct à tous les autres fichiers ( images, css ou des scripts )
  4. RewriteRule - redirection de rien d'autre pour index.php

index.php

Parce que tout est maintenant redirigé vers index.php, il sera déterminé si l'url est correcte, tous les paramètres sont présents, et si le type de paramètres sont corrects.

Pour tester l'url nous avons besoin d'avoir un ensemble de règles, et le meilleur outil pour cela est une expression régulière. En utilisant des expressions régulières, nous allons tuer deux mouches d'un seul coup. Url, pour passer ce test doit avoir tous les paramètres qui sont testés sur des caractères autorisés. Voici quelques exemples de règles.

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

Suivante consiste à préparer l'uri de la demande.

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

Maintenant que nous avons l'uri de la demande, la dernière étape est de tester uri sur les règles d'expression régulière.

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

Match de succès, puisque nous utilisons nommé sous-masques en regex, remplir l' $params tableau presque le même que le PHP remplit l' $_GET tableau. Cependant, lors de l'utilisation d'une url dynamique, $_GET tableau est rempli, sans aucun contrôle des paramètres.

/image/texte/51

Tableau
(
 [0] => /image/texte/51
 [texte] => un peu de texte
 [1] => un peu de texte
 [id] => 51
 [2] => 51
)

image.le php?texte=texte&id=51

Tableau
(
 [texte] => un peu de texte
 [id] => 51
)

Ces quelques lignes de code et une base de savoir des expressions régulières est assez pour commencer à construire un solide système de routage.

Source complet

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' );

7voto

Luca Rocchi Points 2665

c'est un fichier .htaccess qui transmet presque tout à 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
 

alors, c’est à vous d’analyser $ _SERVER ["REQUEST_URI"] et d’acheminer vers picture.php ou autre chose

7voto

rauchmelder Points 68

PHP n'est pas ce que vous cherchez, consultez mod_rewrite

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X