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

Другие вопросы по тегам