支持多语言的PHP路由
我目前正在框架上创建一个CMS。我有我的.htaccess文件,它看起来像这样:支持多语言的PHP路由
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z]+)/(.*)$ index.php?url=$1 [PT,L]
</IfModule>
我的问题是,认为:
1)我的页面可以与正常的MVC URL访问: http://example.com/pages/view/ {了,shorttag-的最页}
2)我的网页也与路由访问: http://example.com/p/ {的-shorttag的最页}
我真正需要实现的是,我可以访问它有两种方法:与语言支持 http://example.com/ {的-shorttag的最页} 或者 http://example.com/ {语言}/{在-shorttag的最页}
我的问题是,我不想改变mod_rewrite - 我宁愿在PHP中创建路由,但我找不到解决方案,如何路由到PageController-> view()方法,而没有在上面的示例中有一个静态字母(“p”)条件。
你明白我的问题吗? 你有一些提示,可能会导致我在正确的方向吗?
这听起来像你需要实现某种形式的路由器。
我面对我自己,这是我如何做它的工作相当不错:
有些路由器类解析URL。它将URL部分(/en/controller/action/param1/paramval1/
)分解成几部分。它决定语言代码(如果未提供,则默认),控制器,操作等。 路由器还向系统的其他部分提供信息(控制器,操作名称,参数),尽管您可以为此目的实现特殊类别(例如请求)。
现在系统的不同部分可以通过路由器或请求类访问给定的信息。从这里开始,应该很容易实现多语言网站。
再一次,重要的部分是将URL映射到控制器和操作。当然,如果你不需要像/controller/action/parameter1
这样的URL,你应该有一些映射表(XML文档/数据库表),它将一个存根(页面短标签)映射到控制器和操作。它是读取该表并根据给定规则确定控制器,操作和其他参数的路由器。
希望没有复杂太多了:)
更新:使用XML文件
至于我自己,我已经实现映射。让我进一步解释一下:路由器负责解析URL。通常情况下,您的URL将包含控制器和操作名称(在您的情况下,页是控制器,视图是操作)。
现在你的情况,你只需要一个存根,所以路由器必须以某种方式获得有关哪个控制器和动作被调用的信息。这是映射的目的,将存根映射到适当的控制器和操作。
我已经实现了这个静态路由,手动写入XML文件,但您可以例如使用某种类型的插件类来检查存根实际上是否与页面相关。如果没有,那可能意味着两件事:它是一个控制器或请求是无效的。
让我进一步讨论碰撞:如果存根与任何控制器的名称相同,就会发生碰撞。您是否应该使用给定的存根渲染页面,或者调用控制器?这需要以某种方式解决,也许你可以通过编程方式限制用户使用那种存根的页面。另外,下次你用PHP进行应用程序开发时,我建议你使用一些着名的PHP框架(如果你还没有,例如)。 Zend,Kohana或CodeIgniter。他们都提供路由器和许多其他组件,使开发应用程序变得更容易,更快速,更安全。
我这样做是通过将域后的整个字符串传递给索引页,并在php中处理它,而不是在.htaccess中处理。我不是一个.htaccess专家,但是这是为我工作:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php
我在安装时指定,如果该网站会或不会使用郎的支持,我觉得既支持在同一个站点可能很难执行。
如果您需要更多详细信息,请咨询我。
修订
丹尼斯,我读@usoban后,我可以说我有一个类似的方法。正如我所说的,我从.htaccess到我的application
类的域后获得完整路径并将其解析为数组。如果在配置中指定'多语言',我将获取第一个数组元素并为该语言加载'别名'表。
在“别名”表是一个关联数组地图别名控制器,像这样:
$lang_mods = array(
'home' => 'Home',
'contact' => 'Contact',
'sitemap' => 'Sitemap',
'about' => 'Section/about',
'terms' => 'Section/terms',
);
以这种方式,我可以有一个完全转变的URL,即:
http://www.example.com/en/contact 和: http://www.example.com/es/contacto
因此,从url数组中删除第一个语言元素后,我检查下一个元素对别名表。表中的最后两个项目是可以为了简化URL中使用的特殊情况下,收到
http://www.example.com/en/about 代替 http://www.example.com/en/section/about 看起来更好,但都指向同一个Section
控制器。
删除语言和别名后,数组中的其余元素(如果有)传递给控制器。例子中的'about'或'terms',被前置于参数数组中。根据控制器的不同,第一个参数可以是动作或不动作。
如果在此过程的某个步骤中,某些内容与允许的值不匹配,则会将其重定向到主页。
好吧,在你的情况下,也许如果第一个参数(或第二个,如果网站是多语言)可以检查可用的控制器,如果它不存在,你可以路由到一个'默认'然后检查您的数据库中可用的页面。通过这种方式,您可以避免在url中增加/p/
。
我想清楚,对不起,英语不是我的母语;)
这就是我现在要做的。我的问题是,我需要PHP代码来实现它。 我制作了一张带语言的表..如果有多种语言,那么应该有语言支持 – 2011-05-02 16:00:19
我在我的框架中完成它,但我不能给你一个简短的答案,因为我的语言支持与许多其他功能。稍后我会尽量简要介绍一下。 (对不起,我的英语) – morgar 2011-05-02 16:10:04
这听起来真的很棒!这是我在CMS中的最后一个脑袋......我真的不想让som成为“OOOPS”:P – 2011-05-02 16:10:56
最后一部分有点复杂 - 为什么我应该有一个映射数据库?这是什么目的?这是我第一次面对语言支持问题,所以它不是我最擅长的。 – 2011-05-02 16:15:28
更新了答案,更详细地解释了关于映射 – usoban 2011-05-02 18:10:26
Usoban:我现在更加注意你的想法。但是我需要提出一个小问题:这是否意味着我必须从数据库中获取所有短标签,并检查这些标签是否在URL中。如果没有,那么我应该创建一个调度程序,该路由指向控制器(如果存在)。如果这些都不存在,则转到错误页面。 这是正确的吗? – 2011-05-02 21:01:08