php 8.5 彻底移除 create_function() 和 each(),调用即致命错误;createfunction() 必须替换为 fn() 或 function() 匿名函数,each() 应改用 foreach;同时 mysql* 函数、动态属性、string|null 联合类型等均被严格禁用。

create_function() 和 each() 调用直接报错
PHP 8.5 彻底移除了 create_function() 和 each(),不是警告,是致命错误。这类函数多见于老 CMS 插件、自定义模板引擎或早期框架的回调注册逻辑中。
-
create_function()必须替换成匿名函数:fn($a, $b) => $a + $b(推荐)或function($a, $b) { return $a + $b; } -
each()基本只在 while 循环遍历数组时出现,改用foreach ($arr as $k => $v)即可,语义更清晰且无兼容风险 - 注意:有些代码会把
create_function()当作“动态 eval”用,这本身就有安全漏洞,升级正好强制清理
mysql_* 系列函数和 ext/mysql 扩展已消失
这不是新消息,但 PHP 8.5 是最后一锤——mysql_connect()、mysql_query() 等函数调用会触发 Fatal error: Uncaught Error: Call to undefined function mysql_connect()。
- 必须迁移到
PDO或mysqli;优先选PDO,抽象层更稳,支持预处理防注入 - 检查所有
php.ini中是否还留着extension=mysql.so(Linux)或extension=php_mysql.dll(Windows),删掉,否则启动失败 - 若项目用了封装类(如
Db::query()),确认底层没偷偷调用mysql_*—— 有些老封装只是套壳,内核仍是废弃函数
联合类型里写 string|null 不再合法,得用 ?string
PHP 8.5 加强了联合类型的语法约束。下面这种写法在 8.4 可能仅警告,但在 8.5 直接报 TypeError:
function greet(string|null $name): string { return "Hello, " . ($name ?? "Guest"); }
原因:PHP 要求可空类型必须显式用 ? 前缀,禁止混用 string|null 这种联合形式(哪怕语义等价)。
立即学习“PHP免费学习笔记(深入)”;
- 统一改成
?string、?int等格式 - 如果函数参数本就允许 null,但没加
?,比如function log(string $msg)却传了null,现在会立刻崩,不是静默转成空字符串 - 启用
declare(strict_types=1)的文件要格外小心,类型校验会在调用入口就卡住
动态属性默认禁用,$obj->undefined_prop = 'x' 触发 Fatal Error
PHP 8.5 默认关闭动态属性(Dynamic Properties)。没有声明的属性赋值会抛出:Fatal error: Cannot create dynamic property User::$name。
- 最稳妥解法:在类里明确定义属性,哪怕只是
public string $name; - 若确需兼容旧逻辑(比如从 JSON 映射数据的 DTO 类),加
#[AllowDynamicProperties]属性到类上 - 注意:这个注解不继承,父类加了,子类还得自己加;而且它不能用于 final 类或有
__set()的类 - 别指望靠
error_reporting(0)屏蔽——这是 Error,不是 Warning,关不掉
最容易被忽略的是扩展依赖和 SAPI 层绑定问题:比如你本地用 php-fpm 测试通过,但生产用的是 apache2handler,而某个扩展(如 apcu)在 Apache 模式下加载失败,日志里只有一行 Segmentation fault,根本看不出是 PHP 版本还是扩展惹的祸。上线前务必在完全一致的运行环境下跑一遍 php -m 和 php --ini 对照。











