数据是 UTF-8,Ajax 错误地返回了一些字符
Data is UTF-8, Ajax is returning some characters incorrectly
我花了很多时间在网上搜索并看到了很多类似的答案,但找不到适合我的情况的答案。
我花了一些时间将 MySQL 数据库从 latin1(默认)转换为 UTF-8。我从文本文件中清空了 tables(截断)和 re-imported 数据。我已经为我的页面设置 headers 以使用 UTF-8 元标记:
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />
而且到处都在使用它。当我通过 PHP 读取数据并将其输出到表格中时,数据正确显示,文本如:Königstadt 出现,正如人们所希望的那样。保存它们(更新集...)它们似乎没问题,因为当我从数据中 re-read 它们时,表格中的显示是正确的。 (PHP Admin 中的显示显示 "Königstadt",这很奇怪,但当我读取数据时它似乎是正确的...... - 我希望这是 PHP 的一些奇怪之处管理员)
当我使用 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 ...
大多数 returned 的记录都很好。然而,上面显示的 (Königstadt) 看起来像: HTML Select 中的 Königstadt 是 returned。
我一直在尝试寻找解决方案,例如为 Ajax 设置 contentType,以下是我尝试过的方法:
contentType: "application/x-www-form-urlencoded;charset=utf-8",
这个似乎没有任何区别。没有任何变化。
contentType: "application/text; charset=utf-8",
(或application/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
我完全不知道如何正确 return 值。我需要文本或 html 的版本(我 return 一个 html table 或此处的选项标签),但我还需要使用 json 数组,我的一些代码可以正确 return 值。 None 其中似乎可以正确处理 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
?>
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
这就是您遇到问题的原因。
有 3 个主要地方可以解决这个问题:
1)
您需要在 MySQL 中启用真正的 UTF-8(4 字节),以便存储在您的 SQL 中的数据是 stored 作为正确的 UTF-8 字符。通过普遍使用带有utf8mb4_
前缀的排序规则和字符集。
2)
为确保来自 application/PHP 的数据被正确 保存,您需要确保数据 传递给 MySQL 作为UTF-8 4 字节字符 通过将 连接字符集 设置为完整 (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)之前,它不会破坏您的字符串。
如果您出于任何原因无法使用 mbstring
功能,请查看此处 [如何安装](http://www.knowledgebase-script.com/kb/article/how-to-enable-mbstring-in-php-46.html
).
也请回顾一下this excellent Q&A对您有帮助吗?
进一步阅读有关解决 MySQL 方面的问题 can be found here。
ö
对于 ö
是 "Mojibake"。请参阅 中的 "Mojibake"。
但真正的问题可能发生在您从 latin1 转换时。
需要通过 ALTER TABLE .. CONVERT TO CHARACTER SET utf8mb4
转换表格。任何其他技术都可能造成混乱。
与 MySQL 的任何连接都需要指定 utf8mb4
。
我花了很多时间在网上搜索并看到了很多类似的答案,但找不到适合我的情况的答案。
我花了一些时间将 MySQL 数据库从 latin1(默认)转换为 UTF-8。我从文本文件中清空了 tables(截断)和 re-imported 数据。我已经为我的页面设置 headers 以使用 UTF-8 元标记:
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />
而且到处都在使用它。当我通过 PHP 读取数据并将其输出到表格中时,数据正确显示,文本如:Königstadt 出现,正如人们所希望的那样。保存它们(更新集...)它们似乎没问题,因为当我从数据中 re-read 它们时,表格中的显示是正确的。 (PHP Admin 中的显示显示 "Königstadt",这很奇怪,但当我读取数据时它似乎是正确的...... - 我希望这是 PHP 的一些奇怪之处管理员)
当我使用 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 ...
大多数 returned 的记录都很好。然而,上面显示的 (Königstadt) 看起来像: HTML Select 中的 Königstadt 是 returned。
我一直在尝试寻找解决方案,例如为 Ajax 设置 contentType,以下是我尝试过的方法:
contentType: "application/x-www-form-urlencoded;charset=utf-8",
这个似乎没有任何区别。没有任何变化。
contentType: "application/text; charset=utf-8",
(或application/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
我完全不知道如何正确 return 值。我需要文本或 html 的版本(我 return 一个 html table 或此处的选项标签),但我还需要使用 json 数组,我的一些代码可以正确 return 值。 None 其中似乎可以正确处理 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
?>
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
这就是您遇到问题的原因。
有 3 个主要地方可以解决这个问题:
1)
您需要在 MySQL 中启用真正的 UTF-8(4 字节),以便存储在您的 SQL 中的数据是 stored 作为正确的 UTF-8 字符。通过普遍使用带有utf8mb4_
前缀的排序规则和字符集。
2)
为确保来自 application/PHP 的数据被正确 保存,您需要确保数据 传递给 MySQL 作为UTF-8 4 字节字符 通过将 连接字符集 设置为完整 (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)之前,它不会破坏您的字符串。
如果您出于任何原因无法使用
mbstring
功能,请查看此处 [如何安装](http://www.knowledgebase-script.com/kb/article/how-to-enable-mbstring-in-php-46.html ).也请回顾一下this excellent Q&A对您有帮助吗?
进一步阅读有关解决 MySQL 方面的问题 can be found here。
ö
对于 ö
是 "Mojibake"。请参阅
但真正的问题可能发生在您从 latin1 转换时。
需要通过 ALTER TABLE .. CONVERT TO CHARACTER SET utf8mb4
转换表格。任何其他技术都可能造成混乱。
与 MySQL 的任何连接都需要指定 utf8mb4
。