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

Laravel控制器嵌套foreach循环过滤受限海报生成新数组问题

Laravel国家受限海报过滤问题修复方案

现有代码问题

  • 属性访问方式错误:Laravel中DB::get()返回的是Collection集合,集合内的每一项是stdClass对象,无法通过数组下标$restrictedPoster['poster_viewable']的方式读取属性,需要用对象语法$restrictedPoster->poster_viewable访问。
  • 过滤逻辑错误:嵌套循环没有匹配当前海报和受限海报的poster_id,导致不管ID是否对应,只要受限列表中存在可查看的条目,就会把当前海报塞入结果数组,同时会出现同一张海报被重复添加的问题。

快速修复方案(基于现有代码调整)

先将受限海报转为ID为键、可视状态为值的映射表,再遍历全量海报做判断:

class PosterRestrictionController extends Controller
{
    public function index() 
    {
        $profile = app('App\Http\Controllers\DevelopmentController')->getActiveUser(Auth::id());
        $userCountry = $profile->country;
        $unrestrictedPosters = [];

        $allPosters = DB::table('posters')
        ->join('profiles', 'posters.user_id', '=', 'profiles.user_id')
        ->join('users', 'posters.user_id', '=', 'users.id')
        ->select('users.name',
                'profiles.surname',
                'profiles.country',
                'posters.id as poster_id',
                'posters.user_id',
                'posters.title',
                'posters.category',
            )
        ->orderBy('posters.id', 'asc')
        ->get();

        $restrictedPosters = DB::table('posters')
        ->join('poster_restrictions', 'poster_restrictions.poster_id', '=', 'posters.id')
        ->where('poster_restrictions.restricted_country_id', '=', $userCountry)
        ->select(
                'posters.id as poster_id',
                'poster_restrictions.poster_viewable',
                'poster_restrictions.restricted_country_id'
                )
        ->orderBy('posters.id', 'asc')
        ->get();

        // 生成受限海报ID和可视状态的映射表
        $restrictedMap = $restrictedPosters->pluck('poster_viewable', 'poster_id');

        foreach ($allPosters as $poster) {
            // 不在受限列表直接加入结果
            if (!isset($restrictedMap[$poster->poster_id])) {
                $unrestrictedPosters[] = $poster;
                continue;
            }
            // 在受限列表且允许查看的才加入
            if ($restrictedMap[$poster->poster_id] != 0) {
                $unrestrictedPosters[] = $poster;
            }
        }

        dd($unrestrictedPosters);
        //return view('你的模板名', compact('unrestrictedPosters'));
    }
}

更优方案(单SQL查询,性能更高)

无需分两次查询再循环处理,直接通过左关联在数据库层面完成过滤:

public function index() 
{
    $profile = app('App\Http\Controllers\DevelopmentController')->getActiveUser(Auth::id());
    $userCountry = $profile->country;

    $unrestrictedPosters = DB::table('posters')
        ->join('profiles', 'posters.user_id', '=', 'profiles.user_id')
        ->join('users', 'posters.user_id', '=', 'users.id')
        // 左关联对应当前国家的受限规则
        ->leftJoin('poster_restrictions', function ($join) use ($userCountry) {
            $join->on('poster_restrictions.poster_id', '=', 'posters.id')
                ->where('poster_restrictions.restricted_country_id', '=', $userCountry);
        })
        ->select('users.name',
                'profiles.surname',
                'profiles.country',
                'posters.id as poster_id',
                'posters.user_id',
                'posters.title',
                'posters.category',
            )
        // 过滤条件:无受限规则 或 受限规则允许查看
        ->where(function ($query) {
            $query->whereNull('poster_restrictions.id')
                ->orWhere('poster_restrictions.poster_viewable', '!=', 0);
        })
        ->orderBy('posters.id', 'asc')
        ->get();

    dd($unrestrictedPosters);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:12:00