【问题标题】:URL redirect based on GET params基于 GET 参数的 URL 重定向
【发布时间】:2014-12-28 22:34:32
【问题描述】:

我想让我的网站上的 URL 更好一点。

目前单品页面有以下形式:

www.mywebsite.com/details.php?id=1

我希望那些更像

www.mywebsite.com/name-of-the-product?id=1

其中 id=1 是可变的,它将是特定产品的 id。

所以我想将所有新链接重定向到名为 details.php 的旧页面,并将 id 传递给它。

我搜索了一些答案,但所有这些都是针对预定义和特定的 GET 参数,我希望这对网站上的所有产品更通用。

更新

感谢大家的帮助!看来我误导了你。我在网站上有很多页面。而且我只想为这个更改路线(单个产品页面,以便那些特定的路线看起来更好)。 现在,只有 @samurai 的答案会重定向,但它也会重定向所有其他页面。这就是为什么我想添加一些特定的 GET 参数(或类似的东西),告诉 .htaccess '嘿,只将这样的页面重定向到 details.php'。 可以这样吗?

【问题讨论】:

  • 如果您已经有了“产品名称”,为什么您的 URL 中还需要 product_id?也许您需要这样的 URL:www.mywebsite.com/product/1 其中 1 是您的产品 ID?
  • 可能是我遗漏了一些东西。我在想通过 id 获取它比将 url slug 转换回产品名称更容易。所以它就像:nike-air-max,在我的数据库中它是 Nike Air Max 等
  • 我认为在这种情况下,如果它有特定的东西(比如 id=?),那么获取 URL(在 .htaccess 中)会更容易。

标签: .htaccess mod-rewrite redirect url-rewriting


【解决方案1】:

内部重写如下所示:

RewriteRule ^(?!details\.php)[^/]+/?$ details.php [L]

查询字符串会自动结转。 (?details\.php) 部分是负前瞻。它会阻止 details.php 匹配此规则,因为这会导致无限循环。请注意,您应该:

  • 如果提供了 id,请检查 details.php。如果没有提供,你应该做你的数据库魔术来获取这个 id,然后在 php 中重定向客户端

    if( empty( $_GET['id'] ) ) {
      $id = getIdByName( $name );
      header( "Location: {$name}?id={$id}", 301 );
      exit();
    }
    
  • 检查是否没有直接请求 details.php。您无法在 .htaccess 中凭空召唤产品名称,因此您需要在 php 脚本中执行此操作

    if( empty( $name ) || $name == "details.php" ) {
      $name = getNameById( $id );
      header( "Location: {$name}?id={$id}", 301 );
      exit();
    }
    

【讨论】:

  • 嘿@Sumurai8,我试过了,但它会将所有页面重定向到详细信息。 php。请检查我更新的问题。
  • 解决这个问题的方法通常是添加一个通用前缀(类似于 lolbas 建议的)。如果所有产品都是product/product-name?id=123的形式,你可以匹配RewriteRule ^product/[^/]+/?$ details.php [L]。或者排除所有您不想在否定前瞻中匹配的页面,但这会很快变得混乱!
  • 关于这个的最后一个问题,对不起,我完全不知道这个问题。现在从 /product 获取 css、js 和其他资产,而不是从根 / 获取此页面。也能修好吗?
  • 这是我的 .htaccess 现在的样子:<IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On RewriteBase / RewriteRule \.(css|jpe?g|gif|png|js|ico)$ - [L] RewriteRule ^product/[^/]+/?$ details.php [L] </IfModule>
  • 您正在为您的 css 和 js 使用相对 url,因此它采用出现在地址栏中的 url 并尝试找到与之相关的 css 和 js 文件。显然它不会在那里找到它们。要么将这些网址设为绝对网址,要么在 html 页面的头部使用 <base href="/">。
【解决方案2】:

为什么会在显示产品名称时在 url 中保留 id? 无论如何,你可以做的是根据提供的 id 从数据库中获取产品名称,头页到所需的 url 并添加一些 .htaccess 魔法

UPD:让我们以 Nike Air Max 为例。用户尝试访问下一个 url:www.mywebsite.com/?id=1,而在您的数据库中,Air Maxes 与 id=1 相关联。你页面的一段php代码:

$id = intval( $_GET['id'], 10 );
$product_name = mysqli_fetch_assoc(mysqli_query($con, "SELECT item_name FROM products WHERE id = $id"));
$altered_name = str_replace(' ', '-', $product_name);
header('Location: /?id=1&product_name='.$altered_name);

现在还有一些 .htaccess 魔法

RewriteRule ^product/([^/]*)$ /?id=1&product_name=$1 [L]

因此,url 将是www.website.com/product/nike-air-maxes

【讨论】:

  • 是的,嗯,.htaccess 魔法是我感兴趣的部分:)
  • 感谢您的评论和帮助。我会赞成你的答案,我希望我能为你的两个答案都加分。
【解决方案3】:

创建一个 .htaccess 文件并将这些行放入其中:

RewriteEngine on
# URL rewriting rules
RewriteRule ^([_a-zA-Z0-9-]+)/([0-9]+)$ details.php?id=$2 [L,E]

你的网址应该是:www.mywebsite.com/name-of-the-product/1

或

RewriteRule ^([_a-zA-Z0-9-]+)?$ details.php [L,E]

拥有这样的网址:www.mywebsite.com/name-of-the-product?id=1

【讨论】:

  • 谢谢,我试过了,但不能让它工作,就像它完全无视规则一样。请查看我更新的问题。
猜你喜欢
  • 2019-04-17
  • 2011-09-30
  • 2021-07-29
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多