URL rewriting with PHP


URL rewriting with PHP

我有一个URL,看起来像:

url.com/picture.php?id=51

如何将URL转换为:

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

我想WordPress也是一样的。

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

有两种方法:

使用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中的硬编码重写规则将做得很好。

如果你只想改变picture.php的路由,那么在.htaccess中添加重写规则将满足你的需求,但是,如果你想在Wordpress中重写URL,那么PHP就是方法。下面是一个简单的例子。

<<p> 文件夹结构/strong>

根文件夹中需要两个文件,.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/文件夹中的所有文件,将对该文件夹的任何调用重定向到index.php
  3. RewriteCond -允许直接访问所有其他文件(如图像,css或脚本)
  4. RewriteRule -重定向到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 )
         */
    }
}

由于我们在regex中使用命名子模式,因此成功匹配将填充$params数组,几乎与PHP填充$_GET数组相同。但是,当使用动态url时,$_GET数组将在不检查参数的情况下填充。

<>之前/图片/一些+文本/51数组([0] =>/picture/some text/[text] =>一些文本[1] =>一些文本[id] => 51[2] => 51)picture.php吗?文本= + text&id = 51数组([text] =>一些文本[id] => 51)之前这几行代码和对正则表达式的基本了解足以开始构建一个可靠的路由系统。 <<p> 完成来源/strong>
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

然后由您解析$_SERVER["REQUEST_URI"]并路由到picture.php或其他

PHP不是你要找的,检查mod_rewrite

虽然已经回答了,作者的意图是创建一个前端控制器类型的应用程序,但我张贴文字规则的问题。如果有人有同样的问题。

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

以上应该适用于url picture.php/Some-text-goes-here/51。不使用index.php作为重定向应用