<p>ThinkPHP 5.0.24 原生不兼容 PHP 8.1+,需针对性修补:修复 count() 对 null 校验、替换 createfunction() 为匿名函数、移除 mysql* 调用;加固模板引擎空值防护;关闭调试模式并禁访 runtime 目录;建议删除或禁用 Windows.php 防反序列化。</p>

ThinkPHP 5.0.24 原生不兼容 PHP 8.1+,直接在 PHP 8 环境下运行会报错,比如 count(): Parameter must be an array or an object、create_function() is deprecated 或 mysql_connect() undefined。它不是“开箱即用”,而是需要针对性改造才能稳定运行。
核心原则是:不升级框架大版本,只做最小必要修补;不硬改核心逻辑,优先拦截、兜底、替换。
确认并修复 PHP 8 兼容性报错点
TP5.0.24 在 PHP 8 下典型崩溃位置有三类,需逐项检查: - count() 对 null 的严格校验:搜索项目中所有 `count($var)`,尤其在模型关联、分页、模板解析处,改为 `is_array($var) || $var instanceof \Countable ? count($var) : 0` - create_function() 已废弃:该函数多见于旧版扩展、自定义标签或第三方插件中;全部替换为匿名函数,例如 `create_function('$a', 'return strtoupper($a);')` → `function($a) { return strtoupper($a); }` - mysql_* 扩展彻底移除:若代码里还存在 `mysql_connect()` 等调用(常见于老迁移脚本或自写数据库封装),必须删除或重写为 PDO/MySQLi;TP5 自身已用 PDO,此问题通常出在业务层硬编码模板引擎 NULL 字符串函数防护(关键补丁)
PHP 8 对字符串函数传入 `null` 更敏感,而 ThinkPHP 模板引擎在解析 `{$name|htmlspecialchars}` 这类修饰符时可能未判空。 需修改:thinkphp/library/think/Template.php 第 894 行附近的 `parseVarFunction` 方法,在执行函数前加空值拦截: ```php if (in_array($func, $this->tpl_denynull_str_func_list) && $value === null) { $value = ''; } ``` 同时确保 `tpl_denynull_str_func_list` 包含 `htmlspecialchars`, `html_entity_decode`, `trim`, `strtoupper` 等常用字符串函数。关闭调试模式与清理日志暴露面
PHP 8 环境下,若仍开启 `APP_DEBUG=true`,错误堆栈会暴露更多内部路径与变量,加剧兼容问题被利用的风险: - 修改 application/config.php,确认 `'debug' => false` - 删除整个 runtime/log/ 目录(不只是清空,要删掉子目录) - Nginx/Apache 配置中禁止访问 runtime: ```nginx location ^~ /runtime/ { deny all; } ```可选但推荐:替换 Windows.php 阻断反序列化链
TP5.0.24 的 `thinkphp/library/think/process/pipes/Windows.php` 是经典 POP 链入口,PHP 8 下虽不一定触发,但存在即风险: - 直接删除该文件(Linux/Unix 服务器完全不调用它) - 或在其类开头强制抛出异常: ```php public function __sleep() { throw new \Exception('Serialization disabled'); } public function __wakeup() { throw new \Exception('Unserialization disabled'); } ```不复杂但容易忽略



















