model基类封装自定义方法whereFilter优化版

创建代码片段SearchFilter

<?php

namespace App\Handlers;

trait SearchFilter
{
    /**
     * searchFilter
     * @param $query
     * @param array $condition
     * @param string $boolean
     * @return mixed
     */
    public function searchFilter($query, array $condition, string $boolean)
    {
        if (!isset($condition[0])) {
            return $query->where(function ($query) use ($condition) {
                // hash format: 'column1' => 'value1', 'column2' => 'value2', ...
                foreach ($condition as $name => $value) {
                    if ($this->isEmpty($value)) {
                        unset($condition[$name]);
                        continue;
                    }

                    if (is_array($value)) {
                        $query->whereIn($name, $value);
                    } else {
                        $query->where($name, '=', $value);
                    }
                }
            }, null, null, $boolean);
        }

        $operator = strtolower(array_shift($condition));

        switch ($operator) {
            case 'and':
            case 'or':
                $query->where(function ($query) use ($operator, $condition) {
                    foreach ($condition as $item) {
                        if (is_array($item)) {
                            $this->searchFilter($query, $item, $operator);
                        }
                    }
                }, null, null, $boolean);
                break;
            case 'in':
                if (array_key_exists(1, $condition) && !$this->isEmpty($condition[1])) {
                    $query->whereIn($condition[0], $condition[1], $boolean);
                }
                break;
            case 'like':
                if (array_key_exists(1, $condition) && !$this->isEmpty($condition[1])) {
                    $query->where($condition[0], $operator, '%' . $condition[1] . '%', $boolean);
                }
                break;
            case 'between':
                if (array_key_exists(1, $condition) && array_key_exists(2, $condition) && !$this->isEmpty($condition[1]) && !$this->isEmpty($condition[2])) {
                    $query->where(function ($query) use ($condition) {
                        $query->whereBetween(array_shift($condition), $condition);
                    }, null, null, $boolean);
                }
                break;
            case 'not between':
                if (array_key_exists(1, $condition) && array_key_exists(2, $condition) && !$this->isEmpty($condition[1]) && !$this->isEmpty($condition[2])) {
                    $query->where(function ($query) use ($condition) {
                        $query->whereNotBetween(array_shift($condition), $condition);
                    }, null, null, $boolean);
                }
                break;
            default:
                if (array_key_exists(1, $condition) && !$this->isEmpty($condition[1])) {
                    $query->where($condition[0], $operator, $condition[1], $boolean);
                }
                break;
        }

        return $query;
    }

    /**
     * Returns a value indicating whether the give value is "empty".
     *
     * The value is considered "empty", if one of the following conditions is satisfied:
     *
     * - it is `null`,
     * - an empty string (`''`),
     * - a string containing only whitespace characters,
     * - or an empty array.
     *
     * @param mixed $value
     * @return boolean if the value is empty
     */
    protected function isEmpty($value): bool
    {
        return $value === '' || $value === [] || $value === null || (is_string($value) && trim($value) === '');
    }
}

在BaseModel中引入

// 加载自定义方法searchFilter
use SearchFilter;

在BaseModel创建自定义方法

/**
 * whereFilter
 * @param $query
 * @param array $condition
 * @param string $boolean
 * @return mixed
 */
public function scopeWhereFilter($query, array $condition)
{
    return $this->searchFilter($query, $condition, 'and');
}

/**
 * orWhereFilter
 * @param $query
 * @param array $condition
 * @param string $boolean
 * @return mixed
 */
public function scopeOrWhereFilter($query, array $condition)
{
    return $this->searchFilter($query, $condition, 'or');
}

在代码中使用测试

$query = DealerModel::whereFilter([
    'and',
    ['=', 'dealer_id', 1],
    ['=', 'dealer_id', null],
    ['like', 'dealer_name', 'aaaa'],
    ['like', 'dealer_name', ''],
    [
        'or',
        ['dealer_id' => 2, 'id' => null, 'dealer_name' => [1, 2, 3]],
        ['in', 'dealer_id', [1, 2, 3]],
        ['in', 'dealer_name', []],
        ['between', 'created_at', time(), time() + 10000]
    ]
])
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2

这个封装的意义在哪,能形成共识吗

11个月前 评论
冯小胖同学 (楼主) 11个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!