如何通过.htaccess检测Smarty模板文件并跳转404页面?
解决Smarty短URL下模板不存在时跳转404页面的问题
当前基于Smarty搭建的网站配置了短URL,访问site.com或site.com/acc(对应index.tpl和acc.tpl)均正常,但访问不存在的路径(如site.com/acc1)时,Smarty直接抛出错误,无法自动跳转至404页面。以下提供两种解决方案:
方案一:在index.php中检测模板文件(推荐,适配复杂模板路径)
修改index.php代码,在调用Smarty的display方法前,先检查对应模板文件是否存在,不存在则触发404跳转:
// Load Smarty library require('smarty-4.2.0/libs/Smarty.class.php'); $smarty = new Smarty(); $smarty->setTemplateDir('templates'); $smarty->setCompileDir('templates_c'); $smarty->setCacheDir('cache'); $smarty->setConfigDir('config'); // Get page $page = (isset($_GET['page'])) ? $_GET['page'] : 'index'; // 过滤非法字符,防范路径遍历攻击 $page = preg_replace('/[^a-zA-Z0-9_-]/', '', $page); // Load PHP script for page if (file_exists('sources/'.$page.'.php')) require_once('sources/'.$page.'.php'); // 检查模板文件是否存在 $templatePath = rtrim($smarty->getTemplateDir(0), '/') . '/' . $page . '.tpl'; if (!file_exists($templatePath)) { header("HTTP/1.1 404 Not Found"); require_once('sources/404.php'); exit; } $smarty->display($page.'.tpl');
说明:
- 增加
preg_replace过滤非法字符,避免恶意用户通过路径遍历访问服务器上的其他文件 - 使用
$smarty->getTemplateDir(0)获取当前设置的模板目录,确保路径准确性,适配多模板目录场景
方案二:在.htaccess中提前检测模板文件(满足转发前检测需求)
修改.htaccess的Rewrite规则,在转发请求到index.php前,先检查templates目录下是否存在对应的.tpl文件,不存在则直接返回404:
RewriteEngine on RewriteBase / Options +FollowSymLinks Options -MultiViews Options -Indexes DirectorySlash Off # 请求非文件/目录,且对应模板不存在时,直接返回404 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{DOCUMENT_ROOT}/templates/%{REQUEST_URI}.tpl !-f RewriteRule ^(.*)\/?$ - [R=404,L] # 模板存在时,转发请求到index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)\/?$ index.php?page=$1 [QSA,NC,L] ErrorDocument 404 /sources/404.php
说明:
- 规则优先级:先判断模板不存在的情况,直接返回404;只有模板存在时才转发到
index.php - 确保服务器有权限读取
templates目录,否则规则无法生效
内容的提问来源于stack exchange,提问作者Karim
相关产品推荐
相关产品推荐

