傳統 PHP 應用常見 URL 如 index.php?module=user&action=login,不利 SEO 且語意不明。採用 PATH_INFO 可產出類似靜態頁的結構化路徑:
https://www.example.com/index.php/module/user/action/login/id/123
進一步隱藏 index.php,即可得到乾淨的 RESTful 風格 URL:
https://www.example.com/module/user/action/login/id/123
在虛擬主機或 .htaccess 中加入:
<Files "index">
ForceType application/x-httpd-php
</Files>
或針對整個目錄:
ForceType application/x-httpd-php
如此 https://example.com/index/foo/bar 會由 index(實為 PHP 腳本)處理,$_SERVER['PATH_INFO'] 為 /foo/bar。
AcceptPathInfo On
預設關閉會導致 404 錯誤。
若想要 https://example.com/app_name/my/app.html 這樣的偽靜態,可在解析 PATH_INFO 時,截斷最後 5 字元 .html:
<?php
$pathInfo = $_SERVER['PATH_INFO'] ?? '';
if (substr($pathInfo, -5) === '.html') {
$pathInfo = substr($pathInfo, 0, -5);
}
// 接著依 '/' 分割路由參數
$segments = explode('/', trim($pathInfo, '/'));
?>
RewriteEngine On
# 若請求非實體檔案/目錄,導向 index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
# 啟用 PATH_INFO(部分主機需在 httpd.conf 設定)
AcceptPathInfo On
<?php
// 統一入口 index.php
$pathInfo = $_SERVER['PATH_INFO'] ?? $_SERVER['REQUEST_URI'] ?? '';
// 移除查詢字串
$pathInfo = parse_url($pathInfo, PHP_URL_PATH);
// 移除開頭的 /index.php
$pathInfo = preg_replace('#^/index\.php#', '', $pathInfo);
// 移除 .html 結尾
$pathInfo = preg_replace('#\.html$#', '', $pathInfo);
// 分段
$segments = array_values(array_filter(explode('/', $pathInfo)));
// 簡易路由映射
$routes = [
'module' => $segments[0] ?? 'default',
'action' => $segments[1] ?? 'index',
'id' => $segments[2] ?? null,
];
// 載入對應 Controller
$controller = ucfirst($routes['module']) . 'Controller';
$action = $routes['action'] . 'Action';
if (class_exists($controller)) {
$ctl = new $controller();
if (method_exists($ctl, $action)) {
$ctl->$action($routes['id']);
}
}
?>
/assets/style.css)或使用 <base href="/">。urldecode() 處理。try_files。PATH_INFO 是 PHP 時代實現美觀、SEO 友好 URL 的經典技術,配合 ForceType 與 AcceptPathInfo On 即可輕鬆隱藏 index.php 甚至模擬靜態結尾。現代專案若採用 Laravel、Symfony 等框架,路由元件已內建更完善的解析與生成機制,建議直接使用框架提供的路由功能。