用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就是这样。 这里是一个简单的例子。
文件夹结构
根文件夹中需要两个文件, .htaccess
和index.php
,将其余的.php
文件放在单独的文件夹(如inc/
将会很好。
root/ inc/ .htaccess index.php
的.htaccess
RewriteEngine On RewriteRule ^inc/.*$ index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L]
这个文件有四个指令:
-
RewriteEngine
– 启用重写引擎 -
RewriteRule
– 拒绝访问inc/
文件夹中的所有文件,将对该文件夹的任何调用redirect到index.php
-
RewriteCond
– 允许直接访问所有其他文件(如图像,CSS或脚本) -
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应用程序。