必须禁用exec、system、shell_exec、passthru、proc_open、popen、dl等危险函数,关闭display_errors并启用日志记录,设置open_basedir限制文件访问范围,禁用非必需的file_uploads,并对所有外部输入进行filter_var白名单校验、数据库操作使用预处理语句、输出按上下文精准编码、凭证通过环境变量加载。

PHP安全编码规范落地不是靠贴几张文档、开几次会就能完成的事,关键在于把“原则”变成“动作”,让安全要求嵌入开发流程的每个环节。
配置层:从php.ini开始堵住基础漏洞
很多安全问题其实在项目启动前就埋下了。生产环境必须调整以下几项:
-
禁用危险函数:在 php.ini 中设
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,dl,防止命令注入和动态加载风险 -
关闭错误显示:设
display_errors = Off,同时开启log_errors = On并指定日志路径,避免敏感路径或数据库结构泄露 -
限制文件访问范围:用
open_basedir明确限定脚本可读写的根目录(如/var/www/app/),禁止跨目录遍历 -
禁用文件上传(如非必需):设
file_uploads = Off;若必须启用,配合upload_max_filesize和post_max_size做严格限制
输入处理:所有外部数据默认不可信
用户提交、API调用、第三方返回的数据,一律视为潜在攻击载荷,不能直接拼接、执行或输出。
- 用
filter_var()做白名单校验:邮箱用FILTER_VALIDATE_EMAIL,URL用FILTER_VALIDATE_URL,整数用FILTER_VALIDATE_INT - 数据库操作必须用预处理语句:PDO 或 MySQLi 的
prepare/bind_param,杜绝字符串拼接 SQL - 文件操作前验证路径:用
realpath()解析绝对路径,再检查是否落在open_basedir范围内 - 避免使用
extract()、parse_str()等自动变量导入函数,防止变量覆盖漏洞
输出控制:按上下文做精准编码
同一段数据,在 HTML、JS、URL、SQL 中的处理方式完全不同,不能“一把梭”地转义。
- 输出到 HTML 文本内容:用
htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') - 输出到 JavaScript 变量:先
json_encode($str, JSON_UNESCAPED_UNICODE),再包裹在单引号中 - 拼接到 URL 参数:用
urlencode(),不要用rawurlencode()(后者不编码斜杠) - 写入文件或日志:确保换行符、制表符等可控,避免日志伪造(Log Injection)
凭证与配置:彻底消灭硬编码
数据库密码、API密钥、加密密钥等,绝不能出现在代码或 Git 仓库中。
- 使用环境变量加载:通过
getenv('DB_PASSWORD')或$_ENV['DB_PASSWORD']读取,配合 .env 文件(被 .gitignore 排除) - 配置文件单独管理:把
config/目录排除在版本控制外,部署时由运维注入真实配置 - 敏感操作加二次确认:如后台删除、密钥重置,需输入当前密码或短信验证码
- 定期轮换密钥:对长期有效的密钥(如 JWT 签名密钥)设定生命周期,支持热切换
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











