You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP嵌套foreach循环转Twig遇pieces数据异常,求解决方案

Twig嵌套循环匹配对应pieces数组的问题

我现在要把一段PHP的嵌套foreach逻辑迁移到Twig模板里,单独处理fruit数组没问题,但pieces部分在Twig里只显示case 2的结果,怎么都匹配不上每个fruit对应的id。

我的现有代码

原PHP逻辑代码

$fruit = array(); 
$fruit[] = array('id' => 1, 'name' => 'Banana 1'); 
$fruit[] = array('id' => 1, 'name' => 'Pear 1'); 
$fruit[] = array('id' => 1, 'name' => 'Mango 1'); 
$fruit[] = array('id' => 2, 'name' => 'Banana 2'); 
$fruit[] = array('id' => 2, 'name' => 'Pear 2'); 
$fruit[] = array('id' => 2, 'name' => 'Mango 2'); 

function get_pieces($id) { 
    $pieces = array(); 
    switch ($id) { 
        case 1: 
            $pieces[] = array('number' => 1); 
            $pieces[] = array('number' => 2); 
            break; 
        case 2: 
            $pieces[] = array('number' => 3); 
            $pieces[] = array('number' => 4, 'qwerty' => 1); 
            break; 
    } 
    return $pieces; 
} 

foreach ($fruit as $item) { 
    echo '<p>'; 
    echo '<b>' . $item['name'] . '</b>'; 
    $pieces = get_pieces($item['id']); 
    foreach ($pieces as $piece) { 
        echo '<p>'; 
        echo '<i>' . $piece['number'] . '</i>'; 
        if (isset($piece['qwerty'])) { 
            echo ' => <i>qwerty is on</i>'; 
        } 
        echo '</p>'; 
    } 
    echo '</p>'; 
}

当前后端传递模板数据的代码

$render = array(); 
$render = array_merge($render, array('fruit' => $fruit)); 
$render = array_merge($render, array('pieces' => get_pieces(1))); 
$render = array_merge($render, array('fruit' => $fruit)); 
$render = array_merge($render, array('pieces' => get_pieces(2))); 
echo $twig->render('test.html', $render);

当前Twig模板代码

{% for f in fruit %} 
    <p>{{ f.id }}</p> 
    <p>{{ f.name }}</p> 
    {% for p in pieces %} 
        <p>Piece {{ p.number }}</p> 
    {% endfor %} 
{% endfor %}

问题分析

你现在的问题很明显——后端传递数据的时候,两次给pieces赋值,第二次get_pieces(2)直接覆盖了第一次的get_pieces(1),所以Twig模板里拿到的永远是id=2的pieces数组,自然没法和每个fruit的id对应起来。

解决方案

方案一:后端预处理,关联每个fruit的pieces

在传递给Twig之前,把每个fruit项对应的pieces直接附加到数组里,这样Twig里直接循环就行:

$render = [];
// 预处理fruit数组,给每个项加上对应的pieces
foreach ($fruit as &$item) {
    $item['pieces'] = get_pieces($item['id']);
}
unset($item); // 解除引用

$render['fruit'] = $fruit;
echo $twig->render('test.html', $render);

对应的Twig模板修改为:

{% for f in fruit %} 
    <p><b>{{ f.name }}</b></p>
    {% for p in f.pieces %} 
        <p><i>{{ p.number }}</i>
        {% if p.qwerty is defined %}
             => <i>qwerty is on</i>
        {% endif %}
        </p>
    {% endfor %} 
{% endfor %}

方案二:在Twig中注册自定义函数,直接调用get_pieces

如果你不想在后端预处理,也可以把get_pieces函数注册到Twig里,这样模板里可以根据当前fruit的id直接调用:

首先在后端注册函数:

// 注册get_pieces函数到Twig
$twig->addFunction(new Twig\TwigFunction('get_pieces', 'get_pieces'));

$render['fruit'] = $fruit;
echo $twig->render('test.html', $render);

然后修改Twig模板:

{% for f in fruit %} 
    <p><b>{{ f.name }}</b></p>
    {% set pieces = get_pieces(f.id) %}
    {% for p in pieces %} 
        <p><i>{{ p.number }}</i>
        {% if p.qwerty is defined %}
             => <i>qwerty is on</i>
        {% endif %}
        </p>
    {% endfor %} 
{% endfor %}

内容的提问来源于stack exchange,提问作者Arthur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:04:14