3

在 PHP中实现 URL 解释器/调度程序(例如在Django和 RoR 中找到)的最佳方法是什么?

它应该能够按如下方式解释查询字符串:

  • /users/show/4映射到
    • 面积=用户
    • 行动=展示
    • 编号= 4
  • /contents/list/20/10映射到
    • 面积=内容
    • 行动=清单
    • 开始= 20
    • 计数= 10
  • /toggle/projects/10/active映射到
    • 动作=切换
    • 面积 =项目
    • 编号= 10
    • 字段=活跃

其中查询字符串可以是指定的 GET / POST 变量,也可以是传递给解释器的字符串。

编辑:我更喜欢不使用 mod_rewrite 的实现。

编辑:这个问题不是关于干净的 url,而是关于解释一个 URL。Drupal 使用 mod_rewrite 将诸如http://host/node/5之类的请求重定向到http://host/?q=node/5。然后它解释 $_REQUEST['q'] 的值。我对口译部分很感兴趣。

4

7 回答 7

2

为什么您不希望使用 mod_rewrite?RoR 使用 mod_rewrite。我不确定 Django 是如何做到这一点的,但是 mod_php 默认将 URL 映射到文件,因此除非您创建一个系统,为每个可能的 URL 编写单独的 PHPfile(维护噩梦),否则您需要使用 mod_rewrite 来处理干净的 URL .

于 2008-10-14T16:59:22.090 回答
2

以 cakephp 实现为例:

https://trac.cakephp.org/browser/trunk/cake/1.2.xx/cake/dispatcher.php

https://trac.cakephp.org/browser/trunk/cake/1.2.xx/cake/libs/router.php

你也可以用 mod_rewrite 做一些事情:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^(.*)$ $1 [L]
    RewriteRule ^([a-z]{2})/(.*)$ $2?lang=$1 [QSA,L]
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

这将捕获 url /en/foo /de/foo,并将它们传递给 index.php,GET参数为“lang”和“url”。可以为“项目”、“行动”等做类似的事情

于 2008-10-14T15:30:15.890 回答
2

您在问题中描述的实际上应该是 URL 映射器部分。为此,您可以使用名为Net_URL_Mapper的 PEAR 包。有关如何使用该类的一些信息,请查看此单元测试

于 2008-11-29T22:29:06.710 回答
2

如果合适,您可以使用已经存在于 MVC 框架中的一个。

查看诸如 Zend Framework、CakePHP、Symfony、Code Ignitor、Kohana、Solar 和 Akelos 之类的项目(排名不分先后)。

于 2008-10-14T15:00:32.003 回答
1

我这样做的方法非常简单。
我使用 wordpress 的 .htaccess 文件:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

这个 .htaccess 所做的是,当某些东西返回 404 时,它会将用户发送到 index.php。

在上面,/index.php 是 URL 的“解释器”。
在 index.php 中,我有以下内容:

$req = $_SERVER['REQUEST_URI'];
$req = explode("/",$req);

第二行根据“/”将 URL 分成几个部分。你可以有

$area = $req['0'];
$action= $req['1'];
$id = $req['2'];

我最终要做的是:

function get_page($offset) {//offset is the chunk of URL we want to look at
    $req = $_SERVER['REQUEST_URI'];
    $req = explode("/",$req);
    $page = $req[$offset];
    return $page;
}
$area   = get_page(0);
$action = get_page(1);
$id     = get_page(2);  

希望这可以帮助!

于 2008-10-15T02:54:18.317 回答
0

为了第二个@ Cheekysoft的建议,请查看 Zend 框架的Zend_Controller组件。它是前端控制器模式的实现,可以独立于框架的其余部分使用(假设您不想使用完整的 MVC 框架)。

显然,CakePHP与 RoR 风格最为相似。

于 2008-10-14T15:04:20.403 回答
-2

我正在做一个 PHP 框架,它的功能正是您所描述的 - 将 Django 正在做的事情带到 PHP 中,这就是我目前解决这个问题的方法:

要获得 Django 拥有的漂亮而干净的 RESTful URL(http://example.com/do/this/and/that/),不幸的是,您需要_重写 mod。但一切都不像看起来那么闷闷不乐,因为您可以使用包含脚本文件名的 URI(http://example.com/index.php/do/this/and/that/)实现几乎相同的事情. 我的 mod rewrite 只是将所有调用转发到该格式,所以它几乎和没有 mod rewrite 技巧_一样可用。_

老实说,我目前正在通过 GET ( http://example.com/index.php?do/this/and/that/ ) 执行后一种方法,并修复一些东西以防传递一些真正的 GET 变量. 但我最初的研究表明,在文件名后使用正斜杠应该更容易。您可以使用某个$_SERVER超全局索引来挖掘它,并且不需要任何 Apache 配置。无法立即记住确切的索引,但是您可以轻松地做一个phpinfo()测试页来查看引擎盖下的东西。

希望这可以帮助。

于 2008-11-29T22:39:51.197 回答