Twig合并JSON时数字字符串键被转为整数的技术问题
这个问题我之前也碰到过!核心原因是Twig里初始化空对象{}其实对应PHP的空数组,当你合并数字字符串键的时候,PHP会自动把这些键转成整数,最后生成的是索引数组,而json_encode遇到连续整数索引的数组时,就会输出JSON数组而不是你想要的对象。
给你两个可行的解决办法:
方法一:用占位键强制保持对象类型(Twig 2.7+适用)
初始化的时候给rows加一个非数字的占位键,这样Twig会把它当成对象而非数组处理,合并完成后再移除这个占位键,最后用JSON_FORCE_OBJECT确保JSON输出是对象:
{# 初始化带占位键的对象,避免被识别为数组 #} {% set rows = {'_temp': ''} %} {% for key, val in row %} {% set rows = rows|merge({ (key) : val }) %} {% endfor %} {# 移除占位键(Twig 2.7及以上支持remove方法) #} {% do rows.remove('_temp') %} {# 输出JSON时强制转成对象 #} {{ { 'report': { 'metric': metric, 'rows': rows, 'tot': tot, 'min': min, 'max': max } }|json_encode(constant('JSON_FORCE_OBJECT'))|raw }}
方法二:兼容低版本Twig的过滤法
如果你的Twig版本低于2.7,没有remove方法,可以用filter过滤器去掉占位键:
{% set rows = {'_temp': ''} %} {% for key, val in row %} {% set rows = rows|merge({ (key) : val }) %} {% endfor %} {# 过滤掉占位键 #} {% set rows = rows|filter((value, key) => key != '_temp') %} {{ { 'report': { 'metric': metric, 'rows': rows, 'tot': tot, 'min': min, 'max': max } }|json_encode(constant('JSON_FORCE_OBJECT'))|raw }}
额外说明
JSON_FORCE_OBJECT这个参数是关键,它会让PHP把所有数组都转成JSON对象,哪怕是连续整数索引的数组,这样就能保证你的rows始终是键为数字字符串的JSON对象,而不是数组。
如果你能在后端PHP代码里处理的话,也可以把row变量转换成stdClass对象再传给Twig,这样Twig合并的时候会保持对象类型,不需要占位键也能得到正确的JSON对象。
内容的提问来源于stack exchange,提问作者Julien B.
相关产品推荐
相关产品推荐

