PHP 5.3, Suhosin и UTF-8
Я изо всех сил пытаюсь найти решение, чтобы продолжать использовать патч Suhosin и заставить его работать с отправками форм UTF-8. Это очень простой тест, который я сделал:
<?php var_dump($_POST); ?>
<form method="post">
<input name="test" type="text"/>
<input type="submit" />
</form>
используя строку iñtërnâtiônàlizætiøn. Очевидно, что сначала я включаю заголовки utf-8 на сервере и устанавливаю Php default_charset в utf-8, а также включаю переопределение mb *. Как только я отключаю исправление Suhosin и повторно отправляю форму, все работает как надо.
ОБНОВИТЬ
Я сделал больше тестов, чтобы быть уверенным:
$test = $_POST['test'];
var_dump(mb_detect_encoding($test, "UTF-8", true));
// Returns true if $string is valid UTF-8 and false otherwise.
function is_utf8($string) {
// From http://w3.org/International/questions/qa-forms-utf-8.html
return preg_match('%^(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$%xs', $string);
} // function is_utf8
var_dump(is_utf8($test));
и оба теста вернули false с включенным патчем Suhosin и true в противном случае. Вопрос: это ошибка или ожидаемое поведение? есть ли параметр конфигурации для патча Suhosin, который делает что-то волшебное с многобайтовыми строками?
Единственный вариант, который я вижу на данный момент - это отключить патч, если только блестящий ум не даст правильный совет.
ОБНОВЛЕНИЕ 2
строки GET не повреждаются и корректно отображаются в браузере. Только POST сделать на данный момент.
3 ответа
В поиске Google я нашел http://algorytmy.pl/doc/php/ref.mbstring.php котором упоминается
Начиная с PHP 4.3.3, если для enctype для формы HTML задано значение multipart/form-data и
mbstring.encoding_translation
установлен на Вкл вphp.ini
переменные POST и имена загруженных файлов будут также преобразованы во внутреннюю кодировку символов. Однако преобразование не применяется к ключам запроса.
Это на самом деле не так много значит для меня, но в нем упоминаются переменные POST, которые, похоже, являются основной проблемой.
Я обнаружил, что если я установлю это на своем виртуальном хосте Apache, я смогу воспроизвести вашу проблему:
php_admin_value mbstring.language "Neutral"
php_admin_value mbstring.encoding_translation "On"
php_admin_value mbstring.http_input "UTF-8"
php_admin_value mbstring.http_output "UTF-8"
php_admin_value mbstring.detect_order "auto"
php_admin_value mbstring.substitute_character "none"
php_admin_value mbstring.internal_encoding "UTF-8"
php_admin_value mbstring.func_overload "7"
php_admin_value default_charset "UTF-8"
Для справки, это была тестовая страница php, которую я использовал для воспроизведения проблемы:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<pre><?php echo $_POST['test'];?></pre>
<form method="post">
<input name="test" type="text"/>
<input type="submit" />
</form>
Test string to use: iñtërnâtiônàlizætiøn
</body>
</html>
Я попытался закомментировать следующий параметр mbstring (или отключить его):
; Disable HTTP Input conversion (PHP 4.3.0 or higher)
mbstring.encoding_translation = Off
Кажется, это решает проблему, хотя для меня это не имеет особого смысла, потому что внутренняя кодировка символов - utf-8??
Я заметил еще одну странность: если я mbstring
значения непосредственно в php.ini
(вместо виртуального хоста Apache) мне не удалось воспроизвести проблему с encoding_translation
так что это кажется проблемой только тогда, когда php_admin_value
используется?
Пробовали ли вы в своих метатегах на HTML-странице следующие
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" ></meta>
Вы пробовали?
<form accept-charset="UTF-8" method="post">