【问题标题】:RewriteRule: trying to get rid of dashesRewriteRule:试图摆脱破折号
【发布时间】:2012-12-05 13:10:43
【问题描述】:

我正在尝试重写 URL 中的破折号,以便它们在内部不存在。例如这个网址

localhost/mysite/关于我

“about-me” 应重写为 “aboutme”。我需要这个,因为控制器类名取决于这个路由字符串,我显然不能为此使用破折号。

这是我发现的条件和规则,我认为应该符合我的需要:

# Condition is to avoid rewrite on files within specified subdirs
RewriteCond $1 !^(css|img|ckeditor|scripts)
RewriteRule ^([^-]+)-([^-]+)$ $1$2 [L]

但它似乎不起作用,因为控制器类 Aboutme 没有实例化。相反,我得到了 404 错误,而且我对名称中没有破折号的类似控制器类没有任何问题。

你能帮我解决这个问题吗?

【问题讨论】:

  • 好吧,入口文件路径是 localhost/mysite/index.php,但我已经在另一对条件规则中处理了这个:RewriteCond $1 !^ (index.php|css|img|scripts|ckeditor|robots.txt|sitemap.xml|sitemap.xml.gz) RewriteRule ^(.*)$ index.php/$1 [L]
  • - 是一个正则表达式条件,如果我没记错的话,你试过\-
  • 我也尝试使用^([^\-]+)\-([^\-]+)$^([^\-]+)-([^\-]+)$ 转义破折号,但问题仍然存在。

标签: php apache codeigniter mod-rewrite rewrite


【解决方案1】:

为什么不走路线?

$route['about-me'] = 'aboutme/index';

【讨论】:

  • 是的。这是我考虑过的一个选项,但我试图用 Apache 来做。我应该能够做到。如果我没有得到它,我会选择 Codeigniter 路线。
  • 我肯定会选择路线。当事情变得动态时特别方便,即$route['product/(:num)/([a-z]+)'] = 'product/view/$1/$2';
  • 我会听取您的建议并使用路线。无论如何,如果我们能找出我的重写规则不起作用的原因会更好。
  • 我需要弄清楚如何对 mod_rewrite 做同样的事情。我已经给你加分了。但我认为这个问题还没有解决。
  • 只是好奇:为什么你更喜欢 .htaccess 而不是 CI 路由?您希望获得什么优势?
【解决方案2】:

尝试删除 ^ 和 $

# Condition is to avoid rewrite on files within specified subdirs
RewriteCond $1 !^(css|img|ckeditor|scripts)
RewriteRule ([^-]+)-([^-]+) $1$2 [L]

【讨论】:

  • 完成了,但我遇到了同样的问题。
  • 重写规则 ([^\-]+)\-([^\-]+) $1$2 [L]
【解决方案3】:

您可以扩展路由器类。
/application/core 中创建一个名为 MY_Router.php 的文件(MY 是默认前缀)并将其复制到其中;

<?php if (! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Router extends CI_Router {

    function set_class($class) {
        $this->class = str_replace('-', '_', $class);
    }

    function set_method($method) {
        $this->method = str_replace('-', '_', $method);
    }

    function _validate_request($segments) {
        // Does the requested controller exist in the root folder?
        if (file_exists(APPPATH.'controllers/'.str_replace('-', '_', $segments[0]).'.php')) {
            return $segments;
        }
        // Is the controller in a sub-folder?
        if (is_dir(APPPATH.'controllers/'.$segments[0])) {       
            // Set the directory and remove it from the segment array
            $this->set_directory($segments[0]);
            $segments = array_slice($segments, 1);

            if (count($segments) > 0) {
                // Does the requested controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().str_replace('-', '_', $segments[0]).'.php')) {
                    show_404($this->fetch_directory().$segments[0]);
                }
            } else {
                $this->set_class($this->default_controller);
                $this->set_method('index');

                // Does the default controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php')) {
                    $this->directory = '';
                    return array();
                }

            }

            return $segments;
        }

        // Can't find the requested controller...
        show_404($segments[0]);
    }
}

这会自动为您重写 - 为 _。
如果您不想使用下划线,请更改代码以将其替换为空;
str_replace('-', '_',str_replace('-', '', 的所有出现

【讨论】:

  • 在路由中使用正则表达式不是比重写Router类更好吗? Mudshark 建议我已经使用路线。但是,如果我也能弄清楚如何使用 mod_rewrite 在 Apache 服务器中执行此操作,那就太好了。
  • 我一直使用扩展路由器类。这样,它不会决定代码部署在哪个平台上,它是自包含的。我经常需要做一些在 IIS 上的网站,所以它可以避免使用 web.config。
【解决方案4】:

这是一种使用 mod-rewrite 的方法:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI}  ^/(.*)([\w]*)-([\w]*)(.*)/?$ [NC]
RewriteRule  .* %1%2%3%4 [L,DPI]

不会重定向,但可以像这样添加R=301 [R=301,DPI,L]。

不必是about-me。可以是任何位置的任何单词对。即

localhost/mysite/about-me = .../aboutme

localhost/mysite/folder1/folder2/folder3/my-folder = .../myfolder

localhost/mysite/folder1/folder2/my-folder/folder3 = .../myfolder/...

【讨论】:

  • 在我的情况下,我只希望它只在路线段中工作,而不是在真正的子目录中。想象一下这就是我正在使用的:localhost/my-site/about-memy-site 是我的本地网站的真实目录。我只想删除像 about-me 这样的路由段中的破折号,因为它被路由到一个 php 控制器类并且它不能有任何破折号。你应该建议什么?
  • 我认为它会起作用。我的示例假定文件夹不存在,除了最后一个。我只是试图赋予算法更多的多功能性。试一试。
猜你喜欢
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
相关资源
最近更新 更多