PHP « PDO — фильтрация строки от инъекций

Всем доброго времени суток. Начал изучать PDO, и возник такой вопрос. Не могу понять как в моем куске кода отфильтровать входящие данные $_POST и обезопасится от инъекций.

/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .php.geshi_code {font-family:monospace;} .php.geshi_code .imp {font-weight: bold; color: red;} .php.geshi_code .kw1 {color: #b1b100;} .php.geshi_code .kw2 {color: #000000; font-weight: bold;} .php.geshi_code .kw3 {color: #990000;} .php.geshi_code .co1 {color: #666666; font-style: italic;} .php.geshi_code .co2 {color: #666666; font-style: italic;} .php.geshi_code .co3 {color: #0000cc; font-style: italic;} .php.geshi_code .co4 {color: #009933; font-style: italic;} .php.geshi_code .coMULTI {color: #666666; font-style: italic;} .php.geshi_code .es0 {color: #000099; font-weight: bold;} .php.geshi_code .es1 {color: #000099; font-weight: bold;} .php.geshi_code .es2 {color: #660099; font-weight: bold;} .php.geshi_code .es3 {color: #660099; font-weight: bold;} .php.geshi_code .es4 {color: #006699; font-weight: bold;} .php.geshi_code .es5 {color: #006699; font-weight: bold; font-style: italic;} .php.geshi_code .es6 {color: #009933; font-weight: bold;} .php.geshi_code .es_h {color: #000099; font-weight: bold;} .php.geshi_code .br0 {color: #009900;} .php.geshi_code .sy0 {color: #339933;} .php.geshi_code .sy1 {color: #000000; font-weight: bold;} .php.geshi_code .st0 {color: #0000ff;} .php.geshi_code .st_h {color: #0000ff;} .php.geshi_code .nu0 {color: #cc66cc;} .php.geshi_code .nu8 {color: #208080;} .php.geshi_code .nu12 {color: #208080;} .php.geshi_code .nu19 {color:#800080;} .php.geshi_code .me1 {color: #004000;} .php.geshi_code .me2 {color: #004000;} .php.geshi_code .re0 {color: #000088;} .php.geshi_code span.xtra { display:block; }
$brand = check($_POST['brand']));
$capacity = intval($_POST['capacity']);

$where = array("categoryID = 157", "tax = 0");
if(!empty($brand)) { $where[] = "brand = '$brand' "; }
if(!empty($ACapacity)) { $where[] = "capacity = '$capacity'"; }

$q = $DBH->prepare("SELECT * FROM products "
 . (!empty($where) ? " WHERE " . implode(' AND ', $where) : "") );

$q->execute();

Толи я запутался, то ли время уже позднее, но у меня. не получается применить здесь плейсхолдеры
Достаточно ли будет здесь использовать $pdo->quote($brand); ?
в описании читал, что не рекомендуют использовать quote(); т.к. не гарантируют защиту от инъекций.
Или подскажите пожалуйста, как правильно здесь применить плейсхолдеры.
Заранее благодарен за помощь.

1 ответов


Вы убиваете саму суть PDO, подставляя значения руками прямо в запрос

$stmt = $dbh->prepare('SELECT * FROM products WHERE categoryID = :cat_id AND tax = :tax AND brand = :brand AND capacity = :capacity');
$data = array(
    ':cat_id' => $catId,
    ':tax' => $tax,
    ':brand' => $brand,
    ':capacity' => $capacity
);
foreach ($data as $k => $v)
    $stmt->bindValue($k, $v);
Если уж настолько нужен динамический набор where-параметров (а он наверняка не нужен)
// формируем массив условий
$values = array('categoryID' => $catID, 'tax' => $tax);
if (...) {
// добавление записей в values
}
// формируем непосредственно строку условий и создаем запрос
$where = array();
foreach ($values as $k => $v)
    $where[] = $k.' = :'.$k;
$q = 'SELECT * FROM products WHERE '.implode(' AND ', $where);
$stmt = $dbh->prepare($q);
// непосредственно подстановка значений
foreach ($values as $k => $v)
    $stmt->bindValue(':'.$k, $v);
PDO сам разберется, скармливаете вы ему строку или число, сам заэкранирует и подставит. В идеале - к сожалению, в PDO-MySQL идеал по умолчанию выключен, если память не изменяет - подстановка ведется на уровне базы данных, которая принимает запрос с плейсхолдерами и переменные, которыми нужно заполнить плейсхолдеры, в этом случае никаких инъекций не будет в принципе, потому что запрос не будет принят в качестве переменной.