PHP 5.4 multipart/form-data UTF-8 кодировка
У меня проблемы с кодировкой UTF-8 при публикации данных формы как "multipart/form-data", без multipart / form-data все работает хорошо. Но так как мне нужно загружать файлы в одно и то же сообщение, мне нужно использовать multipart / form-data.
Проблема началась после обновления с PHP 5.3.x до PHP 5.4.4-14 (в комплекте с Debian Wheezy), те же скрипты хорошо работают с тестовым сервером PHP 5.3.
- Все мои документы сохранены в UTF-8 и имеют
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
теги. - Я тестировал с разными браузерами на разных компьютерах
- mb_detect_encoding() обнаруживает опубликованную строку как UTF-8
- Я старался
AddDefaultCharset utf-8
для настройки Apache.
Здесь вы можете проверить мои сценарии, вы можете скопировать / вставить следующую строку с турецкими символами (например, строка: öçşipğopüp)
http://sa.chelona.com.tr/haber-ekle.html
Я также обнаружил, что связанный с этим вопрос в UTF-8 искажается, когда форма публикуется как multipart / form-data в PHP, но он рекомендует переустановить apache / php, а в моей ситуации это невозможно. Это известная ошибка PHP/Apache?
11 ответов
Я пишу это, чтобы ответить на мой собственный вопрос... Я надеюсь, что это поможет кому-то еще...
Если вы используете PHP 5.4.x, установка mbstring.http_input из "auto" в "pass" может решить вашу проблему.
Сделайте простое преобразование из UTF-8
на турецкий алфавит ISO-8859-9 и проблема должна быть решена
iconv('UTF-8', "ISO-8859-9", $string);
Пример ввода: öçşipğopüp
Пример формы:
<form method="post" enctype="multipart/form-data" action ="self.php">
<input type="text" name="hello" />
<input type="submit" name="test" />
</form>
Простой картер:
var_dump($_POST['hello'],iconv('UTF-8', "ISO-8859-9", $_POST['hello']));
Выход
string 'öçşipğopüp ' (length=16)
string 'öçþipðopüp ' (length=11)
Моя версия PHP 5.4.45 и меняется mbstring.http_input
от auto
в pass
работает очень хорошо. В php.ini
file значение по умолчанию - pass. Более подробно об этой переменной вы можете посмотреть здесь.
Вам нужно добавить заголовки в PHP и HTML, например, в нижнем регистре:
<?php header('content-type: text/html; charset=utf-8'); ?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<form method="post" enctype="multipart/form-data" action ="self.php">
...
</form>
</body>
</html>
Помните: сохраните все файлы php и html в utf-8 без спецификации.
Если раскомментирование строки charset по умолчанию в php.ini что-то сделает, это будет легко исправить. Не забудьте сбросить Apache после изменения.
Я не думаю, что вы должны использовать mb_detect_encoding для определения кодировки в этом случае.
Если вам необходимо его использовать, то, возможно, вам нужно установить порядок обнаружения, чтобы убедиться, что UTF-8 находится выше списка, см. http://www.php.net/manual/en/function.mb-detect-order.php
Вы установили для accept-charset форму UTF-8; Вы установили исходную страницу в UTF-8: все текущие браузеры будут отправлять UTF-8. HTML 5 определяет этот FWIW: http://www.w3.org/TR/2011/WD-html5-20110405/association-of-controls-and-forms.html
Строка будет UTF-8, не пытайтесь ее преобразовать, и все будет в порядке.
Но если вы разместите часть своего PHP-кода, то, возможно, будет ясно, что вы пытаетесь сделать, и что идет не так...
К сожалению, это скорее идея обходного пути, чем реальное решение, однако, если все традиционные методы не сработали, и вы ничего не можете переустановить, попробуйте выполнить преобразование из кодовых точек UTF8. Что-то вроде использования кодировки base64 перед отправкой, а затем декодирования при получении. Или конвертировать в шестнадцатеричную строку и декодировать после получения.
Ваша страница примера выглядит правильно, и шаги, которые вы предприняли, по-видимому, охватывают большинство важных моментов, но есть еще одна вещь, которую я хотел бы проверить. Вы писали, что данные хранятся в базе данных MySql с набором символов UTF-8, но это не обязательно означает, что объект подключения PHP также работает с этим набором символов.
// tells the mysqli connection to deliver UTF-8 encoded strings.
$db = new mysqli($dbHost, $dbUser, $dbPassword, $dbName);
$db->set_charset('utf8');
// tells the pdo connection to deliver UTF-8 encoded strings.
$dsn = "mysql:host=$dbHost;dbname=$dbName;charset=utf8";
$db = new PDO($dsn, $dbUser, $dbPassword);
Приведенные выше примеры показывают, как установить кодировку для SQLI или PDO. Подготовка объекта соединения таким образом делает вас независимым от конфигурации базы данных, при необходимости соединение даже преобразует возвращенные / отправленные данные.
Чтобы проверить это на своей странице, убедитесь, что кодировка установлена, прежде чем вставлять / запрашивать базу данных.
Вы должны попытаться переустановить ваш wamp или xampp или ваш apache и php.и запустить ваш код на чужой машине с той же версией php. Если этот код работает, то попытайтесь выяснить, почему он не работает на вашем сервере или проверьте расширение file_upload в вашем php.
mb_internal_encoding("UTF-8");
Добавьте этот код перед вашей строкой..
После долгих попыток с unpack() и предложениями из ответов здесь я обнаружил ловушку, и, возможно, у вас та же причина для проблемы кодирования.
Все, что мне нужно было сделать, это сделать htmlentities явно используя utf-8:
htmlentities(stripslashes(trim(rtrim($_POST['title']))), ENT_COMPAT, "utf-8");
Это для php 5.2.xx