У меня есть следующие блоки кода в обработчике формы PHP:
function filter($data) { $data = trim(htmlentities(strip_tags($data))); if (get_magic_quotes_gpc()) { $data = stripslashes($data); } $data = mysql_real_escape_string($data); return $data; } foreach($_POST as $key => $value) { $data[$key] = filter($value); }
Я изменяю свою форму, чтобы теперь включать группы флажков:
например:
<input type="checkbox" name="phone_prefs[]" value="prefer_home"> <input type="checkbox" name="phone_prefs[]" value="prefer_cell"> <input type="checkbox" name="phone_prefs[]" value="prefer_work"> etc.
Из-за этого кода у меня теперь есть массивы в переменных _POST, а не только в строках.
Правильно ли я полагаю, что моя функция filter()
не будет собственно деактивировать массивы? Какие изменения необходимо внести в мою функцию filter()
чтобы убедиться, что массивы для флажков полностью очищены и не являются легкой целью для SQL-инъекций?
Ваша функция довольно хорошая, но если вы сделаете ее рекурсивной, она сканирует вложенные массивы для вас
function filter(&$array) { $clean = array(); foreach($array as $key => &$value ) { if( is_array($value) ) { filter($value); } else { $value = trim(strip_tags($value)); if (get_magic_quotes_gpc()) { $data = stripslashes($value); } $data = mysql_real_escape_string($value); } } } filter($_POST); # filters $_POST and any nested arrays by reference
Изменить: Оставить htmlentities()
. Если вам это нужно, используйте его при выводе значений, а не при получении их в качестве входных данных.
Что касается SQL-инъекции, я бы переключился на PDO с помощью подготовленного оператора .
Вы можете использовать простой is_array()
для своих значений, чтобы проверить массив, а затем is_array()
его. Вы правы, так как это значит, что ваша функция filter
не будет правильно обрабатывать массивы.
Изменить: если вы используете PDO и подготовленный оператор, вам больше не понадобится mysql_real_escape_string
. strip_tags
, htmlentities
и trim
также не нужны для безопасного хранения информации в базе данных, они необходимы, когда вы выводите информацию в браузер ( trim
не обязательно …), хотя для этого достаточно htmlspecialchars
. Всегда лучше правильно подготовить вашу информацию / вывод для носителя, который вы выводите в этот момент.
array_walk_recursive($array,function(&$item){ $item=mysql_real_escape_string($item); });
Вы используете foreach в $ _POST, который только петли один раз, используя Array и обрабатывая его как строку.
Попробуйте использовать:
foreach($_POST['phone_prefs'] as $key => $value)
РЕДАКТИРОВАТЬ:
Я считаю, что неправильно понял ваш вопрос:
foreach($_POST as $key => $value) if (is_array($value)) foreach($_POST[$key] as $key2 => $value2) /* Setting stuff */ else /* Setting same stuff */
Вместо того, чтобы вручную деактивировать ввод, используйте всегда подготовленные заявления с заполнителями . Это будет прозрачно передавать входные данные в базу данных таким образом, что ее не нужно экранировать и, следовательно, не подвергать SQL-инъекции. Это лучшая современная практика.
Для получения дополнительной информации см. Следующее: http://php.net/manual/en/pdo.prepared-statements.php
Я использую это на разных сайтах, которые я создал:
public function clean($dirty) { if (!is_array($dirty)) { $dirty = ereg_replace("[\'\")(;|`,<>]", "", $dirty); $dirty = mysql_real_escape_string(trim($dirty)); $clean = stripslashes($dirty); return $clean; } $clean = array(); foreach ($dirty as $p => $data) { $data = ereg_replace("[\'\")(;|`,<>]", "", $data); $data = mysql_real_escape_string(trim($data)); $data = stripslashes($data); $clean[$p] = $data; } return $clean; }
Использование mysql_real_escape_string означает, что перед использованием функции требуется соединение MySQL, что не очень удобно. В этом случае я использовал работу:
function real_escape_string($aQuery) { if (!is_string($aQuery)) { return FALSE; } else { return strtr($aQuery, array( "\x00" => '\x00', "\n" => '\n', "\r" => '\r', '\\' => '\\\\', "'" => "\'", '"' => '\"', "\x1a" => '\x1a' )); } }
Но, безусловно, лучше всего использовать PDO-подготовленный оператор вместо mysql. Вам понравится.