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

基于WordPress的Corcel/Laravel多级菜单生成问题

Fixing "Call to a member function offsetSet() on null" when building multi-level menus with Corcel

Hey there! Let's tackle this multi-level menu issue with Corcel together. That error you're seeing usually happens because you're trying to add items to a null collection—meaning you didn't initialize the child items container for your menu entries first. Let's walk through the correct implementation step by step.

Why the error happens

The official docs mention grouping items by parent ID, but they don't explicitly cover initializing the children collection for each menu item. When you try to push a child item to a parent that doesn't have a pre-defined children property (which defaults to null), you get the offsetSet() on null error.

Correct implementation code

Here's a complete, working example to build your multi-level menu:

// Fetch the main menu by location
$menu = Menu::location('main')->first();

// Handle case where the menu doesn't exist
if (!$menu) {
    return collect();
}

// First, store all menu items in an array keyed by their ID for quick lookup
$allMenuItems = [];
foreach ($menu->items as $item) {
    // Initialize the children collection for each item to avoid null errors
    $item->children = collect();
    $allMenuItems[$item->ID] = $item;
}

// Build the hierarchical menu structure
$menuTree = collect();
foreach ($allMenuItems as $item) {
    if ((int)$item->menu_item_parent === 0) {
        // Top-level items (parent ID 0) go directly into the main tree
        $menuTree->push($item);
    } else {
        // Find the parent item and add this item to its children collection
        if (isset($allMenuItems[$item->menu_item_parent])) {
            $allMenuItems[$item->menu_item_parent]->children->push($item);
        }
    }
}

// Now $menuTree holds your multi-level menu structure!

Key fixes in this code:

  • Initializing children collection: We explicitly set $item->children = collect(); for every menu item, so we never try to push to a null value.
  • Quick parent lookup: Storing items in an array keyed by ID makes finding parent items O(1) instead of looping through the collection every time, which is more efficient.
  • Error handling: We check if the menu exists first to avoid unexpected issues if the menu location is misconfigured.

Rendering the menu (example with Blade)

Once you have $menuTree, you can render it recursively with a Blade template:

<ul class="main-menu">
    @foreach($menuTree as $item)
        <li class="menu-item">
            <a href="{{ $item->url }}">{{ $item->title }}</a>
            <!-- Render submenu if there are children -->
            @if($item->children->isNotEmpty())
                @include('partials.submenu', ['items' => $item->children])
            @endif
        </li>
    @endforeach
</ul>
<ul class="submenu">
    @foreach($items as $item)
        <li class="submenu-item">
            <a href="{{ $item->url }}">{{ $item->title }}</a>
            <!-- Recursively render nested submenus -->
            @if($item->children->isNotEmpty())
                @include('partials.submenu', ['items' => $item->children])
            @endif
        </li>
    @endforeach
</ul>

This approach will handle any depth of nested menus, and you won't run into that offsetSet() error anymore.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:13:06