PHP文件包含路径不应硬编码,因硬编码与用户输入混用(如include 'templates/' . $_GET['page'] . '.php')会导致目录遍历、空字节截断等攻击;应采用白名单映射、basename过滤、绝对路径+配置常量、禁用allow_url_include,并优先使用PSR-4自动加载等结构化机制。

PHP中文件包含路径不应硬编码,所谓“硬编码实现法”不是安全做法,而是典型风险源头。真正安全的方式是避免路径由用户输入控制,同时杜绝动态拼接、禁用不受信来源、固定加载逻辑。
为什么不能硬编码包含路径?
硬编码本身不危险,危险的是把硬编码和用户输入混用——比如写成 include 'templates/' . $_GET['page'] . '.php';。这种写法看似路径前缀“硬编码”了,但整体仍是动态拼接,极易被绕过。攻击者可提交 page=../../etc/passwd%00 或利用空字节截断、目录遍历、PHP包装器(如 php://filter)读取敏感内容。
安全的路径处理方式
核心原则:路径必须完全可控、不可被用户干预。
- 用白名单映射代替字符串拼接:定义允许的页面标识与真实路径的关联数组,只从数组中取值
- 强制添加固定后缀(如
.inc.php),并在包含前用basename()提取文件名,剥离所有路径符号 - 所有包含语句使用绝对路径,且路径来自配置常量或环境变量,不拼接任何运行时变量
- 禁用
allow_url_include = Off,关闭远程文件包含能力
替代 include/require 的更安全方案
现代PHP项目应减少手动包含,转向结构化机制:
立即学习“PHP免费学习笔记(深入)”;
- 使用自动加载(PSR-4),通过类名自动定位文件,完全规避路径构造
- 将模板逻辑封装为视图类,用方法参数控制渲染内容,而非文件名
- 静态引入全部依赖:入口文件中一次性
require_once核心组件,后续不再动态决定包含什么 - 敏感功能(如配置加载)改用
parse_ini_file()或 JSON 配置 + 环境变量覆盖,不走 PHP 执行流
检查与加固要点
快速识别风险点并修复:
- 全局搜索
include(、require(、include_once(、require_once(),确认参数是否含$_、$变量或函数调用 - 检查是否有
eval(、assert(、call_user_func等执行型函数处理用户输入 - 验证
open_basedir是否启用,限制脚本只能访问指定目录树 - 日志中若记录了包含失败错误,确保不暴露真实路径信息



















