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

PHP实现查找菜单树中无子节点(非父节点)的最新记录

解决PHP中查找菜单树最新叶子节点的问题

我来帮你搞定这个需求!咱们用纯PHP循环和函数来实现,完全符合你的要求,不需要用递归或者复杂的SQL语句(当然如果用SQL也能查,但你指定了用PHP循环和函数,那咱们就走这条路线)。

核心思路

叶子节点的定义是没有子节点的节点,也就是这个节点的id不会出现在任何其他节点的parent_id字段里。然后要找“最新条目”,假设你的id是自增主键(通常菜单表都会这么设计),那id值最大的叶子节点就是最新创建的。

分步实现代码

首先咱们分三个函数来实现,逻辑清晰,也方便复用:

  1. 获取所有菜单数据:从数据库拉取完整的菜单列表
  2. 筛选所有叶子节点:通过循环判断找出所有没有子节点的节点
  3. 找出最新的叶子节点:对叶子节点按id降序排序,取第一个就是最新的
// 假设你已经建立了PDO数据库连接,$pdo是你的连接实例
// 如果你用mysqli,只需要把查询部分改成mysqli的写法就行
function getAllMenuItems($pdo) {
    $stmt = $pdo->query("SELECT id, title, parent_id FROM menu");
    // 把结果转成关联数组,方便后续操作
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

function getLeafNodes($menuItems) {
    $parentIds = [];
    
    // 第一步:先收集所有作为父节点的ID(也就是所有出现在parent_id里的有效ID)
    foreach ($menuItems as $item) {
        // 这里假设parent_id为0或null代表根节点,不需要计入父节点集合
        if (!empty($item['parent_id'])) {
            $parentIds[] = $item['parent_id'];
        }
    }
    // 去重,避免重复判断,提升效率
    $parentIds = array_unique($parentIds);
    
    $leafNodes = [];
    // 第二步:筛选叶子节点——ID不在父节点集合里的节点
    foreach ($menuItems as $item) {
        if (!in_array($item['id'], $parentIds)) {
            $leafNodes[] = $item;
        }
    }
    
    return $leafNodes;
}

function getLatestLeafNode($leafNodes) {
    if (empty($leafNodes)) {
        return null;
    }
    
    // 按ID降序排序,ID最大的就是最新创建的节点
    usort($leafNodes, function($a, $b) {
        return $b['id'] - $a['id'];
    });
    
    // 返回第一个元素,也就是最新的叶子节点
    return $leafNodes[0];
}

// 调用示例
$menuItems = getAllMenuItems($pdo);
$leafNodes = getLeafNodes($menuItems);
$latestLeaf = getLatestLeafNode($leafNodes);

// 输出结果
if ($latestLeaf) {
    echo "最新叶子节点:ID=" . $latestLeaf['id'] . ",标题=" . $latestLeaf['title'];
} else {
    echo "没有找到任何叶子节点";
}

细节调整说明

  • 如果你的菜单表中,根节点的parent_id是null而不是0,只需要把getLeafNodes里的判断改成if ($item['parent_id'] !== null)就行。
  • 如果“最新条目”的判断不是基于id,而是有单独的created_at字段,那只需要修改排序逻辑,把$b['id'] - $a['id']改成strtotime($b['created_at']) - strtotime($a['created_at'])即可。
  • 如果你需要的是所有叶子节点按最新排序,而不是只取第一个,直接返回排序后的$leafNodes数组就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:25:14