如何在 PHP 中实现 Django 和 RoR 使用的 URL 模式解释器

发布于 2024-07-07 09:53:57 字数 1270 浏览 12 评论 0原文

实现 URL 解释器/调度程序的最佳方法是什么,例如在 Django 和 RoR,用 PHP 实现?

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

  • /users/show/4 映射到
    • 区域 = 用户
    • 操作 = 显示
    • Id = 4
  • /contents/list/20/10 映射到
    • 面积 = 内容
    • 操作 = 列表
    • 开始 = 20
    • 计数 = 10
  • /toggle/projects/10/active 映射到
    • 操作 = 切换
    • 区域 = 项目
    • id = 10
    • 字段 = 活动

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

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

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

What's the best way to implement a URL interpreter / dispatcher, such as found in Django and RoR, in PHP?

It should be able to interpret a query string as follows:

  • /users/show/4 maps to
    • area = Users
    • action = show
    • Id = 4
  • /contents/list/20/10 maps to
    • area = Contents
    • action = list
    • Start = 20
    • Count = 10
  • /toggle/projects/10/active maps to
    • action = toggle
    • area = Projects
    • id = 10
    • field = active

Where the query string can be a specified GET / POST variable, or a string passed to the interpreter.

Edit: I'd prefer an implementation that does not use mod_rewrite.

Edit: This question is not about clean urls, but about interpreting a URL. Drupal uses mod_rewrite to redirect requests such as http://host/node/5 to http://host/?q=node/5. It then interprets the value of $_REQUEST['q']. I'm interested in the interpreting part.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

壹場煙雨 2024-07-14 09:53:58

如果合适,您可以使用 MVC 框架中已有的框架。

查看以下项目(排名不分先后):Zend Framework、CakePHP、Symfony、Code Ignitor、Kohana、Solar 和 Akelos。

If appropriate, you can use one that already exists in an MVC framework.

Check out projects such as -- in no particular order -- Zend Framework, CakePHP, Symfony, Code Ignitor, Kohana, Solar and Akelos.

披肩女神 2024-07-14 09:53:58

以 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>

这会捕获像 /en/foo /de/foo 这样的 url,并使用 GET 将它们传递到 index.php参数“lang”和“url”。 可以对“项目”、“行动”等进行类似的操作

have a look at the cakephp implementation as an example:

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

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

You could also do something with 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>

This would catch urls like /en/foo /de/foo and pass them to index.php with GET parameters 'lang' amd 'url'. Something similar can be done for 'projects', 'actions' etc

長街聽風 2024-07-14 09:53:58

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

Why specifically would you prefer not to use mod_rewrite? RoR uses mod_rewrite. I'm not sure how Django does this, but mod_php defaults to mapping URLs to files, so unless you create a system that writes a separate PHPfile for every possible URL (a maintenance nightmare), you'll need to use mod_rewrite for clean URLs.

她比我温柔 2024-07-14 09:53:58

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

What you are describing in your question should actually be the URL mapper part. For that, you could use a PEAR package called Net_URL_Mapper. For some information on how to use that class, have a look at this unit test.

海未深 2024-07-14 09:53:58

我这样做的方法非常简单。
我使用 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);  

希望这有帮助!

The way that I do this is very simple.
I use wordpress' .htaccess file:

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

What this .htaccess does is when something returns a 404, it sends the user to index.php.

In the above, /index.php is the "interpreter" for the URL.
In index.php, I have something along the lines of:

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

The second line splits up the URL into sections based on "/". You can have

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

What I end up doing is:

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);  

Hope this helps!

冰魂雪魄 2024-07-14 09:53:58

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

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

Just to second @Cheekysoft's suggestion, check out the Zend_Controller component of the Zend Framework. It is an implementation of the Front Controller pattern that can be used independently of the rest of the framework (assuming you would rather not use a complete MVC framework).

And obviously, CakePHP is the most similar to the RoR style.

长伴 2024-07-14 09:53:58

我正在做一个 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() 测试页来查看底层内容。

希望这可以帮助。

I'm doing a PHP framework that does just what you are describing - taking what Django is doing, and bringing it to PHP, and here's how I'm solving this at the moment:

To get the nice and clean RESTful URLs that Django have (http://example.com/do/this/and/that/), you are unfortunately required to have mod_rewrite. But everything isn't as glum as it would seem, because you can achieve almost the same thing with a URI that contains the script's filename (http://example.com/index.php/do/this/and/that/). My mod_rewrite just forwards all calls to that format, so it's almost as usable as without the mod_rewrite trick.

To be truthful, I'm currently doing the latter method by GET (http://example.com/index.php?do/this/and/that/), and fixing stuff in case there are some genuine GET variables passed around. But my initial research says that using the direct slash after the filename should be even easier. You can dig it out with a certain $_SERVER superglobal index and doesn't require any Apache configuration. Can't remember the exact index off-hand, but you can trivially do a phpinfo() testpage to see how stuff look like under the hood.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文