С отключенными «магическими кавычками» почему PHP / WordPress продолжает автоматически избегать моих данных POST?

Это простой вопрос с странно неуловимым ответом.

get_magic_quotes_gpc() 0. Повторяю, магические кавычки отключены. Магические кавычки, похоже, были отключены в php.ini (не во время выполнения).

Тем не менее, все данные POST, включая одинарные кавычки ('), экранируются при доступе к PHP. Что может быть причиной этого?

Спасибо.


Изменить: для любопытных это скриншот нашей phpinfo: http://img843.imageshack.us/img843/6959/screenshot20120120at552.png


Редактирование: при подготовке тестового примера я обнаружил общее происхождение проблемы. Мы загружаем WordPress, так как наше приложение интегрируется с установкой WP Multisite. Когда я отключу загрузку WordPress, автоматическое экранирование отключено. Кто-нибудь знает, где может быть найден код автозапуска WordPress?

Кажется, я нашел его. Проблема (ошибка): http://core.trac.wordpress.org/ticket/18322

Решение: http://codex.wordpress.org/Function_Reference/stripslashes_deep

  $_GET = array_map('stripslashes_deep', $_GET); $_POST = array_map('stripslashes_deep', $_POST); $_COOKIE = array_map('stripslashes_deep', $_COOKIE); $_SERVER = array_map('stripslashes_deep', $_SERVER); $_REQUEST = array_map('stripslashes_deep', $_REQUEST); 

Примечание. Как предложено @Alexandar O'Mara, вы можете пересмотреть переписывание суперглобалов, как это. Если это подходит для вашей ситуации, например, вы можете просто « $post = array_map('stripslashes_deep', $_POST); локально», используя альтернативу, такую ​​как $post = array_map('stripslashes_deep', $_POST);

Также см. Превосходный ответ @ quickshiftin.

Расширяясь на ответ @ rinogo с более глубоким объяснением и предлагая другое обходное решение.


В wp-settings.php есть безоговорочный вызов wp_magic_quotes

 // Add magic quotes and set up $_REQUEST ( $_GET + $_POST ) wp_magic_quotes(); 

WordPress избегает кавычек независимо от того, что

 function wp_magic_quotes() { // If already slashed, strip. // Escape with wpdb. // Force REQUEST to be GET + POST. } 

Интересно, однако, этот вызов выполняется после загрузки плагинов, прежде чем тема загрузится. Sooo, в верхней части вашего плагина

 // A hack to cope with un-configurable call to wp_magic_quotes // EG Make the original $_POST available through a global $_REAL_POST $_REAL_GET = $_GET; $_REAL_POST = $_POST; $_REAL_COOKIE = $_COOKIE; $_REAL_REQUEST = $_REQUEST; 

Затем вы можете свободно использовать $_REAL_POST и др. Вместо $_POST (помня, что это глобальный не суперглобал ), где вам нужно. Также помните, что, пока ваш плагин загрузил перед темой, если тема вызывает одну из функций плагина, которая использует $_POST , она должна читать из $_REAL_POST чтобы получить $_REAL_POST значения.

Лучший ответ, приведенный здесь, – это копирование для собственного использования, например:

 $post = array_map('stripslashes_deep', $_POST); 

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

Решение: методы доступа

В попытке решить этот беспорядок определенным образом и без каких-либо побочных эффектов я сделал «методы доступа», которые прозрачно применяют stripslashes_deep() или addslashes_deep()* для получения / установки запросов к следующим суперглобальным массивам:

* Мне пришлось бросать addslashes_deep() вместе из stripslashes_deep() WordPress.

  • $_GET
  • $_POST
  • $_COOKIE
  • $_SERVER
  • $_REQUEST

Вы можете использовать их так:

 echo _get('username'); // echo stripslashes_deep($_GET['username']); _cookie('name', 'value'); // $_COOKIE['name'] = addslashes_deep('value'); 

Вот код (я называю его gpcsr.php ):

 <?php // cat stripslashes_deep() | sed 's/stripslashes/addslashes/g' function addslashes_deep( $value ) { if ( is_array($value) ) { $value = array_map('addslashes_deep', $value); } elseif ( is_object($value) ) { $vars = get_object_vars( $value ); foreach ($vars as $key=>$data) { $value->{$key} = addslashes_deep( $data ); } } elseif ( is_string( $value ) ) { $value = addslashes($value); } return $value; } function _generic_slashes_wrap(&$arr, $key, $value = null) { if (func_num_args() === 2) return stripslashes_deep($arr[$key]); else $arr[$key] = addslashes_deep($value); } function _get ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_GET, $key); else _generic_slashes_wrap($_GET, $key, $value); } function _post ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_POST, $key); else _generic_slashes_wrap($_POST, $key, $value); } function _cookie ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_COOKIE, $key); else _generic_slashes_wrap($_COOKIE, $key, $value); } function _server ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_SERVER, $key); else _generic_slashes_wrap($_SERVER, $key, $value); } function _request ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_REQUEST, $key); else _generic_slashes_wrap($_REQUEST, $key, $value); } ?> 

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

 add_action( 'init', 'unslash_gpc' ); function unslash_gpc() { $_GET = array_map('stripslashes_deep', $_GET); $_POST = array_map('stripslashes_deep', $_POST); $_COOKIE = array_map('stripslashes_deep', $_COOKIE); $_SERVER = array_map('stripslashes_deep', $_SERVER); $_REQUEST = array_map('stripslashes_deep', $_REQUEST); } 

И теперь все идеально!

WordPress предоставляет решение для этого, используя функцию wordpress stripslashes_deep . Таким образом, фрагменты, упомянутые в ответе @ rinogo, станут:

 $_GET = stripslashes_deep($_GET); $_POST = stripslashes_deep($_POST); $_COOKIE = stripslashes_deep($_COOKIE); $_REQUEST = stripslashes_deep($_REQUEST); 

Также заметка, WordPress ничего не говорит о глобальной переменной $_SERVER , поэтому я бы предположил, что это не повлияет.

WordPress добавляет косые черты в $ _POST / $ _ GET / $ _ REQUEST / $ _ COOKIE независимо от того, что возвращает get_magic_quotes_gpc (). Поэтому в контексте WordPress всегда необходимо использовать stripslashes () или stipslashes_deep () при использовании этих переменных.

Или просто делай, как я. Прокомментируйте всю реализацию в wp_magic_quotes () методе load.php.

Мне не нужны магические цитаты. Это вызывало у меня гораздо больше головных болей, чем того стоило. Лично я предпочитаю поддерживать свою собственную дисциплину в области санитарии. Я просто не хочу начинать формировать плохие привычки программирования.

Но я понимаю, что принуждение WordPress включать такую ​​«особенность». Возможно, сообщество разработчиков лучше всего будет использовать глобальный вариант, чтобы отключить его.