PHP上线检查清单:从开发到生产的完整安全与性能指南
目录导读
- 为什么需要PHP上线检查单?
- 环境配置检查
- PHP版本与扩展确认
- 错误报告与日志管理
- 时区与字符编码设置
- 代码安全审查
- 敏感信息泄露防护
- SQL注入与XSS过滤
- 文件上传与包含漏洞
- 性能优化检查
- Opcode缓存配置
- 数据库查询优化
- 静态资源压缩与CDN
- 部署与运维检查
- 文件权限与目录结构
- 备份与回滚策略
- HTTPS强制与CSP配置
- QA常见问题
- 上线后遇到500错误怎么办?
- 如何检测PHP代码是否存在安全漏洞?
为什么需要PHP上线检查单?
在开发环境中跑得飞快的PHP代码,一旦部署到生产服务器,可能会突然变得“不听话”,这是因为生产环境与本地环境存在本质差异:更严格的安全策略、更高的并发压力、更复杂的权限约束,一份详尽的 PHP上线检查单(PHP Deployment Checklist)可以帮助开发者系统性地排查问题,避免上线后出现500错误、性能瓶颈或安全漏洞。

核心目标:确保代码在真实生产环境中稳定、安全、高效运行。
环境配置检查
✅ PHP版本与扩展确认
- 版本一致性:确保服务器PHP版本与开发版本一致(或至少兼容),PHP 8.1废弃了某些函数(如
mysql_*)。 - 必要扩展:运行
php -m检查扩展是否安装,如PDO、mysqli、mbstring、gd、curl、openssl、json。 - 禁用危险函数:在
php.ini中禁用exec、shell_exec、system、passthru(除非必要)。
✅ 错误报告与日志管理
- 生产环境错误显示:必须关闭
display_errors,改为display_errors = Off并在php.ini中开启log_errors = On。 - 错误日志路径:确保
error_log指向可写的独立日志目录(如/var/log/php_errors.log)。 - 自定义异常处理:使用
set_error_handler()和set_exception_handler()捕获并记录未处理错误。
✅ 时区与字符编码设置
- 时区:
date.timezone = Asia/Shanghai或UTC。 - 字符集:确保数据库连接使用
utf8mb4,PHP文件保存为UTF-8 without BOM。
代码安全审查
❗ 敏感信息泄露防护
- 硬编码密钥:检查配置文件中是否存在数据库密码、API密钥、盐值(建议使用环境变量:
$_ENV['DB_PASSWORD'])。 - .git 暴露**:生产环境禁止部署
.git文件夹,并配置 Nginx/Apache 拒绝访问隐藏文件。 - 错误信息:自定义404/500页面,避免泄露文件路径。
❗ SQL注入与XSS过滤
- 参数化查询:必须使用 PDO 或 MySQLi 的预处理语句(Prepared Statements)。
// 错误示范 $sql = "SELECT * FROM users WHERE id = " . $_GET['id']; // 正确示范 $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->execute(['id' => $_GET['id']]); - 输出转义:对用户输入输出前使用
htmlspecialchars()或strip_tags()(模板引擎如 Twig 需开启自动转义)。
❗ 文件上传与包含漏洞
- 上传目录权限:上传目录设置为
755,且禁止解析PHP(Nginx 配置location ~* \.php$ { deny all; })。 - 文件类型校验:不仅检查扩展名,还验证 MIME 类型(如
$_FILES['file']['type'])和文件内容头。 - 远程文件包含:关闭
allow_url_include = Off,使用require_once(__DIR__ . '/lib/')限制路径。
性能优化检查
⚡ Opcode缓存配置
- 安装OPcache:生产环境必须启用
zend_extension=opcache.so,并设置opcache.memory_consumption=128、opcache.max_accelerated_files=4000。 - 验证缓存命中率:通过
opcache_get_status()检查misses和hits比例。
⚡ 数据库查询优化
- 慢查询日志:开启 MySQL 慢查询日志(
long_query_time=2),定位慢查询加入索引。 - 连接池与持久连接:高并发下使用
pdo_mysql的持久连接(PDO::ATTR_PERSISTENT => true)。 - 数据缓存:对高频查询使用 Redis 或 Memcached 缓存。
⚡ 静态资源压缩与CDN
- CSS/JS 压缩:使用 Gzip 压缩(Nginx:
gzip on;)。 - CDN 分发:将图片、CSS、JS 部署至 CDN,并设置
Cache-Control缓存头(如max-age=2592000)。 - PHP 输出压缩:启用
output_buffering = 4096减少碎片化。
部署与运维检查
🔒 文件权限与目录结构
- 最小权限原则:PHP文件设为
644,目录设为755,上传目录需www-data可写,但禁止执行。 - 目录分离:将
vendor、config等敏感目录放到 web 根目录外(如/var/www/project而非/var/www/html/project)。 - 配置隔离:
config.prod.php与config.dev.php分开部署。
🔒 备份与回滚策略
- 数据库备份:上线前导出一份完整 SQL 备份(
mysqldump -u root -p dbname > backup.sql)。 - 代码版本标签:使用 Git tag 标记上线版本(
git tag v1.0.0)。 - 回滚步骤:编写
rollback.sh脚本,快速恢复至上一版本。
🔒 HTTPS强制与CSP配置
- 强制HTTPS:在 Nginx 中配置
return 301 https://$host$request_uri;。 - CSP头:添加
Content-Security-Policy头(如default-src 'self'; script-src 'self' 'unsafe-inline';)。 - HSTS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;。
QA常见问题
❓ 上线后遇到500错误怎么办?
- 立即检查错误日志:
tail -f /var/log/php_errors.log。 - 确认
display_errors已关闭,若开启则直接浏览器查看错误。 - 检查文件权限:
webserver用户是否有读取/写入权限。 - 检查扩展冲突:运行
php -m对比开发环境,查看是否存在重复或缺失扩展。 - 使用分步调试:在可疑代码前后加入
error_log('XXX');记录执行过程。
❓ 如何检测PHP代码是否存在安全漏洞?
- 使用静态分析工具:
phpstan --level=9、Psalm、SonarQube。 - 运行渗透测试:工具如
WPScan(针对WordPress)、Nikto。 - 手动检查常见漏洞:
- 搜索所有
$_GET、$_POST变量是否经过过滤。 - 检查
require、include是否有动态路径拼接。
- 搜索所有
- 更新依赖库:使用
composer audit检测已知漏洞。
❓ 上线前是否需要禁用所有调试工具?
是的,必须禁用 Xdebug、Tracy、开发环境下的错误栈跟踪,同时删除所有 dump()、var_dump()、error_reporting(E_ALL) 调用,在部署脚本中加入自动删除这些调试代码的逻辑。
一份严谨的 PHP上线检查单 并非一次性的工作,而是持续迭代的流程,建议将检查单融入 CI/CD 管道,利用自动化工具(如 GitHub Actions 自动检查 PHP Lint、安全扫描、扩展依赖)减少人工遗漏。上线前的每一次细心检查,都是对用户数据和业务稳定性的负责。