PHP 7.4起弃用{}访问数组/字符串偏移(如$str{0}),8.0+彻底移除,必须将$value{0}等改为$value[0];仅偏移访问需改,正则、插值、字符串字面量中的{}不受影响。

PHP 7.4 已正式弃用 {} 语法访问字符串和数组(如 $str{0}、$arr{'key'}),直接升级到 8.0+ 会报 Deprecated: Array and string offset access syntax with curly braces is deprecated 警告,且 PHP 8.0 及以后版本将彻底移除该语法,导致 Fatal error。
哪些写法必须改,改哪里
不是所有大括号都错——只有用于「偏移访问」的 {} 才被弃用。常见误用位置包括:
-
core/library/think/db/Query.php第 139 行:$value{0}→ 改为$value[0] -
vendor/xxx/SomeClass.php中类似$data{$key}或$str{$i}的表达式 - 模板文件(.php 或 .html)中裸写的
<?php echo $row{'name'}; ?>
注意:if ($arr['key'] ?? null) 这类方括号写法完全安全,无需改动;json_encode() 里带大括号的字符串内容(如 "{id:1}")也不受影响。
为什么不能只靠 IDE 全局替换
盲目把所有 { 替成 [ 会出事。因为:
立即学习“PHP免费学习笔记(深入)”;
-
preg_replace('{pattern}', ...)中的{是正则分隔符,不是偏移语法 -
echo "Hello {$name}";是变量插值,{}在双引号内合法且必须保留 - 某些自定义 DSL 或配置字符串(如
"timeout={30}")只是普通文本
真正要改的,仅限于「变量后紧跟 { + 表达式 + }」这种结构,且左侧必须是数组或字符串类型变量。建议用正则精准定位:\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\{.*?\},再人工确认上下文。
如何验证是否改干净
光跑首页没用,很多问题藏在后台、CLI 命令、定时任务里:
- 开启完整错误报告:
error_reporting(E_ALL); ini_set('display_errors', '1');,确保E_DEPRECATED不被屏蔽 - 运行关键路径:登录后台、提交表单、执行
php artisan schedule:run或php bin/console cron:run - 检查日志:
tail -f /var/log/php/error.log或项目storage/logs/laravel.log,搜索curly braces - 用静态分析工具辅助:
phpstan analyse --level=8可捕获部分未显式触发的弃用调用
特别注意 Twig/Smarty 模板:它们编译后的 PHP 文件(如 cache/twig/xx.php)里也可能生成 $context["key"]{0} 类代码,需清空模板缓存后重刷页面再查。
升级后仍报错的隐藏原因
即使代码全改完,上线还报错,大概率是缓存或环境没切干净:
- OPcache 没清除:
php -r "opcache_reset();"或重启 PHP-FPM 进程 - 宝塔面板里网站绑定的是新 PHP 版本,但
.user.ini文件里锁定了旧版:php_version=74必须删掉或改成80 - CLI 和 Web 使用不同 PHP:
which php和phpinfo()输出的版本不一致,composer install用的还是 7.4,导致 vendor 里装了不兼容包
最稳妥的做法:改完代码 → 清 OPcache + 清模板缓存 → 用新 PHP 重新 composer install → 用新 PHP 执行一次 php -m 确认扩展已加载 → 最后再切站。



















