合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
## laravel + nginx 伪静态分析 ### Nginx 伪静态配置分析 假设你在 Nginx 中有如下配置: ~~~ location / { try_files $uri $uri/ /index.php?$query_string; } ~~~ **步骤分析:** 1. **访问 `/api/status?query=example`:** * Nginx 首先会尝试查找 `$uri`,即 `/api/status` 这个文件或目录。如果这个路径上没有物理文件或目录存在,Nginx 会继续下一步。 2. **尝试 `$uri/`:** * 接着 Nginx 会尝试查找 `/api/status/` 目录。如果这个目录也不存在,Nginx 会继续下一步。 3. **匹配到 `/index.php?$query_string`:** * 如果前两步都没有找到资源,Nginx 最终会将请求转发给 `/index.php`,并附带上查询字符串 `?query=example`。 最终相当于请求被转发为: ~~~ /index.php?query=example ~~~ 这时,Nginx 仍然保持原始的请求 URI `/api/status`,并将查询字符串 `query=example` 传递给 PHP-FPM 去处理。 ### Laravel 如何获取到 `/api/status` Laravel 使用 `index.php` 作为单一入口文件,所有的 HTTP 请求都会通过 `index.php` 进入 Laravel 的处理流程。即使 Nginx 最终将请求转发给 `/index.php`,Laravel 依然能够知道原始的请求 URI `/api/status`。 Laravel 通过 PHP 的 **`$_SERVER`** 全局变量获取请求信息。 #### 关键点: 1. **`$_SERVER['REQUEST_URI']`**: * 即使 Nginx 将请求重写为 `/index.php?query=example`,PHP 的 `$_SERVER['REQUEST_URI']` 变量仍然会包含原始的 URI `/api/status`,因为 Nginx 并没有修改实际的请求 URI,而是只是内部重写了请求路径。 * 因此,`$_SERVER['REQUEST_URI']` 的值是 `/api/status?query=example`,Laravel 可以通过这个变量获取到完整的请求路径。 2. **Laravel 路由解析**: * Laravel 的路由系统会根据原始的请求 URI `/api/status` 来匹配定义的路由。Laravel 不关心 Nginx 如何将请求转发到 `index.php`,它只会使用 `$_SERVER['REQUEST_URI']` 中的路径部分来解析和匹配路由。 * 在 Laravel 中,你可能定义了类似的路由: ~~~ Route::get('/api/status', 'ApiController@status'); ~~~ 当 Laravel 解析 `$_SERVER['REQUEST_URI']` 得到 `/api/status`,它会根据这个路径匹配到对应的路由,并调用相应的控制器方法。 3. **查询字符串处理**: * 查询字符串 `query=example` 会被 PHP 自动解析并存放在 `$_GET['query']` 变量中,Laravel 也会通过其请求对象 (`Request` 类) 获取到查询参数。你可以通过 Laravel 的 `Request` 对象轻松获取查询字符串: ~~~ $query = $request->query('query'); // 获取 'query' 参数的值 ~~~ ### 总结 1. **Nginx 伪静态处理**:Nginx 使用 `try_files $uri $uri/ /index.php?$query_string;` 来处理静态文件请求。如果找不到文件或目录,就将请求转发给 `/index.php`,同时保留原始的请求 URI 和查询字符串。 2. **Laravel 如何获取 `/api/status`**:虽然 Nginx 将请求转发给了 `/index.php`,但 Laravel 会通过 PHP 的 `$_SERVER['REQUEST_URI']` 获取到原始的请求 URI `/api/status`,并通过它的路由系统进行匹配。 3. **查询参数**:查询字符串 `?query=example` 会由 PHP 自动解析,Laravel 可以通过 `Request` 类轻松获取查询参数。 因此,即便 Nginx 最终转发到 `/index.php?query=example`,Laravel 仍然通过 PHP 的 `$_SERVER['REQUEST_URI']` 获取并处理原始的 `/api/status` 请求路径,并且可以处理查询参数