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

Laravel含OR操作的Query Builder致全局Scope失效问题及解决

Fixing Laravel 5.4 Global Scope "Failure" with OR Queries

Got it, let's tackle this issue head-on. The root problem here is SQL operator priority: AND gets evaluated before OR, so your generated query ends up being interpreted as name like ? OR (id = ? AND user_id = ?) instead of the (name like ? OR id = ?) AND user_id = ? you need.

Here's a robust way to modify your global scope to automatically wrap user-provided query conditions in parentheses, ensuring the correct logic every time:

Modified Global Scope Implementation

protected static function boot() {
    parent::boot();
    
    static::addGlobalScope('user_filter', function(\Illuminate\Database\Eloquent\Builder $builder) use($userId) {
        // Capture the original where clauses and bindings from the user's query
        $originalWheres = $builder->getQuery()->wheres;
        $originalBindings = $builder->getQuery()->getBindings();
        
        // Clear existing conditions to rebuild the query structure correctly
        $builder->getQuery()->wheres = [];
        $builder->getQuery()->setBindings([]);
        
        // Wrap the user's original query in a nested where, then add the user_id filter
        $builder->where(function($subQuery) use ($originalWheres, $originalBindings) {
            // Restore the user's original query conditions
            $subQuery->getQuery()->wheres = $originalWheres;
            $subQuery->getQuery()->setBindings($originalBindings);
        })->where( (new static)->getTable() . '.user_id', '=', $userId );
    });
}

How This Works

  1. Capture Original Conditions: We first grab all the existing WHERE clauses and their bindings that the user added (like your whereRaw OR query).
  2. Reset the Builder: Clear out the current conditions so we can rebuild the query with the correct structure.
  3. Rebuild with Nested Where: We wrap the user's original query inside a nested WHERE closure (which automatically adds the necessary parentheses) and then chain our user_id filter onto it. The final generated SQL will look exactly like you need:
    select * from `cars` where (name like ? or id = ?) and user_id = ?
    

Why This Is Better Than Manual Fixes

This approach eliminates the need to manually add parentheses to every query that uses OR conditions. It works seamlessly with raw queries, chained where calls, and complex conditional logic—you don't have to worry about remembering to adjust individual queries.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:23:01