使用 mod_rewrite 还是像 PHP 这样的语言来处理友好/干净/漂亮的 URL 更好?
我正在开发我的第一个像样的 PHP 网站,我对处理应用程序中干净/友好/漂亮的 URL 的“正确方法”(假设曾经有这样的事情)有点困惑。
在我看来,有两个主要选项(我将使用简化的社交新闻网站作为示例):
1. 使用 mod_rewrite 处理所有潜在的 URL。这看起来与以下类似,但不完全相同:
RewriteRule ^article/?([^/]*)/?([^/]*)/?([^/]*) /content/articles.php?articleid=$1&slug=$2
RewriteRule ^users/?([^/]*)/?([^/]*) /content/users.php?userid=$1&username=$2
RewriteRule ^search/?([^/]*)/? /content/search.php?query=$1
2. 将所有内容传递给某个处理程序脚本,并让它处理细节:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) handler.php?content=$1
显然,这都是未经测试的“空中代码”,但您明白了。
- 这两种方法中的一种会比另一种慢很多吗?据推测 mod_rewrite 速度较慢,因为我将被迫为此使用 .htaccess 文件。
- 这两种方法有严重的缺点吗?
- 这类事情是否有“最佳实践”,或者每个开发人员倾向于自己决定?我知道 WordPress 使用选项二(尽管当我确切调查他们是如何做到这一点时,这比它值得的麻烦更多)。
I'm developing my first decent-sized PHP site, and I'm a bit confused about what the "right way" (assuming there ever is such a thing) to handle clean/friendly/pretty URLs in the application.
The way I see it, there are two main options (I'll use a simplified social news site as an example):
1. Use mod_rewrite to handle all potential URLs. This would look similar, but not identical, to the following:
RewriteRule ^article/?([^/]*)/?([^/]*)/?([^/]*) /content/articles.php?articleid=$1&slug=$2
RewriteRule ^users/?([^/]*)/?([^/]*) /content/users.php?userid=$1&username=$2
RewriteRule ^search/?([^/]*)/? /content/search.php?query=$1
2. Pass everything to some handler script and let it worry about the details:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) handler.php?content=$1
Clearly this is all untested "air code," but you get the point.
- Is one of these two ways going to be seriously slower than the other? Presumably the mod_rewrite is slower, since I'll be forced to use .htaccess files for this.
- Are there serious disadvantages to either of these approaches?
- Is there a "best practice" for this sort of thing, or is it something that each developer tends to decide for themselves? I know WordPress uses option two (though it was more trouble than it was worth when I investigated exactly how they did it).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
选项 1(.htaccess 和几个 .php 文件)“过去”经常使用;现在,我看到选项 2(每个请求都通过一个 .php 文件)使用了更多。
我认为选项 2 的主要优点是:
index.php
进行:如果您需要为所有请求执行一些代码,请将其放在那里,并且您确信它总是会被执行。几年前,我会选择选项 1;现在我使用 MVC 和框架,我总是选择选项 2。
Option 1 (.htaccess and several .php files) was often used "in the past" ; now, I see option 2 (every request going through one .php file) used a lot more.
The main advantages I see with option 2 are :
index.php
: if you need some code executed for all requests, put it there, and you're sure it'll always be executed.A couple of years ago, I would have gone with option 1 ; now that I use MVC and Frameworks, I always go with option 2.
这确实是“框架值得使用吗?”变相的提问。
使用 mod_rewrite 定义 URL 路由既快速又简单(如果您了解正则表达式...),但您的应用程序代码不会注意到 URL,除非您在某处复制信息。
通常,人们会在不假思索的情况下多次复制此信息,通过在视图中的链接或重定向中对 URL 进行硬编码。这确实很混乱,有一天当您决定在开发过程中更改网站的 URL 结构时,这会带来痛苦。您肯定会错过一个并最终在某个地方得到 404。
在应用程序中使用路由组件(例如 Symfony) 意味着您可以将名称附加到您的路由,允许您定义一次 URL 并多次重复使用它们:
这使得链接到您网站的页面变得非常容易,而无需重复自己:
Really this is the "are frameworks worth using?" question in disguise.
Using mod_rewrite to define your URL routes is quick and easy (if you understand regular expressions...) but your application code is oblivious to the URLs unless you duplicate the information somewhere.
Usually, people duplicate this information many times without thinking about it, by hard-coding URLs in the links in their views, or in redirects. This is really messy, and will one day cause pain when you decide to change the URL structure of your site halfway through development. You're bound to miss one and end up with a 404 somewhere.
Using a routing component in your application (such as the one in Symfony) means you can attach names to your routes, allowing you to define your URLs once and re-use them many times:
This makes it really easy to link to pages of your site without repeating yourself:
使用选项 #2 - 为什么?
.htaccess
中的 RewriteRules 是强大的工具,但它们是某种静态。我的意思是你无法轻松地使用 PHP(或任何你将要使用的)进行管理。此外,.htaccess
并没有提供太多的灵活性,但有一些优点(例如:它更快一点)。如您所见,选项 #2 也需要
.htaccess
,但在大多数情况下RewriteRule
采用以下形式:其中
index.php
是您的前端控制器。这种灵魂的最大优点(IMO)是每条路线都是用 PHP(或您使用的任何东西)描述的,因此访问这些路线、修改它们要容易得多。此外,这些路由不仅可以用于将 URL 更改为变量集,还可以以相反的方式使用 - 从变量集创建 URL。
我认为下面的示例(来自 Symfony 框架)将解释我正在谈论的内容:
现在,每当您更改
routing.yml
文件并更改/read/:id/:slug
到/:slug_:id
应用程序中的所有链接都将变成/my-first-blog-post_123.html
。当您使用选项 #2 时,做这样的事情和其他事情会容易得多。
Use option #2 - why? RewriteRules in
.htaccess
are powerful tool, but they're some kind of static. I mean you cannot easily manage then using PHP (or whatever you're going to use). Also.htaccess
doesn't provide so much flexibility, but has some advantages (for example: it's a bit faster).Option #2 also need
.htaccess
as you noticed, but in most casesRewriteRule
takes the following form:Where
index.php
is your front controller.The biggest advantage (IMO) of this soultion is that each route is described in PHP (or whatever you use) so accessing these routes, modifying them is much easier. Furthermore these routes can be used then not only for changing URL into set of variables, but also in opposite way - to create URL from set of variables.
I think the following example (from Symfony framework) will explain what I am talking about:
Now whenever you change your
rounting.yml
file and change/read/:id/:slug
into/:slug_:id
all your links in application will turn into/my-first-blog-post_123.html
.Doing such and others things when you use option #2 is much easier.
据我所知,这些方法之间任何可能的性能差异都非常微小,并且仅与真正非常高流量的网站相关。
我认为不存在“最佳实践”,这两种方法同样经常使用。如果您的项目结构允许,并且您更擅长在 PHP 中解析 URL(项目的其余部分所在),请将所有内容都通过一个控制器文件,然后让您的应用程序处理其余部分。
如果性能真的很重要,我怀疑让 Apache 处理地址会更快,因为中间没有解释语言。 (不过,我没有这方面的硬数据)。但正如我所说,您可能最好选择从长远来看最适合您维护的那个。
As far as I can see, any possible performance differences between those methods are really minuscule and relevant only for really, really high-traffic sites.
I think there is no "best practice" as such, both methods are equally often used. If your project structure allows it, and you're more at home with parsing the URL in PHP (where the rest of your project is), put everything through one controller file, and let your application handle the rest.
If performance is really of the essence, I suspect that having Apache handle the addresses is faster, because there is no interpreted language in between. (I have no hard data for this, though). But as I said, you're probably best of choosing whichever is going to be most maintainable for you in the long term.
干净漂亮的 URL 似乎是由基于 PHP 脚本的流行内容管理系统 Drupal 使用 .htaccess 中的 modrewrite 规则和插件 PHP Drupal 模块(例如 path 和 pathauto)的组合来提供的。
鉴于此工具的成功和流行 - 以及它在最适度的共享托管上运行的能力,我认为这将是您的答案。
Clean pretty URLs appear to be provided by PHP-script-based popular content management system Drupal using a combination of modrewrite rules in .htaccess and plug-in PHP Drupal modules such as path and pathauto.
Given the success and popularity of this tool - and its ability to run on the most modest of shared hosting, I think this would be your answer.