iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
Modern Web

Laravel 那麼好用還需要自幹框架嗎系列 第 18

Day 18:ORM 的 where() 轉換

  • 分享至 

  • xImage
  •  

昨天我們追蹤到了 Query/Builderwhere()

其實作非常的多,內容如下:

/**
 * Add a basic where clause to the query.
 *
 * @param  \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression  $column
 * @param  mixed  $operator
 * @param  mixed  $value
 * @param  string  $boolean
 * @return $this
 */
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
    if ($column instanceof ConditionExpression) {
        $type = 'Expression';

        $this->wheres[] = compact('type', 'column', 'boolean');

        return $this;
    }

    // If the column is an array, we will assume it is an array of key-value pairs
    // and can add them each as a where clause. We will maintain the boolean we
    // received when the method was called and pass it into the nested where.
    if (is_array($column)) {
        return $this->addArrayOfWheres($column, $boolean);
    }

    // Here we will make some assumptions about the operator. If only 2 values are
    // passed to the method, we will assume that the operator is an equals sign
    // and keep going. Otherwise, we'll require the operator to be passed in.
    [$value, $operator] = $this->prepareValueAndOperator(
        $value, $operator, func_num_args() === 2
    );

    // If the column is actually a Closure instance, we will assume the developer
    // wants to begin a nested where statement which is wrapped in parentheses.
    // We will add that Closure to the query and return back out immediately.
    if ($column instanceof Closure && is_null($operator)) {
        return $this->whereNested($column, $boolean);
    }

    // If the column is a Closure instance and there is an operator value, we will
    // assume the developer wants to run a subquery and then compare the result
    // of that subquery with the given value that was provided to the method.
    if ($this->isQueryable($column) && ! is_null($operator)) {
        [$sub, $bindings] = $this->createSub($column);

        return $this->addBinding($bindings, 'where')
            ->where(new Expression('('.$sub.')'), $operator, $value, $boolean);
    }

    // If the given operator is not found in the list of valid operators we will
    // assume that the developer is just short-cutting the '=' operators and
    // we will set the operators to '=' and set the values appropriately.
    if ($this->invalidOperator($operator)) {
        [$value, $operator] = [$operator, '='];
    }

    // If the value is a Closure, it means the developer is performing an entire
    // sub-select within the query and we will need to compile the sub-select
    // within the where clause to get the appropriate query record results.
    if ($this->isQueryable($value)) {
        return $this->whereSub($column, $operator, $value, $boolean);
    }

    // If the value is "null", we will just assume the developer wants to add a
    // where null clause to the query. So, we will allow a short-cut here to
    // that method for convenience so the developer doesn't have to check.
    if (is_null($value)) {
        return $this->whereNull($column, $boolean, $operator !== '=');
    }

    $type = 'Basic';

    $columnString = ($column instanceof ExpressionContract)
        ? $this->grammar->getValue($column)
        : $column;

    // If the column is making a JSON reference we'll check to see if the value
    // is a boolean. If it is, we'll add the raw boolean string as an actual
    // value to the query to ensure this is properly handled by the query.
    if (str_contains($columnString, '->') && is_bool($value)) {
        $value = new Expression($value ? 'true' : 'false');

        if (is_string($column)) {
            $type = 'JsonBoolean';
        }
    }

    if ($this->isBitwiseOperator($operator)) {
        $type = 'Bitwise';
    }

    // Now that we are working with just a simple query we can put the elements
    // in our array and add the query binding to our array of bindings that
    // will be bound to each SQL statements when it is finally executed.
    $this->wheres[] = compact(
        'type', 'column', 'operator', 'value', 'boolean'
    );

    if (! $value instanceof ExpressionContract) {
        $this->addBinding($this->flattenValue($value), 'where');
    }

    return $this;
}

我們這邊只看 "id" "=" 的場景。

if (! $value instanceof ExpressionContract) {
    $this->addBinding($this->flattenValue($value), 'where');
}

return $this;

這邊在 $this->bindings 裡面加上對應的條件之後,就將自己回傳了。

接著我們就看到了 $this->whereKey($id)->first($columns)first() 這部分。

/**
 * Execute the query and get the first result.
 *
 * @param  array|string  $columns
 * @return TValue|null
 */
public function first($columns = ['*'])
{
    return $this->take(1)->get($columns)->first();
}

上一篇
Day 17:ORM 轉換
系列文
Laravel 那麼好用還需要自幹框架嗎18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言