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

Laravel Eloquent中基于数组动态构建复杂Where条件的问题

Dynamic Grouped Where Conditions for Eloquent Builder

Got it, let's break down how to solve this problem. You want to dynamically apply a variable number of grouped where() conditions to your Eloquent Builder instance using that nested $filter array. Here's a clean, recursive approach that handles both flat conditions and nested groups seamlessly:

Step 1: Parse Individual Condition Strings

First, we need a helper to split each condition string into its core components. The format [boolean]:[column]:[operator]:[value] is straightforward—we'll split it safely (even if your value contains colons) using explode() with a limit of 4:

/**
 * Parse a condition string into boolean, column, operator, and value
 */
function parseCondition(string $condition): array
{
    [$boolean, $column, $operator, $value] = explode(':', $condition, 4);
    return compact('boolean', 'column', 'operator', 'value');
}

Step 2: Recursive Filter Application

The key here is using recursion to handle nested groups. When we hit an array in the $filter list, we'll create a grouped sub-query with a closure (via whereNested(), which automatically wraps the conditions in parentheses):

/**
 * Recursively apply filters to an Eloquent Builder instance
 */
function applyFilters(\Illuminate\Database\Eloquent\Builder $query, array $filters): void
{
    foreach ($filters as $filter) {
        if (is_array($filter)) {
            // Nested array = grouped conditions (wrap in parentheses)
            $query->whereNested(function (\Illuminate\Database\Eloquent\Builder $subQuery) use ($filter) {
                applyFilters($subQuery, $filter);
            });
        } else {
            // Flat condition string = apply directly to the query
            $parts = parseCondition($filter);
            
            // Choose between where() and orWhere() based on the boolean flag
            $method = strtolower($parts['boolean']) === 'and' ? 'where' : 'orWhere';
            
            $query->$method($parts['column'], $parts['operator'], $parts['value']);
        }
    }
}

Step 3: Use It With Your Query

Now just pass your existing $query instance and $filter array to the helper function:

// Your existing Eloquent query (e.g., User::query())
$query = \App\Models\User::query();

// Your filter array
$filter = [
    'or:email:=:ivantalanov@tfwno.gf',
    [
        'or:api_token:=:abcdefghijklmnopqrstuvwxyz',
        'and:login:!=:administrator',
    ],
];

// Apply the dynamic filters
applyFilters($query, $filter);

// The generated SQL will look like this:
// SELECT * FROM `users` WHERE `email` = ? OR (`api_token` = ? AND `login` != ?)

Bonus: Handle More Complex Conditions

If you need to support operators like IN, BETWEEN, or null checks, you can extend the logic easily. For example, to add IN support:

// Inside the flat condition block of applyFilters()
$parts = parseCondition($filter);
$method = strtolower($parts['boolean']) === 'and' ? 'where' : 'orWhere';

if ($parts['operator'] === 'in') {
    $values = explode(',', $parts['value']);
    $query->{$method . 'In'}($parts['column'], $values);
} else {
    $query->$method($parts['column'], $parts['operator'], $parts['value']);
}

This makes the solution flexible enough to handle most common SQL condition types.

内容的提问来源于stack exchange,提问作者Ivan T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:03:58