用PHP重写URL

我有一个URL如下所示:

url.com/picture.php?id=51 

我将如何去转换该URL到:

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

我认为WordPress也一样。

我如何在PHP中创build友好的URL?

你基本上可以做到这两点:

带有mod_rewrite的.htaccess路由

在根文件夹中添加一个名为.htaccess文件,并添加如下内容:

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

这将告诉Apache为这个文件夹启用mod_rewrite,如果它被问到一个与正则expression式相匹配的URL,它会在内部重写它到你想要的内容,而最终用户不会看到它。 简单但不灵活,所以如果你需要更多的权力:

PHP路线

把下面的.htaccess代替:

 FallbackResource index.php 

这将告诉它运行您的index.php所有文件,它通常无法在您的网站find。 那么你可以在那里例如:

 $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(); } 

这就是大的网站和CMS系统,因为它在parsingURL,configuration和依赖于数据库的URL等方面具有更大的灵活性。对于零星的使用,硬编码的.htaccess重写规则将会很好。

如果你只想改变picture.php的path,那么在.htaccess添加重写规则将满足你的需求,但是,如果你想在WordPress中重写URL,那么PHP就是这样。 这里是一个简单的例子。

文件夹结构

根文件夹中需要两个文件, .htaccessindex.php ,将其余的.php文件放在单独的文件夹(如inc/将会很好。

 root/ inc/ .htaccess index.php 

的.htaccess

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

这个文件有四个指令:

  1. RewriteEngine – 启用重写引擎
  2. RewriteRule – 拒绝访问inc/文件夹中的所有文件,将对该文件夹的任何调用redirect到index.php
  3. RewriteCond – 允许直接访问所有其他文件(如图像,CSS或脚本)
  4. RewriteRule – redirect到index.php

的index.php

因为现在所有的东西都被redirect到了index.php,所以会确定url是否正确,所有的参数是否存在,以及参数的types是否正确。

为了testingurl,我们需要一套规则,最好的工具是正则expression式。 通过使用正则expression式,我们将一举击毙两只苍蝇。 要通过此testing的url必须具有在允许的字符上进行testing的所有必需参数。 以下是一些规则的例子。

 $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。

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

现在我们有了请求uri,最后一步就是在正则expression式规则上testinguri。

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

成功的匹配,因为我们在正则expression式中使用命名的子模式,填充$params数组几乎相同,PHP填充$_GET数组。 但是,当使用dynamicURL时, $_GET数组将被填充,而不会对参数进行任何检查。

     /图片/一些+文本/ 51

    排列
     (
         [0] => /图片/一些文字/ 51
         [text] =>一些文字
         [1] =>一些文字
         [id] => 51
         [2] => 51
     )

     picture.php?文本=一些文字+&ID = 51

    排列
     (
         [text] =>一些文字
         [id] => 51
     )

这几行代码和正则expression式的基本知识足以开始构build一个坚实的路由系统。

完整的来源

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

这是一个.htaccess文件,几乎所有的转发到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 

那么是由你parsing$ _SERVER [“REQUEST_URI”]并路由到picture.php或任何

PHP不是你正在寻找的,看看mod_rewrite

虽然已经回答了,作者的意图是创build一个前端控制器types的应用程序,但我发布文字规则的问题。 如果有人遇到同样的问题。

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

以上应该适用于url picture.php/Some-text-goes-here/51 。 而不使用index.php作为redirect应用程序。