关于.htaccess和友好的网址的几个问题

时间:2011-08-18 03:59:53

标签: php apache .htaccess friendly-url seo

我一直很擅长使用apache并使用非常简单的解决方案。现在我已经构建了一个cms软件..但是.htaccess开始变得非常小。

我将首先解释一下,我的友好网址是如何运作的。我的语言切换是基于网址的,并且始终包含两个字符。它看起来像这样: stackoverflow.com/en / 这使得切换非常简单,并且因为它基于URL ...它在SEO术语中运行良好。此外,如果未设置language-id,则将使用默认语言(stackoverflow.com/) 数字中没有page-id。我在文本中有唯一的页面ID: stackoverflow.com/services.html 以及SEO和文件夹目录 - 反冲突目的.html结尾..
对于子页面,我有“$ current_page”和“$ parent_page”样式变量: stackoverflow.com/services/translating.html 作为父级的服务和翻译为当前页面。
一些示例代码也是如此(我非常紧张,所以你不认为它不完整):

RewriteRule ^(et|en|fi)\/(.+)\/(.+)\.html  index.php?language=$1&pagelink=$3&parentlink=$2 [L,NC,QSA]

RewriteRule ^(.+)\/(.+)\.html  index.php?language=0&pagelink=$2&parentlink=$1 [L,NC,QSA]
RewriteRule ^(.+)\.html  index.php?language=0&pagelink=$1&parentlink=0 [L,NC,QSA]

如何让语言切换部分更具动态性?
这个方法..^(et|en|fi)\/..意味着,当我设置cms时,我必须手动设置语言列表。最好的选择是从cms设置以某种方式设置它。因为这种方式没有与文件夹相关的冲突。是否有可能通过php进行全局快速变量,然后将其显示为.htaccess文件?这样的事情:..^(LANGUAGELISTS)\/..?如果这是不可能的,那么接下来最好的方法是匹配该位置的2个字符并将其作为$_GET['language']传递。

我如何动态拥有无限的父母?
这意味着,“$ parent_page”没有静态设置,我有无限的孩子​​,类似于: stackoverflow.com/services/translating/english/somesubpage.html 。如果可能,那么,如何在php中使用数组?

赏金编辑
问题的第一部分基本上解决了,除非有人想出一些php - > apache-array - > .htaccess方式。
但是,问题的第二部分仍未解决。由于这是我所有项目的问题,未来可能会帮助其他人,我决定为这个问题增加赏金。

5 个答案:

答案 0 :(得分:2)

回答你的第一个问题: 你可以使用RewriteRule ^([a-zA-Z]{2})([/]?)(.*)$ path/file.php?language=$1 这会将第一个字符串限制为两个字符,并将其传递给$_GET['language']

修改:添加RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-d将防止与现有目录/文件的冲突

第二个问题要困难得多......

<强>更新

在我看来,Shad和toopay所说的是一个良好的开端。 使用explode()分隔级别并将其与slug进行比较非常简单。 但是,一旦你想为脚本增加灵活性,它就会变得复杂。

function get_URL_items() {
$get_URL_items_url = $_SERVER['REQUEST_URI'];
$get_URL_items_vars = explode("/",$get_URL_items_url);
for ($get_URL_items_i = 0; $get_URL_items_i < count($get_URL_items_vars) ; $get_URL_items_i++) {
    if(strlen(trim($get_URL_items_vars[$get_URL_items_i])) == 0) {
        unset($get_URL_items_vars[$get_URL_items_i]);
    }
}
return $get_URL_items_vars;

假设您有一个名为“Festival”的子网站和一个包含100多位艺术家信息的数据库,您希望自己的网址看起来像website.com/festival/<artistgenre>/<artistname>/。 您不希望在CMS中创建100多个网页,因此<artistgenre><artistname>是某种通配符。

如果没有很多if / else语句,我发现很难实现这个目标,如:

$item = get_URL_items();    
if(is_user($item[2]) && is_genre($item[1]) && is_festival($item[0])) {
  // do mysql stuff here
}

答案 1 :(得分:1)

如果我是你,我会使用这样的东西:

htaccess的:

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !/main.php$
RewriteRule ^([a-zA-Z]{2})?(.*)$ main.php?lang=$1&path=$2 [L,QSA]

main.php:

$langs = array('en','de','ru'); // list of supported languages
$currentLang = isset($_GET['lang'])&&in_array($_GET['lang']) ? $_GET['lang'] : $defaultLang; // current selected language
$path = $_GET['path']; // current path

然后,在main.php中,您可以根据需要解析路径

答案 2 :(得分:1)

在回答您的bounty问题时,我会用这个:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Z]{2}\/)*(([A-Z]+\/)*)([A-Z]+)\.html$ index.php?lang=$1&parents=$2&pagelink=$4 [NC,QSA,L]

由于您希望能够在URL中处理任意数量的代/级别,您是否考虑过如何在PHP脚本中捕获它们?

你绝对不想去检查isset($_GET['parent1']);isset($_GET['parent2'])等等等。

正如其他一些回复所指出的那样,你真的需要在PHP脚本中解析你的URL;为此,我的RewriteRule移除了URL的整个“父母”部分,然后您的脚本可以explode并解析;但不会干扰正常的无父母网址。 =)

答案 3 :(得分:1)

我不知何故认为这个答案不会很受欢迎,但无论如何都会这样。 :)

mod_rewrite达到了一个使用它的方式,正统表达式的老式方式变得烦人。我建议你跳过所有的痛苦并交换使用外部程序/脚本来重写。我不建议您使用此方法重写所有文件,而只是针对大多数用户将看到并键入的URL。只要您知道如何编写高效的代码,您甚至可以重定向到PHP脚本来执行重写(正如我过去在非常高流量的站点上所做的那样)并且它不会对加载时间产生明显影响。如果你曾经达到重写是减慢网站速度的主要因素,你可以将其切换为用更快的语言编写的程序,但是如果你达到这个目标我会感到惊讶。

有些事情要注意:

  • 你需要设置一个重写锁定指令,否则你会得到很多疯狂的输出。
  • 请记住,重写脚本是命令行 PHP脚本。它不知道诸如$ _SERVER全局之类的东西。这很容易让人忘记。
  • 此脚本在服务器启动时加载,因此对其进行的任何更改都需要服务器重新启动才能生效。
  • 始终在命令行上通过传递url并在重新启动服务器之前检查输出来对此进行测试。如果您的脚本中断,重新启动服务器将导致从无法正常重写到服务器的任何内容都无法启动。

一开始有点麻烦,但是一旦你设置了它,你会发现添加新的重写规则是一个绝对的微风和一个更灵活的地狱。

这是我能够找到的关于如何使用PHP ...

的唯一教程

Using MySQL to control mod_rewrite via PHP

这远远不是重写的标准方式,所以我想我会为这个答案付出很大的代价。那好吧。 :)

答案 4 :(得分:0)

嗯,对于SEO部分,我认为最好每篇文章都有slug(引用你的是CMS用它)。在您的数据库中,您有一些“翻译”表,用于翻译请求的uri / slug并将其与$parent_page相关联。