src/Leevel/Database/Condition.php
protected function addConditions(): self
    {
        $args = func_get_args();
        $table = $this->getTable();

        // 整理多个参数到二维数组
        if (!is_array($args[0])) {
            $conditions = [$args];
        } else {
            // 一维数组统一成二维数组格式
            $oneImension = false;

            foreach ($args[0] as $key => $value) {
                if (is_int($key) && !is_array($value)) {
                    $oneImension = true;
                }

                break;
            }

            if (true === $oneImension) {
                $conditions = [$args[0]];
            } else {
                $conditions = $args[0];
            }
        }

        // 遍历数组拼接结果
        foreach ($conditions as $key => $tmp) {
            if (!is_int($key)) {
                $key = trim($key);
            }

            // 字符串表达式
            if (is_string($key) && in_array($key, [':string', ':stringSimple'], true)) {
                // 不符合规则抛出异常
                if (!is_string($tmp)) {
                    $e = sprintf('String type only supports string,but %s given.', gettype($tmp));

                    throw new InvalidArgumentException($e);
                }

                // 表达式支持
                if (false !== strpos($tmp, '{') &&
                    preg_match('/^{(.+?)}$/', $tmp, $matches)) {
                    $tmp = $this->connect->normalizeExpression(
                        $matches[1],
                        $table
                    );
                }

                $this->setConditionItem($tmp, $key);
            }

            // 子表达式
            elseif (is_string($key) && in_array($key, [
                ':subor',
                ':suband',
            ], true)) {
                $typeAndLogic = $this->getTypeAndLogic();

                $select = new static($this->connect);
                $select->setTable($this->getTable());
                $select->setTypeAndLogic($typeAndLogic[0]);

                // 逻辑表达式
                if (isset($tmp[':logic'])) {
                    if (strtolower($tmp[':logic']) === static::LOGIC_OR) {
                        $select->setTypeAndLogic(null, static::LOGIC_OR);
                    }

                    unset($tmp[':logic']);
                }

                $select = $select->addConditions($tmp);

                // 解析结果
                $parseType = 'parse'.ucwords($typeAndLogic[0]);
                $oldLogic = $typeAndLogic[1];

                $this->setTypeAndLogic(null, ':subor' ? static::LOGIC_OR : static::LOGIC_AND);

                $this->setConditionItem(static::LOGIC_GROUP_LEFT.$select->{$parseType}(true).
                    static::LOGIC_GROUP_RIGHT, ':string');

                $this->setTypeAndLogic(null, $oldLogic);
            }

            // exists 支持
            elseif (is_string($key) && in_array($key, [
                ':exists',
                ':notexists',
            ], true)) {
                // having 不支持 [not] exists
                if ('having' === $this->getTypeAndLogic()[0]) {
                    $e = 'Having do not support [not] exists.';

                    throw new InvalidArgumentException($e);
                }

                if (is_object($tmp) && ($tmp instanceof self || $tmp instanceof Select)) {
                    $tmp = $tmp instanceof Select ? $tmp->databaseCondition()->makeSql() : $tmp->makeSql();
                } elseif (is_object($tmp) && $tmp instanceof Closure) {
                    $select = new static($this->connect);
                    $select->setTable($this->getTable());
                    call_user_func_array($tmp, [
                        $select,
                    ]);

                    $tmp = $select->makeSql();
                }

                $tmp = (':notexists' === $key ? 'NOT EXISTS ' : 'EXISTS ').
                    static::LOGIC_GROUP_LEFT.
                    $tmp.
                    static::LOGIC_GROUP_RIGHT;

                $this->setConditionItem($tmp, ':string');
            }

            // 其它
            else {
                // 处理字符串 "null"
                if (is_scalar($tmp)) {
                    $tmp = (array) $tmp;
                }

                // 合并字段到数组
                if (is_string($key)) {
                    array_unshift($tmp, $key);
                }

                // 处理默认 “=” 的类型
                if (2 === count($tmp) && !in_array($tmp[1], [
                    'null',
                    'not null',
                ], true)) {
                    $tmp[2] = $tmp[1];
                    $tmp[1] = '=';
                }

                // 字段
                $tmp[1] = trim($tmp[1]);

                // 特殊类型
                if (in_array($tmp[1], [
                    'between',
                    'not between',
                    'in',
                    'not in',
                    'null',
                    'not null',
                ], true)) {
                    if (isset($tmp[2]) && is_string($tmp[2])) {
                        $tmp[2] = explode(',', $tmp[2]);
                    }

                    $this->setConditionItem([$tmp[0], $tmp[1], $tmp[2] ?? null]);
                }

                // 普通类型
                else {
                    $this->setConditionItem($tmp);
                }
            }
        }

        return $this;
    }
protected function addConditions(): self
    {
        $args = func_get_args();
        $table = $this->getTable();

        // 整理多个参数到二维数组
        if (!is_array($args[0])) {
            $conditions = [$args];
        } else {
            // 一维数组统一成二维数组格式
            $oneImension = false;

            foreach ($args[0] as $key => $value) {
                if (is_int($key) && !is_array($value)) {
                    $oneImension = true;
                }

                break;
            }

            if (true === $oneImension) {
                $conditions = [$args[0]];
            } else {
                $conditions = $args[0];
            }
        }

        // 遍历数组拼接结果
        foreach ($conditions as $key => $tmp) {
            if (!is_int($key)) {
                $key = trim($key);
            }

            // 字符串表达式
            if (is_string($key) && in_array($key, [':string', ':stringSimple'], true)) {
                // 不符合规则抛出异常
                if (!is_string($tmp)) {
                    $e = sprintf('String type only supports string,but %s given.', gettype($tmp));

                    throw new InvalidArgumentException($e);
                }

                // 表达式支持
                if (false !== strpos($tmp, '{') &&
                    preg_match('/^{(.+?)}$/', $tmp, $matches)) {
                    $tmp = $this->connect->normalizeExpression(
                        $matches[1],
                        $table
                    );
                }

                $this->setConditionItem($tmp, $key);
            }

            // 子表达式
            elseif (is_string($key) && in_array($key, [
                ':subor',
                ':suband',
            ], true)) {
                $typeAndLogic = $this->getTypeAndLogic();

                $select = new static($this->connect);
                $select->setTable($this->getTable());
                $select->setTypeAndLogic($typeAndLogic[0]);

                // 逻辑表达式
                if (isset($tmp[':logic'])) {
                    if (strtolower($tmp[':logic']) === static::LOGIC_OR) {
                        $select->setTypeAndLogic(null, static::LOGIC_OR);
                    }

                    unset($tmp[':logic']);
                }

                $select = $select->addConditions($tmp);

                // 解析结果
                $parseType = 'parse'.ucwords($typeAndLogic[0]);
                $oldLogic = $typeAndLogic[1];

                $this->setTypeAndLogic(null, ':subor' ? static::LOGIC_OR : static::LOGIC_AND);

                $this->setConditionItem(static::LOGIC_GROUP_LEFT.$select->{$parseType}(true).
                    static::LOGIC_GROUP_RIGHT, ':string');

                $this->setTypeAndLogic(null, $oldLogic);
            }

            // exists 支持
            elseif (is_string($key) && in_array($key, [
                ':exists',
                ':notexists',
            ], true)) {
                // having 不支持 [not] exists
                if ('having' === $this->getTypeAndLogic()[0]) {
                    $e = 'Having do not support [not] exists.';

                    throw new InvalidArgumentException($e);
                }

                if (is_object($tmp) && ($tmp instanceof self || $tmp instanceof Select)) {
                    $tmp = $tmp instanceof Select ? $tmp->databaseCondition()->makeSql() : $tmp->makeSql();
                } elseif (is_object($tmp) && $tmp instanceof Closure) {
                    $select = new static($this->connect);
                    $select->setTable($this->getTable());
                    call_user_func_array($tmp, [
                        $select,
                    ]);

                    $tmp = $select->makeSql();
                }

                $tmp = (':notexists' === $key ? 'NOT EXISTS ' : 'EXISTS ').
                    static::LOGIC_GROUP_LEFT.
                    $tmp.
                    static::LOGIC_GROUP_RIGHT;

                $this->setConditionItem($tmp, ':string');
            }

            // 其它
            else {
                // 处理字符串 "null"
                if (is_scalar($tmp)) {
                    $tmp = (array) $tmp;
                }

                // 合并字段到数组
                if (is_string($key)) {
                    array_unshift($tmp, $key);
                }

                // 处理默认 “=” 的类型
                if (2 === count($tmp) && !in_array($tmp[1], [
                    'null',
                    'not null',
                ], true)) {
                    $tmp[2] = $tmp[1];
                    $tmp[1] = '=';
                }

                // 字段
                $tmp[1] = trim($tmp[1]);

                // 特殊类型
                if (in_array($tmp[1], [
                    'between',
                    'not between',
                    'in',
                    'not in',
                    'null',
                    'not null',
                ], true)) {
                    if (isset($tmp[2]) && is_string($tmp[2])) {
                        $tmp[2] = explode(',', $tmp[2]);
                    }

                    $this->setConditionItem([$tmp[0], $tmp[1], $tmp[2] ?? null]);
                }

                // 普通类型
                else {
                    $this->setConditionItem($tmp);
                }
            }
        }

        return $this;
    }
组装条件.

@return $this