Laravel 8多选筛选异常:仅展示首个选中来源的工单数据
问题分析
你遇到的核心问题是SQL的IN条件格式错误:
当你选择多个来源时,代码通过implode(', ', $source)生成的是类似"Email, Chat"的字符串,直接拼进SQL后变成AND ticket.source IN ('Email, Chat')——这会把整个字符串当作单个匹配值,而非多个独立的来源选项,自然只会匹配到source等于Email, Chat的工单(几乎不存在),导致看起来只生效第一个选项。
同时你的代码存在SQL注入风险,直接将用户输入和变量拼进原生SQL是不安全的。
解决方案
推荐方案:使用Laravel查询构造器(简洁且安全)
Laravel的查询构造器会自动处理数组格式的IN条件,同时内置参数绑定防止注入:
public function dashboard_realtime_filter(Request $request){ $project = Auth::user()->id_project_sementara; // 先验证请求参数合法性 $request->validate([ 'source' => 'required|array', 'source.*' => 'string' ]); // 用查询构造器替代原生SQL,自动处理IN条件 $served = DB::table('ticket') ->whereRaw("DATE_PART('DAY',CURRENT_TIMESTAMP) = DATE_PART('DAY',created_at)") ->where('id_project', $project) ->whereIn('source', $request->source) ->count('update_date'); return view('dashboard.dashboard_realtime', [ 'served' => $served, 'master_skill' => Master_skill::where('skill_name', '!=', 'All')->get() ]); }
备选方案:修复原生SQL写法(不推荐,仅作参考)
如果坚持使用原生SQL,需要手动生成带占位符的IN条件,并通过参数绑定传递值:
public function dashboard_realtime_filter(Request $request){ $project = Auth::user()->id_project_sementara; $request->validate([ 'source' => 'required|array', 'source.*' => 'string' ]); // 生成对应数量的SQL占位符(?) $placeholders = implode(', ', array_fill(0, count($request->source), '?')); // 通过参数绑定传递变量,避免注入 $served = DB::select(DB::raw( "SELECT COUNT(update_date) AS update_date FROM ticket WHERE DATE_PART('DAY',CURRENT_TIMESTAMP) = DATE_PART('DAY',ticket.created_at) AND ticket.id_project = ? AND ticket.source IN ($placeholders) "), array_merge([$project], $request->source)); $serveds = $served[0]->update_date; return view('dashboard.dashboard_realtime', [ 'served' => $serveds, 'master_skill' => Master_skill::where('skill_name', '!=', 'All')->get() ]); }
额外说明
- 表单中的
@csrf标签在GET请求中可以移除,CSRF保护主要针对POST/PUT/DELETE等修改类请求。 - 新增的参数验证可以防止非法请求,确保
source是合法的数组格式。
内容的提问来源于stack exchange,提问作者ryoushii16
相关产品推荐
相关产品推荐

