我正在構建一個簡單的 PHP 路由器,除了“.htaccess”檔案中的內容外,我了解大多數內容。如果我注釋掉“.htaccess”檔案中的內容,沒有任何變化,或者我沒有注意到任何變化(“.htaccess”檔案的內容來自教程)。“.htaccess”檔案包含以下內容
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(. )$ index.php [QSA,L]
這是 index.php 中的內容
$request = $_SERVER['REQUEST_URI'];
switch ($request) {
case '/ROUTER/index.php':
case '/ROUTER/index.php/home':
require __DIR__ . '/controller/homeController.php';
break;
case '/ROUTER/index.php/about' :
require __DIR__ . '/controller/shopController.php';
break;
default:
http_response_code(404);
require __DIR__ . '/controller/404Controller.php';
break;
}
homeController.php 等檔案中的內容只是帶有文本的簡單回顯。也許有人可以向我解釋“.htaccess”檔案中發生了什么。
uj5u.com熱心網友回復:
大多數 Web 服務器都有這樣的邏輯來確定要服務的檔案:
- 如果存在檔案名與 URL 路徑匹配的檔案,請使用該檔案
- 如果存在名稱與 URL 路徑匹配的目錄:
- 如果該目錄中存在默認檔案(通常為
index.html或index.php),請使用該檔案 - 如果配置為顯示檔案串列,請執行此操作
- 如果該目錄中存在默認檔案(通常為
否則,Web 服務器會回傳錯誤狀態。
許多 Web 應用程式希望實作自己的邏輯來顯示每個 URL 的內容并實作自己的路由規則。它們通常用于.htaccess創建一個前端控制器,該控制器將幾乎每個請求都傳遞到一個中央檔案中,該檔案處理它自己的 Web 應用程式路由。您.htaccess有相當標準的前端控制器規則,可以將大多數 URL 傳遞到index.php
逐行分解:
RewriteEngine On-- 啟用mod rewrite,這是一個 Apache 模塊,它使用規則來更改哪些檔案處理哪些 URLRewriteBase /-- 指定規則相對于哪個目錄。這通常可以省略,因為它是檔案根目錄中/的默認值。.htaccess請參閱RewriteBase 做什么以及如何使用它?RewriteCond %{REQUEST_FILENAME} !-d-- 如果請求的 URL 不是現有目錄RewriteCond %{REQUEST_FILENAME} !-f-- 如果請求的 URL 不是現有檔案RewriteRule ^(. )$ index.php [QSA,L]- 處理所有帶有index.php.- 重寫規則包含三個部分:
- 與 URL 路徑匹配的模式 (
^(. )$)^是以.一個或多個任意字符$是結束于()括號將匹配的字符捕獲為變數 ( ) 中可用的組$1。可以洗掉此規則中的括號,因為該變數從未使用過。
- 與 URL 路徑匹配的模式 (
- 處理 URL 的目標檔案 (
index.php) - 修改規則作業方式的標志 (
[QSA,L])QSA是查詢字串追加以確保index.php可以訪問?URL 中的任何內容L是最后一個,這樣以后的任何重寫規則都不會被執行。
- 重寫規則包含三個部分:
實際上,它對存在的檔案或目錄使用默認的 Web 服務器邏輯,但將所有其他請求傳遞給index.php.
uj5u.com熱心網友回復:
@StephenOstermiller 的回答.htaccess在描述檔案/前端控制器程序方面做得很好,但我想我會解決你提出的另一個問題......
如果我注釋掉“.htaccess”檔案中的東西,沒有任何改變
那是因為您使用的 URL 的格式(例如。/ROUTER/index.php/home)完全不需要.htaccess檔案開頭。您index.php直接在 URL 本身中呼叫(“前端控制器”)并/home作為附加路徑名資訊(又名路徑資訊)傳遞。
該.htaccess檔案仍在處理中,但檢查請求未映射到物理檔案的第二個條件(指令)失敗(是物理檔案),因此不會觸發規則(它什么也不做)。RewriteCondindex.php
URL 上的附加路徑資訊可用于$_SERVER['PATH_INFO']超全域中的 PHP。因此,如果您使用表單的 URL,/ROUTER/index.php/home那么您可以像這樣(簡化)撰寫您的前端控制器(index.php):
// URLs of the form "/ROUTER/index.php/home"
$request = $_SERVER['PATH_INFO'];
switch ($request) {
case '':
case '/home':
:
case '/about' :
:
}
(如上所述,這不是使用.htaccess)
另一方面,您的.htaccess檔案允許您擁有表單/ROUTER/home(或簡稱/home)的 URL,避免您必須包含index.php在 URL 中,然后在內部將其重寫為index.php(通過規則 in .htaccess)。然后,您使用$_SERVER['REQUEST_URI'](如在您的原始腳本中)訪問 PHP 中請求的 URL。
例如(簡化):
// URLs of the form "/ROUTER/home"
$request = $_SERVER['REQUEST_URI'];
switch ($request) {
case '/ROUTER/':
case '/ROUTER/home':
:
case '/ROUTER/about' :
:
}
但是,您的現有.htaccess檔案沒有為此正確配置。該.htaccess檔案假設index.php位于檔案根目錄中,但您的 URL 表明您有一個/ROUTER子目錄,index.php(“前端控制器”)位于其中。
如果您的.htaccess檔案位于/ROUTER子目錄中,/ROUTER/.htaccess則完全洗掉該RewriteBase指令。
但是,如果您的.htaccess檔案位于檔案根目錄中,那么您需要將RewriteBase指令更改為:
RewriteBase /ROUTER
(兩種RewriteBase /ROUTER情況下的設定也可以。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/421719.html
標籤:
