[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Ох уж эти Magic Quotes
Игорь_Vasinsky
Дело вот собстевно в чём:

для отправки данных в базу MySQL нужно обезопасить себя как следовать, и как известно самой используемой и рекомендуемой является функция для обработки входящих данных:

mysql_real_escape_string()


и она справляется со своей ролью удачно (экранирование таких символов как одинарная кавычка (’), двойная кавычка (”), обратный слэш (\) или NULL-символ)

И всё ю хорошо, но в версиях PHP 4 и PHP 5 есть опция в php.ini

;magic_quotes_gpc = On/OFF

и если magic_quotes_qpc включена, то экранируются спецсимволы из следующих источников: $_GET, $_POST, $_REQUEST, $_COOKIE, $_ENV

И получается все счасливы и все довольны, но есть одно но:

админ хостинга сам решает включить или отключить эту опцию в PHP, а значит

если опция откл - а мы на неё надеемся - и данные пролетают не обработанными в БД, что соответственно вызавит ошибку

а если опция включена - а мы решили подстраховаться и используем
mysql_real_escape_string() для обработки данных перед отправкой в БД то получаем двойное экранирование и следовательно ..мороку.. в выводе


Так вот когда такой вопрс был поставлен передо мной всем нам известным участником форума, то пришлось обратиться к mr. Google, который выдал нам возможные варианты:

оказывается там я узнаю о ещё 2х опциях на которые предётся обратить внимание:

magic_quotes_runtime
magic_quotes_sybase


и каждая из них может быть включена (On), либо выключена (Off).

Данные директивы отвечают за экранирование спецсимволов в различных данных поступающих в php-скрипт и выводимых из php-скрипта.


Директива magic_quotes_gpc экранирует только одинарные кавычки, если включена также директива magic_quotes_sybase. Причем экранирует она одинарную кавычку одинарной кавычкой:

index.php?test=123′

$test = $_REQUEST['test'];

echo $test; // выведет: ”123”


Цитата:

magic_quotes_runtime

Если включена эта директива, то большинство функций, которые возвращают данные из базы например или текстовых файлов, будут возвращать заэкранированные текстовые данные. А если в добавок включена директива magic_quotes_sybase, то экранируются только одинарные кавычки, причем не обратным слэшем, а такой же одинарной кавычкой.

magic_quotes_sybase

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

Первое что приходит в голову - Куда я полез...... huh.gif и всё же предложены следующие варианты решения задачи:

1. Проверка:

Предложено:

if (!get_magic_quotes_gpc()) {
$test = addslashes($test);
}


но так ка я буду использывать mysql_real_escape_string(), то мне больше подходит:

if (!(!get_magic_quotes_gpc())) { // замудрил
$test = stripslashes($test);
}


т.е. если MQ включены - то я удалю экранировку

2. Дополнительные строки, непосредственно в коде PHP

ini_set(’magic_quotes_runtime’, 0);
ini_set(’magic_quotes_sybase’, 0);



3. Редактирование .htaccess

magic_quotes_gpc = Off


И вот, что хочется узнать: мне что всё это нужно будет сделать, если я хочу обходить эти блин волшебные ковычки ?

Или достаточно: ....




Спустя 6 минут, 32 секунды (22.03.2010 - 17:20) twin написал(а):
Ну дал же я ссыль... чего тыго мучаешься, почитать не хочешь
/**  
* Убиваем магические кавычки
*/

function stripslashesDeep($data)
{
if(is_array($data))
$data = array_map("stripslashesDeep", $data);
else
$data = stripslashes($data);
return $data;
}

if(get_magic_quotes_gpc())
{
$_GET = stripslashesDeep($_GET);
$_POST = stripslashesDeep($_POST);
$_COOKIE = stripslashesDeep($_COOKIE);
$_REQUEST = stripslashesDeep($_REQUEST);
}

Спустя 10 минут, 19 секунд (22.03.2010 - 17:30) krasilich написал(а):
Вот я выработал правило для себя: каждый проект начинается с создания .htaccess где делается две вещи.
Первое - установить кодировку utf8.
Второе - отключить magic_quotes всевозможных вариаций.

А дальше хоть потоп=))

Спустя 1 минута, 19 секунд (22.03.2010 - 17:31) Игорь_Vasinsky написал(а):
twin я вижу код и верю что он работает, а понять как он работает у меня не получается, и стало быть мне остаётся использывать его как готовый шаблон.

А нужно ведь вникнуть в суть.
Ну ладно. спасиб.
Про кодировку тож тока узнал..спасиб.

Спустя 3 минуты, 38 секунд (22.03.2010 - 17:35) Игорь_Vasinsky написал(а):
Цитата
if(get_magic_quotes_gpc())
{
$_GET = stripslashesDeep($_GET);
$_POST = stripslashesDeep($_POST);
$_COOKIE = stripslashesDeep($_COOKIE);
$_REQUEST = stripslashesDeep($_REQUEST);
}


почему бы просто этим не обойтись

Спустя 2 минуты, 29 секунд (22.03.2010 - 17:37) Игорь_Vasinsky написал(а):
шаблон так шаблон. тема закрыта всем спасибо.

Спустя 17 минут, 37 секунд (22.03.2010 - 17:55) Adil написал(а):
Цитата (Игорь_Vasinsky @ 22.03.2010 - 18:31)
twin я вижу код и верю что он работает, а понять как он работает у меня не получается, и стало быть мне остаётся использывать его как готовый шаблон.


а что именно не понятно в его коде?

Спустя 1 минута, 27 секунд (22.03.2010 - 17:57) Игорь_Vasinsky написал(а):
Вот эта часть:

Цитата
function stripslashesDeep($data)
{
if(is_array($data))
$data = array_map("stripslashesDeep", $data);
else
$data = stripslashes($data);
return $data;
}


и откуда $data

Спустя 7 минут, 46 секунд (22.03.2010 - 18:04) Adil написал(а):
Есть такая функция stripslashes(). Она удаляет экранирующие слэши. Но дело в том, что ей надо передать строку, а не массив.
Поэтому надо создать свою функцию stripslashesDeep(),чтобы она умела обрабатывать как массив, так и строки:
function stripslashesDeep($data)

Она принимает параметр $data.
Что происходит внутри функции?
  if(is_array($data))  


Проверяется, передали в функцию массив. Если это массив, то ко всем элементам этого массива через функцию array_map() применяется функция stripslashes().
array_map("stripslashesDeep", $data);

Цитата
array_map — Применить функцию обратного вызова ко всем элементам указанных массивов

Но если это не массив, то просто применяем функцию stripslashes()

И конец функции, возвращаем обработанные данные:
   return $data; 




Вторая часть:

Функция уже готова, и если включена директива magic quotes:
 if(get_magic_quotes_gpc()) 

то убираем слэши со всех данных, применив функцию stripslashesDeep().

Спустя 4 минуты, 44 секунды (22.03.2010 - 18:09) Игорь_Vasinsky написал(а):
Спасибо. понятненько.

Спустя 7 минут, 2 секунды (22.03.2010 - 18:16) twin написал(а):
krasilich
Цитата
Второе - отключить magic_quotes всевозможных вариаций.

А дальше хоть потоп=))

Вот именно. А потоп случится и обязательно.
1. Тот, кто после тебя будет обслуживать сайт, может случайно затереть .htaccess с твоими настройками.
2. Если php стоит не как модуль аппача, а как CGI, то флаги не сработают. Нужно ini_set(); вместо этого.

По этому на Бога надейся, а сам не плошай. Скрипт должен как можно меньше зависить от внешних настроек.

Спустя 4 минуты, 37 секунд (22.03.2010 - 18:21) Игорь_Vasinsky написал(а):
Цитата
ini_set();


иногда работает только

ini_get()

я читал.... sad.gif

Спустя 3 минуты, 24 секунды (22.03.2010 - 18:24) twin написал(а):
Вот именно. Так что уповать на тонкую настройку сервера не надь. Нужно скрипт делать автономным.

Спустя 1 минута (22.03.2010 - 18:25) krasilich написал(а):
twin
1. Ну не умею я писать код для людей, которые только тем и занимаются, что подтирают нужные файлы.
2. Да, согласен, но опять же в большинстве случаев проект пишется под конкретную систему. И перенос сайта, не такое уже и буденное дело. Хотя да... проблема есть, но я лучше в документацию добавлю строчку, мол php только как модуль апача.

Спустя 11 минут, 7 секунд (22.03.2010 - 18:36) twin написал(а):
Цитата
1. Ну не умею я писать код для людей, которые только тем и занимаются, что подтирают нужные файлы.

Сам ни разу не попадался? smile.gif
А вот на счет
Цитата
в большинстве случаев проект пишется под конкретную систему

заблуждение. Проект может и да, но ты каждый раз пишешь с чистого листа? И откуда ты вообще можешь знать, какая там система?
Я вот часто пишу сайты людям, у которых нет хостинга. Оно и логично - зачем заранее деньги тратить. Так что, потом его озадачить - мол ты туда не ходи, снег башка попадет.
Писать стараться нужно так, что бы работало везде.

Спустя 29 минут, 29 секунд (22.03.2010 - 19:06) glock18 написал(а):
Цитата (twin @ 22.03.2010 - 15:16)
Нужно ini_set(); вместо этого.


ini_set не может переопределить magic_quotes_gpc из-за того, что экранирование данных (а значит и применение этой директивы) выполняется еще до входа в скрипт (что вполне логично). таким образом, изменить magic_quotes_gpc можно только тремя способами:

1. php.ini

и для апача
2. httpd.conf
3. .htaccess

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

Спустя 25 минут, 40 секунд (22.03.2010 - 19:31) Игорь_Vasinsky написал(а):
что и требовалось доказать.

Спустя 55 минут, 27 секунд (22.03.2010 - 20:27) twin написал(а):
Вот Бог миловал пока от таких вариантов, как CGI))) Но на сколько я знаю, если PHP стоит не как модуль, то он запускается каждый раз, как запрашивается скрипт. Соответственно каждый раз происходит его конфигурирование. По этому для настройки директив и используется не .htaccess, а php.ini
По этому должен он отреагировать на ini_set() мне кажется. По крайней мере register_globals отключается так.

Спустя 50 минут, 31 секунда (22.03.2010 - 21:17) glock18 написал(а):
не так. .htaccess принадлежит веб-серверу apache. И служит он для того, чтобы налету переопределять настройки сервера, заданные в httpd.conf. Вообще все настройки должны задаваться в таком порядке (чем ниже порядковый номер, тем предпочтительнее использовать):

1. php.ini
2. httpd.conf
3. .htaccess
4. ini_set

некоторые настройки не могут быть изменены на определенных этапах. и естественно изменение magic_quotes_gpc внутри скрипта с помощью ini_set не поможет. мне это кажется очевидным донельзя. если все же есть сомнения:

создаем файло
<?php
print_r($_GET);
ini_set('magic_quotes_gpc', 0);
print_r($_GET);
?>

включаем magic_quotes в php.ini, перезапускаем сервер и запускаем через браузер с каким-нибудь параметром с кавычками.

против того, что сработает, есть один очень веский довод - глобальные массивы формируются перед выполнением скрипта, а ini_set выполняется внутри него.

то же самое касается и register_globals. не проверял, но согласно мануалу эта директива создает глобальные переменные, а не ищет их в массивах, если встречает неинициализированную. таким образом, если выключить register_globals внутри скрипта эти переменные останутся.

PS: для настройки php .htaccess и ini_set нужно использовать в самую последнюю очередь. потому как они обрабатываются каждый при запросе к странице. опять же настройки сервера (такие как RewriteRule's и тп) тоже лучше прописывать в httpd.conf. Из htaccess они достаточно тормознуто обрабатываются.

ну а настройки пыха - php.ini. если не там, то в httpd.conf и далее по списку. хотя и httpd.conf и .htaccess позволяют менять настройки php, к нему они не относятся напрямую никак.

Спустя 12 минут, 46 секунд (22.03.2010 - 21:30) twin написал(а):
Убедил)) Тем более не нужно ориентироваться на настройки. smile.gif


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.