URL重写和重定向(带数据库数据)
URL rewriting and redirection (with database data)
我的 url 是 http://testurl.com/user.php?id=1&name=TestUser
上面 link 的默认 url 需要像 http://testurl.com/user/12345/TestUser
如果用户尝试在自己的浏览器中更改它 link 如下所示
http://testurl.com/user/12345
http://testurl.com/user/12345/
http://testurl.com/user/12345/TestUsers_bla-bla
然后 url 栏自动更改为 http://testurl.com/user/12345/TestUser
编辑
<?php
$name = "This-is-a-test-user";
$id = 1;
$fields = array('id' => $id,
'name' => $name);
$url = "http://localhost/view_user.php?" . http_build_query($fields, '', "&");
?>
<a href = "<?php echo $url; ?>"> View User</a>
在 root/.htaccess 文件中试试这个
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^user/([a-zA-Z0-9]+)/?$ /user.php?id= [QSA,L]
RewriteRule ^user/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ /user.php?id=&name= [QSA,L]
条件确保您不会重写服务器上任何现有的 file/directories。
为什么不尝试让一个非常基本的规则起作用,然后从那里开始。
首先您需要确保您的服务器启用了重写模块,然后在您的 htaccess 文件的顶部放置:
RewriteEngine On
然后您可以使用正则表达式重写规则。例如:
RewriteRule ^user/(\w+)/(\w+)$ user.php?id=&name=
这里你需要两件事。
1) htaccess 规则处理
http://testurl.com/user/12345
http://testurl.com/user/12345/
http://testurl.com/user/12345/xxx
和对应规则避免重复内容(重定向旧格式/user.php?xxx
为新格式/user/ID/NAME
)
为此,您可以将此代码放入您的根 htaccess
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)\s [NC]
RewriteRule ^ user/%1? [R=301,L]
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)&name=([^&\s]+)\s [NC]
RewriteRule ^ user/%1/%2? [R=301,L]
RewriteRule ^user/([0-9]+)/?$ user.php?id= [L]
RewriteRule ^user/([0-9]+)/([^/]+)$ user.php?id=&name= [L]
注意:此时,确保启用 mod_rewrite 并允许 htaccess
(在 Apache 配置文件中)。
一个简单的测试:http://example.com/user/12345/XXXXX
应该在内部重写为 /user.php?id=12345&name=XXXXX
。
2) 现在你需要调整 user.php
逻辑(这是你检查你的数据 <ID, NAME>
对是否存在)
<?php
if (!isset($_GET['id']) || empty($_GET['id']))
{
// error page not found (since there is no ID)
header("HTTP/1.1 404 Not Found");
return;
}
if (!isset($_GET['name']) || empty($_GET['name']))
{
// no name -> get it by its ID
$name = getNameByID($_GET['id']); // this function checks in the database
if ($name === NULL)
{
// error: ID is unknown -> page not found
header("HTTP/1.1 404 Not Found");
return;
}
// ID exists, we now have its name -> redirect to /user/ID/NAME (instead of /user/ID)
header("HTTP/1.1 301 Moved Permanently");
header("Location: /user/".$_GET['id']."/".$name);
return;
}
// if we reach here, we have an ID and a name in the url
// we have to check if NAME corresponds to ID (and if ID exists)
$name = getNameByID($_GET['id']); // this function checks in the database
if ($name === NULL)
{
// error: ID is unknown -> page not found
header("HTTP/1.1 404 Not Found");
return;
}
// now, check if NAME in the url corresponds to the one we got from database
if ($name !== $_GET['name'])
{
// it doesn't -> redirect to good NAME
header("HTTP/1.1 301 Moved Permanently");
header("Location: /user/".$_GET['id']."/".$name);
return;
}
// finally, here we're fine.
// do what you then have to do...
?>
我特意用 "duplicate" 部分编写这段代码,让您理解其中的逻辑。
当然,你可以改进它。
我的 url 是 http://testurl.com/user.php?id=1&name=TestUser
上面 link 的默认 url 需要像 http://testurl.com/user/12345/TestUser
如果用户尝试在自己的浏览器中更改它 link 如下所示
http://testurl.com/user/12345
http://testurl.com/user/12345/
http://testurl.com/user/12345/TestUsers_bla-bla
然后 url 栏自动更改为 http://testurl.com/user/12345/TestUser
编辑
<?php
$name = "This-is-a-test-user";
$id = 1;
$fields = array('id' => $id,
'name' => $name);
$url = "http://localhost/view_user.php?" . http_build_query($fields, '', "&");
?>
<a href = "<?php echo $url; ?>"> View User</a>
在 root/.htaccess 文件中试试这个
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^user/([a-zA-Z0-9]+)/?$ /user.php?id= [QSA,L]
RewriteRule ^user/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ /user.php?id=&name= [QSA,L]
条件确保您不会重写服务器上任何现有的 file/directories。
为什么不尝试让一个非常基本的规则起作用,然后从那里开始。
首先您需要确保您的服务器启用了重写模块,然后在您的 htaccess 文件的顶部放置:
RewriteEngine On
然后您可以使用正则表达式重写规则。例如:
RewriteRule ^user/(\w+)/(\w+)$ user.php?id=&name=
这里你需要两件事。
1) htaccess 规则处理
http://testurl.com/user/12345
http://testurl.com/user/12345/
http://testurl.com/user/12345/xxx
和对应规则避免重复内容(重定向旧格式/user.php?xxx
为新格式/user/ID/NAME
)
为此,您可以将此代码放入您的根 htaccess
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)\s [NC]
RewriteRule ^ user/%1? [R=301,L]
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)&name=([^&\s]+)\s [NC]
RewriteRule ^ user/%1/%2? [R=301,L]
RewriteRule ^user/([0-9]+)/?$ user.php?id= [L]
RewriteRule ^user/([0-9]+)/([^/]+)$ user.php?id=&name= [L]
注意:此时,确保启用 mod_rewrite 并允许 htaccess
(在 Apache 配置文件中)。
一个简单的测试:http://example.com/user/12345/XXXXX
应该在内部重写为 /user.php?id=12345&name=XXXXX
。
2) 现在你需要调整 user.php
逻辑(这是你检查你的数据 <ID, NAME>
对是否存在)
<?php
if (!isset($_GET['id']) || empty($_GET['id']))
{
// error page not found (since there is no ID)
header("HTTP/1.1 404 Not Found");
return;
}
if (!isset($_GET['name']) || empty($_GET['name']))
{
// no name -> get it by its ID
$name = getNameByID($_GET['id']); // this function checks in the database
if ($name === NULL)
{
// error: ID is unknown -> page not found
header("HTTP/1.1 404 Not Found");
return;
}
// ID exists, we now have its name -> redirect to /user/ID/NAME (instead of /user/ID)
header("HTTP/1.1 301 Moved Permanently");
header("Location: /user/".$_GET['id']."/".$name);
return;
}
// if we reach here, we have an ID and a name in the url
// we have to check if NAME corresponds to ID (and if ID exists)
$name = getNameByID($_GET['id']); // this function checks in the database
if ($name === NULL)
{
// error: ID is unknown -> page not found
header("HTTP/1.1 404 Not Found");
return;
}
// now, check if NAME in the url corresponds to the one we got from database
if ($name !== $_GET['name'])
{
// it doesn't -> redirect to good NAME
header("HTTP/1.1 301 Moved Permanently");
header("Location: /user/".$_GET['id']."/".$name);
return;
}
// finally, here we're fine.
// do what you then have to do...
?>
我特意用 "duplicate" 部分编写这段代码,让您理解其中的逻辑。
当然,你可以改进它。