我的网址如下所示:
url.com/picture.php?id=51
我该如何将该 URL 转换为:
picture.php/Some-text-goes-here/51
我认为 WordPress 也是这样做的。
如何在 PHP 中创建友好的 URL?
您基本上可以通过两种方式做到这一点:
在根文件夹中添加一个名为
.htaccess
的文件,并添加如下内容:
RewriteEngine on
RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1
这将告诉 Apache 对此文件夹启用 mod_rewrite,如果它被询问与正则表达式匹配的 URL,它会在内部将其重写为您想要的内容,而最终用户不会看到它。简单,但不灵活,所以如果您需要更多动力: PHP路线
FallbackResource /index.php
这将告诉它运行您的
index.php
以查找通常无法在您的站点中找到的所有文件。例如,您可以在那里:
$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 系统就是这样做的,因为它在解析 URL、配置和数据库相关 URL 等方面提供了更大的灵活性。对于零星使用,
.htaccess
中的硬编码重写规则就可以了。
picture.php
的路由,那么在
.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/
文件夹中的所有文件,将对该文件夹的任何调用重定向到 index.php
RewriteCond
RewriteRule
index.php
因为现在所有内容都重定向到index.php,因此将确定url是否正确,所有参数是否存在,以及参数类型是否正确。
为了测试 url,我们需要有一组规则,而最好的工具就是正则表达式。通过使用正则表达式,我们可以一击打死两只苍蝇。要通过此测试,Url 必须具有针对允许的字符进行测试的所有必需参数。以下是一些规则示例。
$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,最后一步是根据正则表达式规则测试 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 )
*/
}
}
成功的匹配将,因为我们在正则表达式中使用命名子模式,填充
$params
数组几乎与PHP填充
$_GET
数组相同。但是,当使用动态 url 时,会在不检查参数的情况下填充 $_GET
数组。 /图片/一些+文字/51
大批
(
[0] => /图片/一些文字/51
[文本] => 一些文本
[1] => 一些文字
[id] => 51
[2] => 51
)
图片.php?text=some+text&id=51
大批
(
[文本] => 一些文本
[id] => 51
)
这几行代码和对正则表达式的基本了解足以开始构建可靠的路由系统。完整源码
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';
# 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
然后由您解析 $_SERVER["REQUEST_URI"] 并路由到 picture.php 或其他内容
RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)/([\d]+)$ $1?id=$3 [L]
以上应该适用于 url
picture.php/Some-text-goes-here/51
。不使用index.php作为重定向应用程序。