src/Query.php
public function where($field, $cond = null, $value = null, $kind = 'where', $num_args = null)
    {
        // Number of passed arguments will be used to determine if arguments were specified or not
        if ($num_args === null) {
            $num_args = func_num_args();
        }

        // Array as first argument means we have to replace it with orExpr()
        if (is_array($field)) {
            // or conditions
            $or = $this->orExpr();
            foreach ($field as $row) {
                if (is_array($row)) {
                    call_user_func_array([$or, 'where'], $row);
                } else {
                    $or->where($row);
                }
            }
            $field = $or;
        }

        if ($num_args === 1 && is_string($field)) {
            $this->args[$kind][] = [$this->expr($field)];

            return $this;
        }

        // first argument is string containing more than just a field name and no more than 2
        // arguments means that we either have a string expression or embedded condition.
        if ($num_args === 2 && is_string($field) && !preg_match('/^[.a-zA-Z0-9_]*$/', $field)) {
            // field contains non-alphanumeric values. Look for condition
            preg_match(
                '/^([^ <>!=]*)([><!=]*|( *(not|is|in|like))*) *$/',
                $field,
                $matches
            );

            // matches[2] will contain the condition, but $cond will contain the value
            $value = $cond;
            $cond = $matches[2];

            // if we couldn't clearly identify the condition, we might be dealing with
            // a more complex expression. If expression is followed by another argument
            // we need to add equation sign  where('now()',123).
            if (!$cond) {
                $matches[1] = $this->expr($field);

                $cond = '=';
            } else {
                $num_args++;
            }

            $field = $matches[1];
        }

        switch ($num_args) {
            case 1:
                $this->args[$kind][] = [$field];
                break;
            case 2:
                if (is_object($cond) && !$cond instanceof Expressionable && !$cond instanceof Expression) {
                    throw new Exception([
                        'Value cannot be converted to SQL-compatible expression',
                        'field'=> $field,
                        'value'=> $cond,
                    ]);
                }

                $this->args[$kind][] = [$field, $cond];
                break;
            case 3:
                if (is_object($value) && !$value instanceof Expressionable && !$value instanceof Expression) {
                    throw new Exception([
                        'Value cannot be converted to SQL-compatible expression',
                        'field'=> $field,
                        'cond' => $cond,
                        'value'=> $value,
                    ]);
                }

                $this->args[$kind][] = [$field, $cond, $value];
                break;
        }

        return $this;
    }
public function where($field, $cond = null, $value = null, $kind = 'where', $num_args = null)
    {
        // Number of passed arguments will be used to determine if arguments were specified or not
        if ($num_args === null) {
            $num_args = func_num_args();
        }

        // Array as first argument means we have to replace it with orExpr()
        if (is_array($field)) {
            // or conditions
            $or = $this->orExpr();
            foreach ($field as $row) {
                if (is_array($row)) {
                    call_user_func_array([$or, 'where'], $row);
                } else {
                    $or->where($row);
                }
            }
            $field = $or;
        }

        if ($num_args === 1 && is_string($field)) {
            $this->args[$kind][] = [$this->expr($field)];

            return $this;
        }

        // first argument is string containing more than just a field name and no more than 2
        // arguments means that we either have a string expression or embedded condition.
        if ($num_args === 2 && is_string($field) && !preg_match('/^[.a-zA-Z0-9_]*$/', $field)) {
            // field contains non-alphanumeric values. Look for condition
            preg_match(
                '/^([^ <>!=]*)([><!=]*|( *(not|is|in|like))*) *$/',
                $field,
                $matches
            );

            // matches[2] will contain the condition, but $cond will contain the value
            $value = $cond;
            $cond = $matches[2];

            // if we couldn't clearly identify the condition, we might be dealing with
            // a more complex expression. If expression is followed by another argument
            // we need to add equation sign  where('now()',123).
            if (!$cond) {
                $matches[1] = $this->expr($field);

                $cond = '=';
            } else {
                $num_args++;
            }

            $field = $matches[1];
        }

        switch ($num_args) {
            case 1:
                $this->args[$kind][] = [$field];
                break;
            case 2:
                if (is_object($cond) && !$cond instanceof Expressionable && !$cond instanceof Expression) {
                    throw new Exception([
                        'Value cannot be converted to SQL-compatible expression',
                        'field'=> $field,
                        'value'=> $cond,
                    ]);
                }

                $this->args[$kind][] = [$field, $cond];
                break;
            case 3:
                if (is_object($value) && !$value instanceof Expressionable && !$value instanceof Expression) {
                    throw new Exception([
                        'Value cannot be converted to SQL-compatible expression',
                        'field'=> $field,
                        'cond' => $cond,
                        'value'=> $value,
                    ]);
                }

                $this->args[$kind][] = [$field, $cond, $value];
                break;
        }

        return $this;
    }
Adds condition to your query.

Examples:
$q->where('id',1);

By default condition implies equality. You can specify a different comparison
operator by either including it along with the field or using 3-argument
format:
$q->where('id>','1');
$q->where('id','>',1);

You may use Expression as any part of the query.
$q->where($q->expr('a=b'));
$q->where('date>',$q->expr('now()'));
$q->where($q->expr('length(password)'),'>',5);

If you specify Query as an argument, it will be automatically
surrounded by brackets:
$q->where('user_id',$q->dsql()->table('users')->field('id'));

You can specify OR conditions by passing single argument - array:
$q->where([
['a','is',null],
['b','is',null]
]);

If entry of the OR condition is not an array, then it's assumed to
be an expression;

$q->where([
['age',20],
'age is null'
]);

The above use of OR conditions rely on orExpr() functionality. See
that method for more information.

To specify OR conditions
$q->where($q->orExpr()->where('a',1)->where('b',1));

@param mixed  $field    Field, array for OR or Expression
@param mixed  $cond     Condition such as '=', '>' or 'is not'
@param mixed  $value    Value. Will be quoted unless you pass expression
@param string $kind     Do not use directly. Use having()
@param string $num_args When $kind is passed, we can't determine number of
actual arguments, so this argument must be specified.

@return $this