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

Laravel控制器通过foreach循环向Blade返回数据,实现帖子按分类归类展示

我看了你的代码,发现几个关键问题导致没法正确按分类关联展示帖子,咱们一步步来修正:

首先说下原代码的问题点:

  • 循环逻辑错误:你在嵌套循环里把整个查询结果数组($postsWithCatQuery/$smallpostsWithCatQuery)push到目标数组里,而不是匹配的单个帖子数据;而且第二个循环还误把$postsWithCatQuery当成了小帖子的查询结果,应该用$smallpostsWithCatQuery。
  • 数据结构不合理:原代码生成的是扁平数组,没法直接对应“分类-帖子”的层级关系,Blade里遍历会混乱。
  • 查询冗余:两次查询逻辑重复,写法可以优化。

修正后的控制器代码

我们先构建「分类ID → 对应大/小帖子」的映射数组,再和你的分类列表关联,这样结构更清晰:

// 获取当前语言下的大缩略图帖子(注意修正join的等号,避免语法隐患)
$bigPosts = DB::table('posts')
    ->join('post_translations', 'posts.id', '=', 'post_translations.post_id')
    ->join('language', 'post_translations.language_id', '=', 'language.id')
    ->where('language.local', App::getLocale())
    ->where('big_thumbnail', 1)
    ->latest('post_date')
    ->get();

// 获取当前语言下的小缩略图帖子
$smallPosts = DB::table('posts')
    ->join('post_translations', 'posts.id', '=', 'post_translations.post_id')
    ->join('language', 'post_translations.language_id', '=', 'language.id')
    ->where('language.local', App::getLocale())
    ->whereNull('big_thumbnail')
    ->latest('post_date')
    ->limit(2)
    ->get();

// 初始化分类-帖子映射数组
$postsByCategory = [];

// 把大帖子按分类分组
foreach ($bigPosts as $post) {
    $catId = $post->category_id;
    if (!isset($postsByCategory[$catId])) {
        $postsByCategory[$catId] = ['big' => [], 'small' => []];
    }
    $postsByCategory[$catId]['big'][] = $post;
}

// 把小帖子按分类分组
foreach ($smallPosts as $post) {
    $catId = $post->category_id;
    if (!isset($postsByCategory[$catId])) {
        $postsByCategory[$catId] = ['big' => [], 'small' => []];
    }
    $postsByCategory[$catId]['small'][] = $post;
}

// 关联你的分类列表,确保只保留存在的分类
$categorizedPosts = [];
foreach ($cate as $category) {
    $catId = $category->category_id;
    $categorizedPosts[] = [
        'category' => $category,
        'posts' => $postsByCategory[$catId] ?? ['big' => [], 'small' => []]
    ];
}

// 把整理好的数据传给视图
return view('你的视图名称', compact('categorizedPosts'));

修正后的Blade模板代码

现在可以按「分类 → 大帖子 → 小帖子」的层级遍历,逻辑更直观:

@foreach($categorizedPosts as $item)
    <!-- 先展示分类名称(假设分类有name字段,根据你的实际字段调整) -->
    <h2>{{ $item['category']->name }}</h2>

    <!-- 遍历大缩略图帖子 -->
    @foreach($item['posts']['big'] as $post_b)
    <div class="post sports-post post-separator-border">
        <div class="post-wrap">
            <!-- 图片链接修正:加上引号,用post的id(原代码用post_id,注意你的字段名是否正确) -->
            <a class="image" href="{{ route('front.post_view', [$post_b->id]) }}">
                <img src="{{ $post_b->image }}" alt="{{ $post_b->title }}">
            </a>
            <div class="content">
                <!-- 这里补充你的帖子内容,比如标题、日期等 -->
                <h3><a href="{{ route('front.post_view', [$post_b->id]) }}">{{ $post_b->title }}</a></h3>
                <p>{{ $post_b->excerpt }}</p>
                <span class="post-date">{{ $post_b->post_date }}</span>
            </div>
        </div>
    </div>
    @endforeach

    <!-- 遍历小缩略图帖子 -->
    @foreach($item['posts']['small'] as $post_s)
    <div class="post small-post">
        <div class="post-wrap">
            <a class="image" href="{{ route('front.post_view', [$post_s->id]) }}">
                <img src="{{ $post_s->image }}" alt="{{ $post_s->title }}">
            </a>
            <div class="content">
                <h4><a href="{{ route('front.post_view', [$post_s->id]) }}">{{ $post_s->title }}</a></h4>
                <span class="post-date">{{ $post_s->post_date }}</span>
            </div>
        </div>
    </div>
    @endforeach
@endforeach

额外建议

如果你的项目用了Eloquent模型(比如Post、Category、PostTranslation),可以定义关联关系,代码会更简洁:

  • 在Post模型里定义category()关联和translations()关联
  • 用with()预加载关联,避免N+1查询

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 13:07:32