Форумы xBB

Форумы xBB > Вебразработка

Боремся с Magic Quotes

Автор: dima. Последнее редактирование: 2009-02-06 03:34:51

Для тех, кто не в теме:
 
Волшебные кавычки (Magic Quotes) - это процесс автоматического экранирования входящих данных PHP скрипта. Желательно отключать директиву magic quotes и вместо этого экранировать данные в процессе разработки, если это необходимо.

Это означает, что если вы передаете скрипту такую строку: "моя строка со слэшом '\'", то она автоматически превратится в следующую: "моя строка со слэшом \'\\\'".
 
Это было когда-то сделано в целях безопасности, во избежание SQL-инъекций. Но, честное слово, приносит больше проблем, чем пользы. Пряморукие разработчики в этой фиче не нуждаются, а криворукие даже и с ней дыр понаделают.
 
В результате, начиная с PHP 5.3.0, эта фича становится DEPRECATED, а в 6-й версии PHP её и вовсе не будет.
 
Уже из-за одного этого не следует ею пользоваться. Она в любой момент может оказаться недоступной и тогда придется фиксить все свои скрипты в пожарном порядке.
 
Эту фичу можно отключить в php.ini. за нее отвечают опции magic_quotes_gpc, magic_quotes_runtime и magic_quotes_sybase.
 
Если у вас есть доступ к php.ini - хорошо. Но, как правило, его нет, так как создаваемые нами сайты, чаще всего, крутятся на серверах сторонних хостеров. Приходится менять эти опции уже в собственном скрипте.
 
Наиболее проблемной из этих опций является magic_quotes_gpc, так как она включена по умолчанию. И рано или поздно каждый разработчик с ней сталкивается. Ниже будет показано, как с ней бороться.
 
Существует функция get_magic_quotes_gpc(), которая возвращает 0, если magic_quotes_gpc = off в php.ini, и возвращает 1, если magic_quotes_gpc = on.
 
Если get_magic_quotes_gpc() == 1, то следует очистить от лишних слэшей все данные, полученные скриптом методами POST, GET и из COOKIE. Функция, очищающая строку от лишних слэшей, есть stripslashes(string $str).
 
Однако, совсем не стоит пользовать код типа следующего:
 
PHP
foreach ($_POST as $k => $v) {
    $_POST[$k] = stripslashes($v);
}

Дело в том, что $_POST[$k] может оказаться массивом и тогда stripslashes($v) заменит этот массив на строку 'array', что совсем неприятно.
 
Поэтому стоит написать свою рекурсивную функцию для очистки массивов:
 
PHP
function my_stripSlashes($param)
{
    if (! is_array($param)) {
        return stripslashes($param);
    }
    foreach ($param as $k => $v) {
        $param[$k] = my_stripSlashes($v);
    }
    return $param;
}

И именно её применить:
 
PHP
if (get_magic_quotes_gpc()) {
    $_GET    = my_stripSlashes($_GET);
    $_POST   = my_stripSlashes($_POST);
    $_COOKIE = my_stripSlashes($_COOKIE);
}

Это будет работать хорошо!
 
Только ещё одно предупреждение: не очищайте строки от слэшей дважды. Это может случиться, например, если вы сначала боретесь с Magic Quotes в различных отдельных скриптах, которые вызывают друг друга через include. Но это также может привести к неприятностям.
 
Будьте бдительны и успехов Well

8 комментариев

30.08.2009 15:16:41 #
Opera Гость dimka (UA)
Можно просто в .htaccess прописать:
php_value  magic_quotes_gpc 0
php_value  magic_quotes_runtime 0
И слеши небудут ставится...
30.08.2009 17:18:42 #
Iceweasel dima
Тоже правда. Но я предпочитаю меньше зависеть от .htaccess. Он доступен не на всех хостах с PHP.
02.09.2010 17:09:09 #
Opera Гость hell0win
Респект dima, очень пригодилось
03.09.2010 09:10:50 #
Mozilla Firefox dima
Пожалуйста Well
22.12.2010 13:35:38 #
Mozilla Firefox Гость Лешка
Огромное спасибо за статью!
22.12.2010 14:34:56 #
Mozilla Firefox dima
Well
19.03.2011 15:49:20 #
Mozilla Firefox Гость гостть
не пойму куда вписать что бы отключить эту функциюNot so
19.03.2011 16:00:08 #
Mozilla Firefox dima
В начало скрипта

Ответить:

Представиться как     Антибот:
   

Просьба не постить мусор. Пользуйтесь кнопкой предварительного просмотра на панели инструментов редактора.

Введите логин: и пароль: (

© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.