Этот запрос слишком экранирован! Нужна простая идея - PullRequest
1 голос
/ 16 марта 2012

Итак, я создал простую функцию PHP, которая «ОБНОВЛЯЕТ» мою строку MySQL, просто обновляя массив, полученный PHP.

function db_updateproduct(array $new, array $old = array()) {
    $diff = array_diff($new, $old);
    return 'INSERT INTO table (`'.mysql_real_escape_string(implode(array_keys($diff), '`,`')).'`) VALUES \''.mysql_real_escape_string(implode(array_values($diff), '\',\'')).'\'';
}

...


Обновление (с подтвержденным ответом)

function db_updateproduct(array $new, array $old = array()) {
    $diff = array_diff($new, $old);
    return 'INSERT INTO `Product` (`'.implode(array_keys($diff), '`,`').'`) VALUES (\''
        .implode(array_map('mysql_real_escape_string', array_values($diff)), '\', \'').'\')';
}

сейчас ...

echo db_updateproduct(array('a' => 'on\'e', 'b' => 'two', 'c' => 'three'));

возвращается:

INSERT INTO `Product` (`a`,`b`,`c`) VALUES ('on\'e', 'two', 'three')

(Как и ожидалось / хотел!)

Ответы [ 2 ]

6 голосов
/ 16 марта 2012

Вы можете запустить функцию escape для ключей и значений с помощью array_map():

$ escaped_keys = array_map ('mysql_real_escape_string', array_keys($ Diff));

$escaped_values = array_map('mysql_real_escape_string', array_values($diff));

Затем вы можете применить магию implode() к этим двум массивам.


ОБНОВЛЕНИЕ: Как правильно указал @YourCommonSense, на самом деле не имеет смысла запускать mysql_real_escape_string() для значений, которые будут использоваться в запросе как имена полей / имена таблиц / и т.д.Он корректно экранирует \x00, \n, \r, \, ', " и \x1a, но НЕ экранирует обратный тик , поэтому запрос по-прежнемууязвимы для атак.

Вы должны проверить имена полей (чтобы можно было использовать только ожидаемые имена) или, что еще лучше, использовать подготовленные запросы (я рекомендую PDO).

Рекомендуемое чтение:

1 голос
/ 16 марта 2012

На самом деле выполнение mysql_real_escape_string для ключей массива является примером абсолютно бесполезного действия.

...