專業網站需提供友善的 404 頁面,既提升使用者體驗,又有利 SEO。ThinkPHP 利用「空控制器(EmptyAction)」與「空方法(_empty)」機制,可輕鬆實現全站 404 攔截。本文並補充存取安全防護建議。
檔案:Lib/Action/EmptyAction.class.php
<?php
class EmptyAction extends Action {
// 空方法:訪問不存在的控制器時觸發
public function _empty() {
header("HTTP/1.0 404 Not Found");
$this->display('empty:index');
}
// 空控制器下的 index 方法(直接訪問空控制器時)
public function index() {
header("HTTP/1.0 404 Not Found");
$this->display('empty:index');
}
}
?>
在每個控制器(或公共基底類 CommonAction)中加入:
public function _empty() {
header("HTTP/1.0 404 Not Found");
$this->display('empty:index');
}
當訪問存在的控制器但不存在的方法時,將觸發此 _empty()。
目錄:Tpl/empty/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>404 - 頁面不存在</title>
<style>body{text-align:center;padding:50px;font-family:Microsoft YaHei;}</style>
</head>
<body>
<h1>404</h1>
<p>您訪問的頁面不存在或已被移除。</p>
<a href="__APP__/">返回首頁</a>
</body>
</html>
若攻擊者猜測使用 ThinkPHP,可能嘗試直接訪問 /Public/、/Runtime/ 等敏感路徑。建議:
Lib/Action/SecureAction.class.php 作為所有控制器基底。_initialize() 中攔截可疑請求(如路徑含 ..、Runtime、Conf 等關鍵字)。SecureAction,EmptyAction 亦繼承之。class SecureAction extends Action {
public function _initialize() {
$url = $_SERVER['REQUEST_URI'];
$blacklist = array('Runtime', 'Conf', 'Lang', '.svn', '.git', '..');
foreach ($blacklist as $keyword) {
if (stripos($url, $keyword) !== false) {
header("HTTP/1.0 404 Not Found");
exit('Access Denied');
}
}
}
public function _empty() {
header("HTTP/1.0 404 Not Found");
$this->display('empty:index');
}
}
APP_DEBUG 於生產環境。open_basedir 限制 PHP 存取目錄。原文出處:尛雷博客