Php 使用.htaccess获取干净的URL

Php 使用.htaccess获取干净的URL,php,regex,apache,.htaccess,mod-rewrite,Php,Regex,Apache,.htaccess,Mod Rewrite,一段时间以来,我一直在为干净的URL发狂,我希望在这里得到一些帮助,提供一些提示和解决方案 更新 这是我当前的导航@anubhava $select_category = mysql_query("SELECT * FROM menu WHERE hidden = 0 ORDER BY menu ASC"); while ($ln = mysql_fetch_array($select_category)) { $idcat = $ln['nmr']; $catname = $ln['m

一段时间以来,我一直在为干净的URL发狂,我希望在这里得到一些帮助,提供一些提示和解决方案

更新

这是我当前的导航@anubhava

$select_category = mysql_query("SELECT * FROM menu WHERE hidden = 0 ORDER BY menu ASC");
while ($ln = mysql_fetch_array($select_category)) {
  $idcat = $ln['nmr'];
  $catname = $ln['menu'];
  $catsname = str_replace(' ', '-', $ln['menu']);

  echo '<li>';
  if($catname == "a certain category"){
  echo '<a href="http://mywebsite.aurl.net/" title="'.$catname.'"><span><strong>'.$catname.'</strong></span></a>'. PHP_EOL;
     }else{
  echo '<a href="http://www.mywebsite.com/cats/'.$idcat.'/'.$catsname.'/" title="'.$catname.'"><span><strong>'.$catname.'</strong></span></a>'. PHP_EOL; // if the user press on a main category it will stay open using GET[] on $idcat in categorymain.php
     }
  echo '<ul';


  if(isset($_GET['cats']) && $_GET['cats'] == $idcat){
    echo ' style="display:block;">'. PHP_EOL;
  }else{
    echo '>'. PHP_EOL;
  }

  $select_sub = mysql_query("SELECT * FROM submenu WHERE nmrmenu = '$idcat' AND hidden = 0");
  while ($lsub = mysql_fetch_array($select_sub)) {
      $subname = $lsub['submenu'];
    $subsname = str_replace(' ', '-', $lsub['submenu']);
    $pil = '&raquo;';
    $brnr = $lsub['nmr'];

    if(isset($_GET['cat'])){
    if ($_GET['cat'] == $brnr){
        $subname = '<u>'.$lsub['submenu'].'</u>'; // here the subcategory gets underlined if the user press on a sub category in category.php

    }else{
        $subname = $lsub['submenu'];
    }
    }

    echo '<li><a href="http://www.mywebsite.com/cat/'.$lsub['nmr'].'/'.$idcat.'/'.$subsname.'/"><span><strong> '.$pil.' '.$subname.' </strong></span></a></li>'. PHP_EOL; // here i send both main and sub category id so i can keep the main category opened and the underlined sub category when a user has pressed it.
  }

  echo '</ul>'. PHP_EOL;
  echo '</li>'. PHP_EOL;
   }
显示如下:www.xxxxx.com/cats/x/the_main_category/,这不是很好

我的目标是:www.xxxxx.com/the_main_category/

我甚至得到了这个:

RewriteCond %{REQUEST_URI} cats/(.*)/
RewriteRule ^cats/([a-zA-Z0-9]+)/(.*)/$ /categorymain.php?cats=$1&mcn=$2
RewriteCond %{REQUEST_URI} cat/(.*)/
RewriteRule ^cat/([a-zA-Z0-9]+)/(.*)/(.*)/$ /category.php?cat=$1&cats=$2&cn=$3
RewriteCond %{REQUEST_URI} id/(.*)/
RewriteRule ^id/([a-zA-Z0-9]+)/(.*)/(.*)/(.*)/$ /product.php?id=$1&cat=$2&cats=$3&pn=$4
显示如下:www.xxxxx.com/cat/x/x/the_sub_category/,这真的不好

我的目标是:www.xxxxx.com/the_sub_category/

最后我有一句非常可怕的话:

RewriteCond %{REQUEST_URI} cats/(.*)/
RewriteRule ^cats/([a-zA-Z0-9]+)/(.*)/$ /categorymain.php?cats=$1&mcn=$2
RewriteCond %{REQUEST_URI} cat/(.*)/
RewriteRule ^cat/([a-zA-Z0-9]+)/(.*)/(.*)/$ /category.php?cat=$1&cats=$2&cn=$3
RewriteCond %{REQUEST_URI} id/(.*)/
RewriteRule ^id/([a-zA-Z0-9]+)/(.*)/(.*)/(.*)/$ /product.php?id=$1&cat=$2&cats=$3&pn=$4
显示如下:www.xxxxxx.com/id/xxxx/x/x/the_product/hord:O

我的目标是:www.xxxxx.com/the_产品/

如果你能帮我解决这个问题,我会非常高兴


之所以有这么多的变量,是因为我在导航中使用了它们,这样用户可以很容易地看到他们在电子商店中的位置,如果他们想回去,还可以在类别和产品上方使用“内部”导航,这样他们就不必过多地使用侧导航

实际上,您需要的是一个“slug”,它是每个类别的唯一标识符字符串。如果类别名称是“食品”,那么URL中唯一的slug必须是“食品”。一旦建立了这些独特的slug,请将脚本更改为按slug
&cat=food stuff
查找,而不是按数据库中的ID查找

从这里开始,它相当简单,您可以使用您的重写规则并实现您想要的结果

RewriteCond %{REQUEST_URI} /(.*)/
RewriteRule ^/([a-zA-Z0-9]+)/(.*)/$ /categorymain.php?cats=$1&mcn=$2

实际上,您需要的是一个“slug”,它是每个类别的唯一标识符字符串。如果类别名称是“食品”,那么URL中唯一的slug必须是“食品”。一旦建立了这些独特的slug,请将脚本更改为按slug
&cat=food stuff
查找,而不是按数据库中的ID查找

从这里开始,它相当简单,您可以使用您的重写规则并实现您想要的结果

RewriteCond %{REQUEST_URI} /(.*)/
RewriteRule ^/([a-zA-Z0-9]+)/(.*)/$ /categorymain.php?cats=$1&mcn=$2

听起来您真正需要的是将所有内容传递到单个位置:

RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
然后在PHP中解析请求的URL,并确定是否请求了主类别、子类别或产品(通过与数据库等进行比较)


我知道你想要“干净”的URL,但如果每个主类别、子类别和产品名称都是唯一的,那么将URL限制为只包含文本,这肯定是不现实的。你原来的设计/一些身份证/一些名字/非常好。URL中有一个数字并不意味着它“不干净”。

听起来您真正需要的是将所有内容传递到一个位置:

RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
然后在PHP中解析请求的URL,并确定是否请求了主类别、子类别或产品(通过与数据库等进行比较)


我知道你想要“干净”的URL,但如果每个主类别、子类别和产品名称都是唯一的,那么将URL限制为只包含文本,这肯定是不现实的。你原来的设计/一些身份证/一些名字/非常好。URL中有一个数字并不表示它“不干净”。

根据您的评论,尝试以下规则:

RewriteEngine On

RewriteRule ^([\w-]+)/([0-9]+)/?$ /product.php?id=$2&pn=$1 [L,NC,QSA]

这将支持URI结构为:
/productname/123
,内部重写为
/product.php?id=123&pn=productname

,根据您的评论,尝试以下规则:

RewriteEngine On

RewriteRule ^([\w-]+)/([0-9]+)/?$ /product.php?id=$2&pn=$1 [L,NC,QSA]

这将支持URI结构为:
/productname/123
,在内部重写为
/product.php?id=123&pn=productname

您是否了解,如果您想使用这些短URL,您必须更改脚本,因为您无法获得id?@user4035是的,我知道这一点。但我不确定该怎么做,因为我是根据ID查看类别和产品的。但为了优化,我需要在其中包含名称。对于您想要的URL:
www.xxxxx.com/the_product/
您希望它被改写成什么?@anubhava我的目标是让它成为您所写的内容。目前是:www.xxxxxx.com/id/xxxx/x/x/the_product/I了解您想要的漂亮URL,即
www.xxxxx.com/the_product/
,但您希望它在内部变成什么?您是否了解,如果您想使用这些短URL,您必须更改脚本,因为您无法获得id?@user4035是的,我知道这一点。但我不确定该怎么做,因为我是根据ID查看类别和产品的。但为了优化,我需要在其中包含名称。对于您想要的URL:
www.xxxxx.com/the_product/
您希望它被改写成什么?@anubhava我的目标是让它成为您所写的内容。目前它是:www.xxxxxx.com/id/xxxx/x/x/the_product/I了解您想要的漂亮URL,即
www.xxxxx.com/the_product/
,但您希望它在内部成为什么?主类别和子类别在某些地方具有相同的id,因此自动递增。产品列表基于商品编号(唯一),无自动递增。当然,所有产品都有唯一的名称,因为我没有两次使用相同的产品。但基本上你的意思是,我应该将所有产品数据、主类别数据和子类别数据移动到index.php中,并在该文件中进行检查以获得我想要的效果?我实际上可以更改类别,使数据库中具有不同的id,以使所有内容都是唯一的。但是我遇到的问题是,我使用一个get变量来收集ID,
.com/ID/主类别和子类别在某些地方具有相同的ID,因此自动递增。产品列表基于商品编号(唯一),无自动递增。当然,所有产品都有唯一的名称,因为我没有两次使用相同的产品。但基本上你的意思是,我应该将所有产品数据、主类别数据和子类别数据移动到index.php中,并在该文件中进行检查,以获得des