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

Silverstripe 3:如何将PHP多维数组转换为模板可循环格式

解决Silverstripe 3中多维数组转模板可循环结构的问题

嘿,我之前在Silverstripe 3里踩过一模一样的坑!你之前的尝试应该是没搞对ArrayList和ArrayData的嵌套逻辑——Silverstripe的模板引擎没法直接识别原生PHP多维数组,得把每个层级转换成它能解析的结构才行。

方法一:保留原分类键(直接访问Venue/Hotels)

如果想保持你原本的数组结构,让模板里能直接用$Locations.Venue这种方式访问,你需要把外层做成ArrayData,里面每个分类对应的子数组转换成ArrayList,每个子项再包成ArrayData:

// 你的原始多维数组
$locations = [
    'Venue' => [
        ['Name' => 'ANZ Events Centre']
    ],
    'Hotels' => [
        ['Name' => 'Pullman Hotel'],
        ['Name' => 'Mercure Hotel']
    ]
];

// 转换为Silverstripe模板可识别的结构
$ssLocations = new ArrayData([
    'Venue' => ArrayList::create(array_map(function($item) {
        return new ArrayData($item);
    }, $locations['Venue'])),
    'Hotels' => ArrayList::create(array_map(function($item) {
        return new ArrayData($item);
    }, $locations['Hotels']))
]);

// 将转换后的对象传给模板
$this->customise(['Locations' => $ssLocations]);

这样你就能在模板里完全按照你想要的逻辑写循环了:

<% if $Locations %>
    <% if $Locations.Venue %>
        <div class="venue-section">
            <% loop $Locations.Venue %>
                <p>$Name</p>
            <% end_loop %>
        </div>
    <% end_if %>

    <% if $Locations.Hotels %>
        <div class="hotels-section">
            <% loop $Locations.Hotels %>
                <p>$Name</p>
            <% end_loop %>
        </div>
    <% end_if %>
<% end_if %>

方法二:通用分类循环(适合扩展更多分类)

如果之后可能要加更多分类(比如Restaurants、Parks),更灵活的方式是把整个结构转换成ArrayList嵌套,每个分类包含名称和对应的子项集合:

$locations = [
    'Venue' => [['Name' => 'ANZ Events Centre']],
    'Hotels' => [['Name' => 'Pullman Hotel'], ['Name' => 'Mercure Hotel']]
];

$ssLocations = new ArrayList();
foreach ($locations as $categoryName => $items) {
    $itemList = new ArrayList();
    foreach ($items as $item) {
        $itemList->push(new ArrayData($item));
    }
    $ssLocations->push(new ArrayData([
        'CategoryName' => $categoryName,
        'Items' => $itemList
    ]));
}

$this->customise(['Locations' => $ssLocations]);

对应的模板代码可以简化成通用循环,不用逐个判断分类:

<% if $Locations %>
    <% loop $Locations %>
        <h3>$CategoryName</h3>
        <% loop $Items %>
            <p>$Name</p>
        <% end_loop %>
    <% end_loop %>
<% end_if %>

为什么之前的尝试失败?

Silverstripe的模板引擎只认识自己的数据结构:ArrayList是可循环的集合类,ArrayData是能直接访问字段(比如$Name)的数据对象。原生PHP数组哪怕是多维的,模板里只能访问键值,没法用loop语法,也不能直接解析子数组里的字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:51:52