Как безопасно использовать WHERE?



@flapflapjack

Привет.

В подготовленных запросах вопроса с экранированием – нет. А вот как правильно поступить, если класс имеет примерно такой вид:

Как контролировать например $where, которое может быть не указано, или может затрагивать другие столбцы?

<?php

Class Test {
protected $where;

public function getAll()
{
$result=$this->db->prepare("SELECT * FROM table WHERE col=:col ".$this->where);
$result->execute(array("col"=>123));
return $result->fetchAll(PDO::FETCH_ASSOC);
}

public function byDate($start,$end=false)
{
$this->where.=" data BETWEEN $start AND ".($end ? $end : "NOW()");
return $this;
}

}

P.S. для DevMan:

Вместо даты можно поставить инъекцию. Как облагородить?

$class=new Test();
var_dump($class->byDate("2021-05-01 00:00:00")->getAll());


Решения вопроса 2



@FanatPHP

Ты хочешь написать квери билдер. Практически всё уже написал.
Всего-то надо вместо значений подставлять плейсхолдеры, а сами значения запоминать в переменной.
Общий принцип такой:

class Test {
    protected $where;
    protected $params;

    public function getAll()
    {
        $result=$this->db->prepare("SELECT * FROM table WHERE 1=1 ".$this->where);
        $result->execute($this->params);
        return $result->fetchAll(PDO::FETCH_ASSOC);
    }

    public function byDate($start,$end=false)
    {
        if ($end) {
            $this->where .= " AND data BETWEEN :start AND :end";
            $this->params['end'] = $end;
        } else {
            $this->where .= " date >= :start";
        }
        $this->params['start'] = $start;
        return $this;
    }

    public function byCol($col)
    {
        $this->where .= " AND col = :col";
        $this->params['col'] = $col;
        return $this;
    }
}

$sql = new Test;
$data = $sql->byCol($col)->byDate($start)->getAll();

по-хорошему тут еще должны быть отдельные переменные для самого запроса, для order by, limit и так далее
Но начать можно с такого



3

комментария


Ответы на вопрос 0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *