"Волшебные кавычки" в PHP
Дата публикации: 08/10/2008Как известно, PHP делает много дополнительной работы, предоставляя программисту уже обработанные данные. В частности, это относится к обработке данных, передаваемых в программу. Способ передачи может быть различным - это и заполненная форма и информация содержащаяся в "cookies" и загруженные пользователем файлы. Программист автоматически получает эти данные через переменные, которые создает PHP. Лучше всего для чтения данных введенных пользователем использовать специальные глобальные переменные:
$_GET, $_POST, $_COOKIE и $_REQUEST
Эти переменные представляют собой ассоциативные массивы, содержащие все переданные пользователем данные. Первые три, как понятно из их названия, содержат данные переданные тем или иным способом, а вот глобальная переменная $_REQUEST это объединенный массив из трех предыдущих переменных. При этом, при совпадении имен переменных, происходит их переопределение в порядке заданном в настройках PHP.
И есть одна тонкость при обработке значений переменных, содержащих в себе спецсимволы, к которым относятся: апостроф('), кавычки (") и обратный слеш (\). Такие спецсимволы должны экранироваться при помощи обратного слеша, чтобы показать, что в данном случае они выступают как символы, а не как элементы языка программирования.
Для просмотра полного текста заметки, перейдите по ссылке. Собственно говоря, то что описано далее в заметке это один из возможных способов решения проблемы, использованный в движках "Wikipad" и "Photopad", что позволяет им корректно работать даже на нестандартных хостингах. Обновленные версии движков выложены на официальном сайте поддержки этих проектов.
По умолчанию, все вводимые в форме данные автоматически экранируется, что позволяет писать код не задумываясь о таких тонкостях. Но иногда эти умолчания могут измениться и тогда код начинает работать несколько неправильно или точнее сказать возможны случаи его неправильной работы. Чаще всего это происходит при обновлении программного обеспечения или настроек безопасности на хостинге.
По вышеописанной причине, чтобы сделать код более устойчивым к разным настройкам PHP необходимо проверять факт использования "волшебных кавычек". К счастью, сам PHP предоставляет нам функцию get_magic_quotes_gpc(), которая возвращает нам текущее состояние настройки "волшебных кавычек". Но вот проверять каждую переменную очень неудобно, тем более если проект будет в дальнейшем развиваться и неизвестно какие еще переменные могут появиться. Гораздо удобнее сразу обработать все переданные переменные, воспользовавшись ранее описанными глобальными переменными:
// Включаем "волшебные кавычки" для данных переданных методом GET, POST или COOKIE if (!get_magic_quotes_gpc()) { if (!empty($_GET)) add_magic_quotes($_GET); if (!empty($_POST)) add_magic_quotes($_POST); if (!empty($_COOKIE)) add_magic_quotes($_COOKIE); if (!empty($_REQUEST)) add_magic_quotes($_REQUEST); @ini_set("magic_quotes_gpc", 1); } // Отключаем "волшебные кавычки" для данных прочитанных из файлов @set_magic_quotes_runtime(0);
В данном примере кода, просто проверяется факт использования "волшебных кавычек" и если они не включены, то производится их принудительное добавление при помощи функции add_magic_quotes() текст которой приведен чуть ниже.
Кроме обработки данных переданных скрипту, вышеупомянутый фрагмент кода также устанавливает умолчательный режим для данных читаемых из файлов. Эти данные наоборот не должны автоматически экранироваться.
/////////////////////////////////////////////////////////////////////////////// // // // Функция добавления "волшебных кавычек" // // // /////////////////////////////////////////////////////////////////////////////// function add_magic_quotes(&$data) { reset($data); while(list($key, $value) = each($data)) { // Если переданные данные являются массивом, // то вызываем функцию рекурсивно if (is_array($value)) { $data[$key] = add_magic_quotes($value); } else { $data[$key] = addslashes($value); } } return $data; }
Функция добавления "волшебных кавычек" рекурсивная, т.к. передаваемые данные могут быть не просто переменными, но массивами. И чтобы автоматически обработать сколько угодно сложную передаваемую структуру, как раз и используется рекурсия.
Если поместить вышеописанный фрагмент кода в начало любого скрипта, то далее можно не беспокоиться о проблемах связанных с обработкой спецсимволов. Для больших проектов, имеет смысл размещать данный код в файле инициализации, подключаемом ко всем скриптам.