使用 PHP 重写 URL

问题描述 投票:0回答:6

我的网址如下所示:

url.com/picture.php?id=51

我该如何将该 URL 转换为:

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

我认为 WordPress 也是这样做的。

如何在 PHP 中创建友好的 URL?

php .htaccess url mod-rewrite url-rewriting
6个回答
207
投票

您基本上可以通过两种方式做到这一点:

带有 mod_rewrite 的 .htaccess 路由

在根文件夹中添加一个名为

.htaccess
的文件,并添加如下内容:

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

这将告诉 Apache 对此文件夹启用 mod_rewrite,如果它被询问与正则表达式匹配的 URL,它会在内部将其重写为您想要的内容,而最终用户不会看到它。简单,但不灵活,所以如果您需要更多动力: PHP路线

将以下内容放入 .htaccess 中:(注意前导斜杠)

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

中的硬编码重写规则就可以了。

    


60
投票
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
  1. - 启用重写引擎
  2. RewriteRule
  3. - 拒绝访问
    inc/
    文件夹中的所有文件,将对该文件夹的任何调用重定向到
    index.php
  4. RewriteCond
  5. - 允许直接访问所有其他文件(如图像、CSS 或脚本)
  6. RewriteRule
  7. - 将其他任何内容重定向到
    index.php
    
    
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';



7
投票

# 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 或其他内容


6
投票
mod_rewrite


3
投票

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

以上应该适用于 url 
picture.php/Some-text-goes-here/51

。不使用index.php作为重定向应用程序。

    


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.