Я видел десятки фрагментов PHP, которые выглядят следующим образом:
function DB_Quote($string) { if (get_magic_quotes_gpc() == true) { $string = stripslashes($string); } return mysql_real_escape_string($string); }
Что произойдет, если я вызову DB_Quote("the (\\) character is cool");
? (Спасибо jspcal!)
Разве мы не должны get_magic_quotes_gpc() == true
разрезы только тогда, когда get_magic_quotes_gpc() == true
и значение, полученное из $_COOKIE
$_GET
, $_POST
или $_COOKIE
?
Да, я тоже видел десятки PHP-фрагментов. Это немного грустно.
Волшебные кавычки являются проблемой ввода. Он должен быть исправлен на этапе ввода, итерации массивов GET / POST / COOKIES и удаления косых черт, если вам нужно, чтобы ваше приложение запускалось на серверах, используя ложную архаичную ошибку, которая является magic_quotes_gpc
. Простой альтернативой является обнаружение опции магических кавычек и смерть с ошибкой «ваш сервер».
mysql_real_escape_string
– проблема вывода. Его нужно запускать на выходе из сценария, по заголовку контента в базу данных, если вы не используете параметризованные запросы (которые вы обязательно должны учитывать).
Это две отдельные несвязанные стадии в программе. Вы не можете поместить их в одну и ту же функцию, заманчиво, хотя может попытаться инкапсулировать всю вашу обработку строк в один квадрат.
Разве мы не должны сбрасывать разрезы только тогда, когда […] значение возникло из супергелблов $ _GET, $ _POST или $ _COOKIE?
Да, точно. Вот почему фрагмент, который вы цитировали, действительно вреден. Поскольку отслеживание происхождения строки нецелесообразно (особенно, поскольку вы можете комбинировать строки из разных источников, один из которых разрезан, а другой нет), вы не можете сделать это в одной функции. Это должно быть две отдельные функции обработки строк, вызываемые в соответствующее время.
Первый шаг состоит в том, чтобы полностью отключить магические кавычки и выдавать большие неувядаемые предупреждения, если он включен.
Если это не вариант для вас, то, на мой взгляд, лучший способ – удалить все магические кавычки все время.
// in an include used on every page load: if (get_magic_quotes_gpc()) { foreach (array('_GET', '_POST', '_COOKIE', '_REQUEST') as $src) { foreach ($$src as $key => $val) { $$src[$key] = stripslashes($val); } } }
Небольшой удар производительности, но даст вам больше удовольствия от работы при работе с вашими переменными с этого момента.
да, как сказал dav, вплоть до сценария, чтобы использовать только stripslashes при вводе формы …
если вы вызываете stripslashes со строкой «O'Reilly», строка не будет изменена. если вы вызываете stripslashes строкой вроде: «символ обратной косой черты (\) крут», результат заменит escape-последовательность \) на). поэтому, используя эту функцию для всех значений db, можно было бы тонко разбить вещи, но это, возможно, не заметилось.
как и многие приложения, вы также можете просто не поддерживать режим магических котировок. проверьте его и распечатайте сообщение об ошибке, если оно включено. он был отключен по умолчанию в течение многих лет, и это не рекомендуется.
Вы можете попробовать сделать следующее в $ _GET, $ _POST или $ _COOKIE, прежде чем делать с ними что-нибудь еще:
<?php if (get_magic_quotes_gpc ()) { $_POST = array_map ('stripslashes', $_POST); } ?>
Обратите внимание, что это будет работать, только если ваш входной массив «плоский» (не содержит подмассивов). Если вы ожидаете sub-массивы на входе, вам нужно будет написать свой собственный обратный вызов для его обработки. Что-то вроде
<?php function slashField ($input) { if (is_array ($input)) { foreach ($input as $key => $row) { $input [$key] = slashField ($row); } } else { $input = stripslashes ($input); } return ($input); } if (get_magic_quotes_gpc ()) { $_POST = array_map ('slashfield', $_POST); } ?>
Номер 6 является правильной идеей, но не работает, потому что до тех пор, пока PHP 5.4 $$ src [$ key] не использует синтаксис переменной переменной в $ src [$ key], который интерпретируется как $ src [0], создавая переменную $ _, которая бесполезно. Просто используйте & (ссылочный оператор) на $ val и $ val = stripslashes ($ val). Кроме того, в противном случае, начиная с PHP 5.4, вы, вероятно, получите ошибку, потому что PHP не будет просто отбрасывать _ в 0