Codeigniter 中的路由 - 自动
Posted
技术标签:
【中文标题】Codeigniter 中的路由 - 自动【英文标题】:Routes in Codeigniter - Automatically 【发布时间】:2011-11-28 22:30:36 【问题描述】:我对 Codeigniter 路由有疑问。我希望我网站上的所有注册用户都拥有自己的“目录”,例如:www.example.com/username1
、www.example.com/username2
。这个“目录”应该映射到控制器“polica”,方法“ogled”,参数“username1”。
如果我这样做,那么每个控制器都会映射到以下路由:“polica/ogled/parameter”。不行:
$route["(:any)"] = "polica/ogled/$1";
这可行,但我总是在routes.php
中手动输入信息:
$route["username1"] = "polica/ogled/username1";
如何实现自动化?
更新:
例如,我有一个名称为ads
的控制器。例如,如果你去www.example.com/ads/
会有列出的广告。如果您转到www.example.com/username1
,则会列出用户username1
的广告。还有控制器user
,profile
,latest
,...
我的当前routes.php
:
$route['oglasi'] = 'oglasi';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
我用这段代码解决了问题:
$route['oglasi/(:any)'] = 'oglasi/$1';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
问候,马里奥
【问题讨论】:
太棒了!我只是用默认控制器做到了这一点,它也可以在那里工作。 【参考方案1】:您的路线的问题在于,通过使用 :any you match, 实际上...ANY 路线,所以您几乎被困在那里。 我认为您可能有两种解决方案:
1)您可以有选择地单独重新路由所有站点控制器,例如:
$route['aboutus'] = "aboutus";
$route['where-we-are'] = "whereweare";
//And do this for all your site's controllers
//Finally:
$route['(:any)'] = "polica/ogled/$1";
所有这些路由都必须在 ANY 之前,因为它们是按照它们出现的顺序阅读的,如果你把 :any 放在开头,它会很高兴地跳过所有其余的。
评论后编辑:
我的意思是,如果你要匹配任何段,这意味着你根本不能使用任何控制器(默认情况下,第一个 URI 段),因为路由器总是会重新路由你使用你定义的法律。 为了允许 CI 执行其他控制器(不管它们是什么,我只是使用了一些常见的网页,但实际上可以是任何东西),您需要通过将它们排除在重新路由之外来允许它们。您可以通过将它们放在 ANY 规则之前来实现这一点,这样每次 CI 通过您的路由规则时,它都会首先解析您“转义”的那个,并且只有当它们与在 URL 上找到的任何内容都不匹配时,它才会继续到 :ANY 规则。
尽管如此,我知道这是一个代码冗长,但它们肯定会小于你所说的 6K。 由于我不知道您的 URL 和 Web 应用程序的实际结构,因此这是我想到的唯一解决方案。如果您提供更多信息,例如您的应用的常规网址是如何形成的,那么我可以更新我的答案
/结束编辑
这不是一个实用的解决方案,因为它需要大量代码,但如果你想要这样的设计,这是我想到的唯一方法。 此外,考虑您可以使用正则表达式作为 $route 索引,但我认为它不能在这里工作,因为您的用户名不太可能以这种方式匹配,但我只是想指出这种可能性。
或
2) 你可以稍微改变你的设计模式,并为用户名分配另一条路线,类似于
$route['user/(:any)'] = "polica/ogled/$1";
尽管如此,这将生成相当漂亮(和语义)的 URL,并且将避免转义其他路由的所有麻烦。
【讨论】:
感谢您的回复。我不能使用您的第二个解决方案,因为我的客户希望在域名后使用用户名。我不明白你的第一个解决方案。你能就我的情况向我解释一下吗?我的目标是用更少的代码解决这个问题。现在,我的routes.php
文件中有大约 6000 行 - 我不喜欢这样:/
@Puzo 我用第一个解决方案的一些解释更新了我的答案。是的,6000 条路线肯定太多了。
我更新了我的第一篇文章 - 问题.. 您需要更多信息吗?什么样的?
现在我在我的第一篇帖子中的routes.php
中有代码 - 问题。现在我无法访问控制器oglas
,我把它放在用户名规则之前..
@Puzo 抱歉迟到了。我看到你解决了你的问题。只有一件事:作为手动状态,您应该将自定义路由放在默认路由之后,因此在“default_controller”和“404_ovverride”之后。剩下的,我明白你的意思了,希望现在一切正常【参考方案2】:
查看这个: http://www.web-and-development.com/codeigniter-minimize-url-and-remove-index-php/ 其中包括自动删除 index.php/remove 1st url segment/remove 2st url sigment/routing。这对你很有帮助。
【讨论】:
【参考方案3】:我最近也在努力解决同样的问题。我以这种方式创建了一些对我有用的东西:
使用remap 方法定义一个“重定向”控制器。这将允许您将发送到控制器的请求与任何正在进行的变量字符串一起收集到一个函数中。因此,如果向http://yoursite/jeff/
或http://yoursite/jamie
发出请求,它不会点击这些方法,而是点击http://yoursite/
重映射函数。 (即使这些方法/名称不存在,即使你有一个索引函数,它也会取代它)。在 _Remap 方法中,您可以定义一个条件开关,然后该开关与您的其余代码一起使用,以您想要的任何方式重定向用户。
然后您应该将此重定向控制器定义为默认控制器,并像这样设置您的路由:
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
这起初有点问题,因为这基本上会强制一切都重新定向到这个控制器,无论如何,最终通过这个_remap
开关。
但是您可以做的是在这些路由声明之上定义您不想遵守此条件的规则/路由。
即
$route['myroute'] = "myroute";
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
我发现这会产生一个很好的系统,在该系统中,我可以拥有与定义一样多的可变用户,我可以通过一个控制器根据他们所代表的内容轻松地重定向他们。
【讨论】:
Hmm.. 所以如果我理解正确,我应该在routes.php
文件中定义我的所有控制器,然后在底部定义重定向规则?这会影响页面的性能吗?
@Puzo 阅读您的评论,这几乎就是我在回答中试图说的......
@Chamilyan 如何用路由替换 # 与 / 在 url 中【参考方案4】:
另一种方法是使用您的内部控制器声明一个数组,并将其他所有内容重定向到用户控制器,就像您在 codeigniter 的 routes.php 文件中这样:
$controllers=array('admin', 'user', 'blog', 'api');
if(array_search($this->uri->segment(1), $controllers))
$route['.*'] = "polica/ogled/$1";
【讨论】:
以上是关于Codeigniter 中的路由 - 自动的主要内容,如果未能解决你的问题,请参考以下文章
Eclipse 中的 Code Igniter 2.1 自动完成/智能感知
Laravel 自动路由,如 Codeigniter - 自定义解决方案