为了更彻底地解决您的问题,我想暂时将您的注意力从 Web 服务器转移到 HTTP 协议及其基本工作原理上。
HTTP 是一个非常简单的协议,由请求-响应模型组成。客户端(基本上是用户的浏览器)发送所谓的 HTTP 请求标头,该标头可能具有也可能不具有非空 HTTP 请求正文。当您想访问像https://stackoverflow.com/questions/tagged/url+php这样的 URL 时,标题看起来像这样
GET /questions/tagged/url+php HTTP/1.1
Host: stackoverflow.com
Connection: keep-alive
请注意,在您的浏览器为了发送到 stackoverflow 服务器而制定的 HTTP 请求标头的第 1 行上,整行由 3 个非常简单的部分组成。
- 请求动词,通常类似于 GET 或 POST(但也可以是许多其他的东西)。这告诉服务器您希望如何处理请求,以便它期望它响应。
- 请求路径,可以由主机愿意接受的任何路径加上客户端希望提供的任何可选查询字符串组成,通常需要进行URL编码。
- 发出请求的协议版本。这通常是 HTTP/1.1 或 HTTP/1.0。
此请求的第二行向服务器提供客户端打算通过此请求访问的主机名。
现在,在服务器端,一旦您的 Web 服务器收到此实际请求,它就可以选择处理该请求,但它可以随心所欲。但是,在任何常见的 apache/nginx/lighttpd Web 服务器设置中,您可能非常习惯的行为是客户端提供的路径必须与文档根目录中的物理路径匹配。这远非真相。这只是您的 Web 服务器可以处理请求的一种方式。您可以选择告诉您的 Web 服务器以不同的方式处理每个请求。
例如,Apache 的 httpd Web 服务器提供 mod_rewrite,它可以告诉您的 Web 服务器重写请求 URI,以便服务器可以根据特定规则(例如正则表达式或给定条件集)将它们重定向到其他地方。
<Directory />
Options -Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
Allow from all
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</Directory>
以上是 WordPress 重写规则的一个非常简单的示例,它们通常为您提供一个 in .htaccess 文件,但我是从我的虚拟主机文件中获取的,这通常比使用 .htaccess 快得多。Directory
在您决定使用 .htaccess 之前,请务必先考虑将您想要放入 .htaccess 的任何内容放入您的 apache.conf 的 vhost指令中,因为它们是运行时文件,因此本质上比较慢。一般来说, mod_rewrite 本身很慢,只能作为最后的手段使用。
在任何情况下,所有这些重写的东西都会重定向到该虚拟主机根目录上的网络服务器的任何请求,DocumentRoot
以重定向到您的 index.php 文件,然后该文件在内部处理该请求以确定它应该包含哪些 PHP 脚本此请求以及页面将如何呈现。
这只是穷人的做法。它通常被称为前端控制器或前端路由器。它只是充当请求 URI 和我们处理为任何给定请求 URI 呈现响应的实际方式之间的中间人。
如果您是 stackoverflow 或 google,您将拥有反向代理(基本上是负载平衡器),它们在更高级别处理这些请求,并连接到数据中心中的其他服务器,然后这些服务器将根据该请求 URI 处理请求的呈现。
请记住,我们所做的只是获取GET /questions/tagged/url+php HTTP/1.1
客户端的HTTP 请求标头的一部分并将其发送到另一个知道如何响应它的脚本或程序。就像您的网络服务器可以为您做的一样。