如何查找所有需使用traverse的TYPO3 TypoScript条件?
查找受影响的TypoScript条件方案
正则表达式与数据库检索
直接通过数据库查询定位sys_template表中存在风险的配置:
mariadb> select uid,pid from sys_template where (config REGEXP '\\[ *request.getQueryParams()' or config REGEXP '\\[page\\[') and not hidden and not deleted;
针对常见风险场景,可用以下正则表达式匹配未使用traverse()的写法:
- 匹配直接访问数组元素:
\[\s*(page|request.getQueryParams\(\))\[[^]]+\] - 匹配多层数组嵌套访问:
\[\s*(request.getQueryParams\(\))\['[^']+'\]\['[^']+'\]
可用工具
- 官方扩展:使用
typo3/cms-lowlevel扩展的configanalyzer工具,扫描系统内TypoScript配置,识别不符合最佳实践的条件。 - IDE辅助:PhpStorm等IDE的TYPO3插件可配置代码检查规则,实时提示未用
traverse()的风险代码。 - 自定义脚本:编写PHP脚本遍历所有TypoScript文件(含sys_template记录、扩展内配置文件),用正则批量匹配风险代码。
问题背景
TYPO3 9.4及以后版本,TypoScript条件基于Symfony表达式语言实现。当条件(或EXT:form等依赖该语言的模块)访问未初始化变量或不存在的数组元素时,会触发PHP警告——这是当前Symfony表达式语言的已知缺陷,官方确认后续版本会修复。
官方推荐用traverse()函数保护属性访问:
page变量仅在前端上下文可用。由于TypoScript配置可能在后端模块或CLI环境中加载,因此始终用traverse()包裹属性访问是最优方案。
修复示例
请求参数访问优化
# 优化前 -[request.getQueryParams()['tx_news_pi1'] && request.getQueryParams()['tx_news_pi1']['news'] > 0] # 优化后 +[traverse(request.getQueryParams(), 'tx_news_pi1/news') > 0]
Page数组访问优化
# 优化前 - [page["uid"] == 2] # 优化后 + [traverse(page, "uid") == 2]
错误日志标识
在PHP 8.1 + TYPO3 v11环境下,触发问题时会生成如下警告日志:
PHP Warning: Undefined array key "uid" in /app/vendor/symfony/expression-language/Node/GetAttrNode.php line 97
参考信息
- TYPO3官方问题(编号95781):Symfony表达式语言在访问未定义数组元素或变量时会抛出PHP警告,该问题在PHP 8及以上版本中表现更明显。官方给出的临时解决方案是使用
traverse()函数规避,同时确认Symfony后续版本会修复底层逻辑。
内容的提问来源于stack exchange,提问作者Sybille Peters
相关产品推荐
相关产品推荐

