Данные в UTF-8, Ajax неправильно возвращает некоторые символы

Я потратил много времени на поиск в Интернете и увидел много похожих ответов, но не могу найти ничего, что подходило бы для моей ситуации.

Я потратил некоторое время на преобразование моей базы данных MySQL в UTF-8 из latin1 (по умолчанию). Я очистил таблицы (усек) и повторно импортировал данные из текстового файла. Я установил заголовки для своих страниц, чтобы использовать метатег в UTF-8:

<meta http-equiv = "Content-Type" content = "text/html" charset = "UTF-8" />

И это используется повсюду. Когда я читаю данные через PHP и выводю их в формы и тому подобное, данные отображаются правильно, текст вроде: Königstadt выглядит так, как можно было бы надеяться. Сохранив их (набор обновлений ...), они кажутся нормальными, потому что, когда я перечитываю их из данных, отображение в форме правильное. (Дисплей в PHP Admin показывает "Königstadt", что странно, но когда я читаю данные, они кажутся правильными ... - я надеюсь, что это какая-то странность PHPAdmin)

Кажется, что все падает на меня, это мой код Ajax, когда я получаю данные через PHP с помощью Ajax. Ниже приводится относительно простая процедура, которая вызывает программу PHP для создания тегов параметров для SELECT:

     function get_branches()
     {
        // numeric values that need to be passed to the
        // routine (so we show the correct item selected)
        var region = document.getElementById("search_region").value;
        // the code in load_branches needs this, but ...
        var branch = document.getElementById("search_branch").value;

        $.ajax
        ({
           type: "POST",
           url: "<?php echo $Roster_html_RootPath; ?>lookups/load_branches.php",
           data: {
                   'region' : region,
                   'local_branch' : branch
                 },
           //cache: false,
           success: function(data)
           {
              // load contents of DIV tag with id of branchoptions:
              $("#branch_options").html(data);
           }  // end success
        }); // end ajax call
     }; // end function get_branches()

  }); // end document.ready ...

Большинство возвращенных записей в порядке. Однако показанный выше (Königstadt) выглядит так: Königstadt в возвращаемом HTML Select.

Я пытался найти решение, например, установить contentType для Ajax, вот что я пробовал:

contentType: "application/x-www-form-urlencoded;charset=utf-8",

Кажется, что это вообще не имеет значения. Ничего не меняется.

contentType: "application/text; charset=utf-8",

(или приложение / json) Это убивает значения, передаваемые в файл PHP - массив данных, кажется, не попадает туда, потому что я получаю ошибки от PHP:

Notice: Undefined index: region in C:\xampp\htdocs\Heralds\Roster\lookups\load_branches.php on line 32

Notice: Undefined index: local_branch in C:\xampp\htdocs\Heralds\Roster\lookups\load_branches.php on line 33

Я совершенно не понимаю, как правильно вернуть значения. Мне нужны версии как для текста, так и для html (где я возвращаю таблицу html или теги параметров, как здесь), но мне также нужно использовать массив json для некоторых из моего кода, чтобы правильно возвращать значения. Ни один из них не работает должным образом с данными в кодировке UTF-8. Я работаю над этим некоторое время и очень расстроен. Объяснения, которые я вижу, не работают или в некоторых случаях не имеют смысла ...

PHP lookups/load_branches.php

<?php
// if session has not started:
session_start();

// load some basic configuration, including relative paths
// and variables needed ...
include_once( "../includes/configuration.php" );

// data connection
include_once( $Roster_RootPath . "includes/connect.php");

// values from Ajax code:
$region       = $_POST["region"];
$local_branch = $_POST["local_branch"];

// open the roster_branches table and get list
if ( $region > 0 ) // check only needed for find_by_branch.php
{
   $branch_statement = "select * from roster_branches where region = " .  $region . " order by local";
}
else
{
   $branch_statement = "select * from roster_branches order by local";
}

// first, get the data from the table:
$branch_result = mysqli_query( $connect, $branch_statement );
if ( !$branch_result )
{
   $out = "";
   $out .= "<div class='alert alert-danger'>";
   $out .= "<p><b>Error in SQL statement ...</b><br />";
   $errornum = mysqli_errno( $connect );
   $out .= "MySQL Error Number: " . $errornum . "<br />";
   $out .= "MySQL Error: " . mysqli_error( $connect ) . "<br />";
   $out .= "SQL Statement: " . $branch_statement . "</p>";
   $out .= "</div>";
   echo $out;
   die;   
}
else
{
   $out = "";
   // create select:
   $out = "<select class='form-control' id='local_branch' name='local_branch'>\n";

   // need the blank option:
   $out .= "   <option value=0 selected></option>\n";

   while( $branch_row = mysqli_fetch_array( $branch_result ) )
   {
      $id = $branch_row["rb_id"];
      $local = $branch_row["local"];
      $selected = "";
      if ( $local_branch == $id )
      {
         $selected = " selected";
      }
      $out .= "<option value = " . $id . $selected . ">" . $local . "</option> \n";
   }

   $out .= "</select>\n";
   echo $out;      
} // we have something

?>

Покажите, пожалуйста, ваш PHP-файл lookups/load_branches.php

Martin 26.09.2018 19:42

Возможный дубликат UTF-8 полностью

miken32 26.09.2018 20:01

Добавим файл load_branches.php, он не слишком длинный, но нужно убедиться, что редактор правильно его форматирует ...

Ken Mayer 26.09.2018 20:27

Вы пробовали это: stackoverflow.com/questions/8285936/how-to-change-ajax-chars‌ et

Martin 26.09.2018 21:22

Из образца, на который указывает @Martin: contentType: "application / x-www-form-urlencoded; charset = UTF-8", не действует; contentType: "application / x-javascript; charset: UTF-8", нарушает код (не передает массив данных в файл PHP)

Ken Mayer 26.09.2018 22:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
5
205
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

my MySQL database to UTF-8 from latin1 (the default).


1) I used "utf8_unicode_ci". 2) I have no idea what "multibyte safe functions" you're talking about. I use mysqli_real_escape_string() when reading data from $_POST, and the usual mysqli_query() and so on functions

Это причина вашей проблемы.

Чтобы исправить это, нужно поработать тремя основными способами:

1)

Вам необходимо включить истинный UTF-8 (4 байта) в MySQL, чтобы данные, хранящиеся в вашем SQL, были хранится как правильные символы UTF-8. на повсеместно с использованием сопоставлений и наборов символов с префиксом utf8mb4_.

2)

Чтобы убедиться, что данные из вашего приложения / PHP правильно представляют собой сохранен, вам необходимо убедиться, что данные являются передается в MySQL как 4-байтовые символы UTF-8, установив набор символов подключения на полный (4 байта) UTF-8 в вашем PHP:

$mysqliObject->set_charset('utf8mb4');   // object oriented style
mysqli_set_charset($connect, 'utf8mb4');    // procedural code style

3)

Наконец-то; вам необходимо убедиться, что любая обработка, производимая PHP с результирующими данными, является многобайтовый; с помощью набора функций mbstring.

В частности:

  • mb_http_output() - обнаружение и преобразование кодировки символов вывода HTTP
  • mb_internal_encoding() - устанавливает внутреннюю кодировку символов PHP

Таким образом, ваша верхняя часть каждой страницы PHP должна выглядеть так до любого вывода браузера)

mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');

Затем, если вы что-нибудь сделаете с функциями str_<whatever> (и некоторыми другими), вы знаете, что это не сломает вам строки до того, как они будут выведены в браузер (в данном случае это ajx).


1) Я использовал utf8_unicode_ci. 2) Понятия не имею, о каких "многобайтовых безопасных функциях" вы говорите. Я использую mysqli_real_escape_string () при чтении данных из $ _POST, а также обычные функции mysqli_query () и т. д.

Ken Mayer 26.09.2018 20:32

Я попытался вставить это в какой-то код и получил сообщение об ошибке: Неустранимая ошибка: вызов неопределенной функции mbstring () в C: \ xampp \ htdocs \ Heralds \ Roster \ lookups \ load_branches.php в строке 79

Ken Mayer 26.09.2018 20:39

@KenMayer Я написал для вас более полезный ответ. надеюсь, это поможет

Martin 26.09.2018 20:49

@KenMayer mbstring не является функцией сама по себе. См. Руководство.

Martin 26.09.2018 20:50

utf8 подходит для простых символов, таких как ö. utf8mb4 действительно становится необходимым только при работе с такими вещами, как эмодзи, которые находятся в гораздо более высоких кодовых точках.

miken32 26.09.2018 20:53

@ miken32 да, но где-то по ходу кодировки злоупотребляют - если mbstring не включен на сервере (неизвестно по умолчанию), то PHPMyAdmin может выводить что-то неправильно

Martin 26.09.2018 21:24

Я добавил: mb_internal_encoding ('UTF-8'); mb_http_output ('UTF-8'); Перед чтением (запросом к массиву $ _POST) данных ничего не произошло, никаких изменений в поведении.

Ken Mayer 26.09.2018 22:46

Преобразование базы данных в utf8mb4 мая сделало свое дело. Мне нужно провести дополнительное тестирование, но две рассматриваемые программы в настоящее время возвращают правильные значения.

Ken Mayer 26.09.2018 23:05

Оказывается, что: 1) преобразование в utf8mb4, и; 2) использование функций mb _... () могло решить эту проблему. Я тестировал две разные таблицы и два очень разных набора кода, выполняя разные действия, и, похоже, в настоящий момент это работает.

Ken Mayer 26.09.2018 23:23

О, это: mysqli_set_charset($conn, 'utf8mb4'); - похоже, что-то напортачило (и это не имя строки подключения, но данные, похоже, снова конвертируются ...)

Ken Mayer 26.09.2018 23:25

@KenMayer рад, что решил эту проблему, повторю свой последний комментарий, вам нужно адаптировать мой код к вашей конкретной ситуации; т.е. используйте переменное имя, которое вы использовали для своего объекта подключения MySQL ;-)

Martin 27.09.2018 10:02

@Martin - Я это сделал (изменил имя объекта подключения), в моем приложении все равно испортились данные. Спасибо хоть.

Ken Mayer 27.09.2018 17:23

@KenMayer вы читали руководство для mysql_set_charset?

Martin 27.09.2018 17:28

@Martin - Я просмотрел это, но после определенного момента мои глаза начали тускнеть. Большинство этих руководств нелегко читать. Я не понимаю, зачем мне это нужно, когда все остальное вроде работает, и если я его использую, мои страницы, похоже, выполняют какой-то перевод символов, что делает их нечитаемыми на экране; однако, если я это опущу, они выглядят нормально.

Ken Mayer 28.09.2018 18:27

ö - это «моджибаке» для ö. См. «Моджибаке» в Проблема с символами UTF-8; то, что я вижу, это не то, что я сохранил.

Но настоящая проблема, вероятно, случится, когда вы перейдете с latin1.

Таблицы нужно было конвертировать через ALTER TABLE .. CONVERT TO CHARACTER SET utf8mb4. Любая другая техника может испортить ситуацию.

Любое подключение к MySQL необходимо указывать utf8mb4.

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