【问题标题】:URL rewriting and redirection (with database data)URL 重写和重定向(使用数据库数据)
【发布时间】:2015-07-26 09:41:27
【问题描述】:

我的网址是http://testurl.com/user.php?id=1&name=TestUser

我上面链接的默认网址需要像http://testurl.com/user/12345/TestUser

如果用户尝试在自己的浏览器链接中更改它,如下所示

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>

【问题讨论】:

  • 到目前为止,您的 htaccess 文件中有什么内容?你试过重写规则吗?
  • 目前为空白。我尝试了多种选择,但都没有奏效。所以,每次失败后,我都会从头开始。

标签: php apache .htaccess mod-rewrite url-rewriting


【解决方案1】:

你需要两件事。

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=$1 [L]
RewriteRule ^user/([0-9]+)/([^/]+)$ user.php?id=$1&name=$2 [L]

注意:此时,请确保 mod_rewrite 已启用并且htaccess 允许(在 Apache 配置文件中)。

一个简单的测试:http://example.com/user/12345/XXXXX 应该在内部重写为/user.php?id=12345&amp;name=XXXXX

2) 现在你需要调整user.php 逻辑(这是你在这里检查你的数据&lt;ID, NAME&gt; 对是否存在)

<?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...

?>

我故意用“重复”部分编写这段代码,让您理解逻辑。
当然,你可以改进它。

【讨论】:

  • 感谢您的回答和解释。今晚我会试一试,然后告诉你。
  • 上面的代码也会创建漂亮的 url 吗?实际上我有一个页面有这个链接testurl.com/user.php?id=1&name=TestUser。此链接仍按原样显示。我已在 .htaccess 文件中添加了条目,但我在页面和浏览器地址栏上获得了相同的链接。有没有我可以解决的问题。
  • Htaccess 规则可确保显示的 url 是新格式(漂亮的 url)。但这并不意味着你不能有错误,例如http://example.com/user/12345/NAME_OF_ID_45678(甚至是“最糟糕的”,一个未知的ID)。这就是为什么我添加了一个 php 逻辑代码来处理它。此外,请确保您已启用 mod_rewrite 并且允许 htaccess(全部在 Apache 配置文件中)。注意:您的 htaccess 必须在根文件夹中
  • 我们鼓励您用“新”链接(漂亮的 url)替换“旧”链接,但这不是强制性的,因为 htaccess 会将旧格式重定向到新格式。如果你尝试它(点击你的旧链接),你会得到一个重定向到http://testurl.com/user/1/TestUser
  • 那么链接正是我的答案。它基于ID。例如,您可以尝试仅更改 ID 部分或仅更改问题标题部分,您将看到它是如何处理的(作为我的 php 逻辑)。这是强制性的,因为 htaccess 对数据库中的数据一无所知。最后,由于 SEO 原因,SO 使其链接看起来像这样:它比(例如)/questions.aspx?ID=30242996 更加用户友好,并且您可以在 url 中使用 question-title。这也(至少,它不再是强制性的)更适合引用
【解决方案2】:

为什么不尝试让一个非常基本的规则起作用,然后从那里开始。

首先您需要确保您的服务器启用了重写模块,然后在您的 htaccess 文件顶部放置:

RewriteEngine On

然后您可以使用正则表达式来放置您的重写规则。例如:

 RewriteRule ^user/(\w+)/(\w+)$ user.php?id=$1&name=$2

【讨论】:

  • 感谢您的回答。
【解决方案3】:

在 root/.htaccess 文件中试试这个

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^user/([a-zA-Z0-9]+)/?$ /user.php?id=$1 [QSA,L]

RewriteRule ^user/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ /user.php?id=$1&name=$2 [QSA,L]

这些条件确保您不会重写服务器上的任何现有文件/目录。

【讨论】:

  • 如果可能,请您详细说明一下。正如我想了解的那样,不想只是复制粘贴代码。谢谢
  • 欢迎您! Apache 文档有一个关于 Mod_rewrite 的基本教程。请看一下..httpd.apache.org/docs/current/mod/mod_rewrite.html
猜你喜欢
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-09
  • 2017-06-16
  • 2016-06-27
相关资源
最近更新 更多