为什么扩展ASCII字符(如â、é等)会被替换成<?>字符?

3
为什么扩展 ASCII 字符(如 â、é 等)会被替换为 <?> 字符?
我附上了一张图片...但我正在使用 PHP 从 MySQL 中提取数据,有些地方有扩展字符...我使用 Arial 字体。
你可以在这里看到屏幕截图:http://img269.imageshack.us/i/funnychar.png/ 即使按照建议操作后仍然存在问题,以下是我所做的:
我的 Firefox(查看->编码)设置为 UTF-8,添加该行代码后,然而,在选项标签内的文本仍然显示有趣的字符,而不是实际的重音字符。现在我应该寻找什么?
更新: 我在 PHP 程序中加入了以下内容,导致出现了那些<?>字符...
ini_set( 'default_charset', 'UTF-8' );

在我的Zend DB对象创建后,我设置了以下查询:
$db->query("SET NAMES utf8;");

我将所有表格都改成了UTF-8,并重新插入了所有数据(浪费了时间),因为它并没有起到帮助作用。原来是latin1编码。
此外,状态报告如下:
Connection:             Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /var/run/mysqld/mysqld.sock
Uptime:                 4 days 20 hours 59 min 41 sec

查看页面源代码,我看到了<option value="Br�l� Lake"> Br�l� Lake

好的- 新更新- 我将PHP和HTML中的所有内容更改为:

header('Content-Type: text/html; charset=latin1');

现在它可以工作了,怎么办?如何将所有内容转换为UTF-8?


你使用的Firefox版本是什么,它给了你什么问题?我尝试重现您的问题,但未能成功。您测试的机器是否缺少正确的Unicode字体?如果您有兴趣查看我测试的页面,可以在这里找到:http://dan-herbert.com/unicode.htm - Dan Herbert
奇怪,dan-herbert.com/unicode.htm 在我的浏览器中看起来完美...这就排除了火狐浏览器的问题... - Kladskull
类似的问题在这里:https://dev59.com/IHVC5IYBdhLWcg3wnCaA - Simon East
8个回答

19
当浏览器不知道使用哪种编码来处理字符时,它会采取这样的处理方式。请确保在头部或标记元数据中指定文本的编码类型,以便向客户端发送。
在HTML中:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

在 PHP 中(在向客户端发送任何其他内容之前):

header('Content-Type: text/html; charset=utf-8');

我假设您希望使用UTF-8编码。如果您的网站使用其他文本编码,则应将UTF-8替换为您正在使用的编码。
关于使用HTML指定编码的一件事情是,浏览器将在看到Content-Type元标记后重新启动呈现页面,因此您应该在页面中的< head/>标记之后立即包含标记,这样浏览器就不会进行更多的额外处理。
另一个常见的字符集是"iso-8859-1"(基本拉丁语),您可能希望使用它来代替UTF-8。您可以从character encodings and the web这篇很棒的文章中找到更详细的信息。如果需要特定类型的编码,您也可以在此处获得详尽的list of character encodings列表。
如果其他方法都不起作用,另一个(罕见的)可能性是您的计算机上没有安装带有显示页面所需字符的字体。我尝试在我的服务器上重复您的结果,但没有成功,可能是因为我在我的电脑上安装了很多字体,所以浏览器总是可以用另一个字体替换不可用的字符。
通过进一步调查,我注意到如果文本发送的编码与浏览器报告的编码不同,Unicode字符可能会呈现出意外的效果。为了解决这个问题,我使用了特殊字符的HTML字符实体表示,因此â变成了&#226;在我的HTML中,é变成了&#233;。一旦我这样做了,无论我报告什么编码,我的字符都正确呈现。
显然,您不想修改数据库以HTML编码Unicode字符。如果必须这样做,您最好的选择是使用PHP函数htmlentities()。您应该在任何期望具有Unicode字符的数据驱动文本上使用此函数。这可能很烦人,但如果指定编码无法解决问题,这是强制Unicode字符正常工作的最后一招。

我也是。恭喜你的打字速度 =) - David Thomas
5
快速调试此问题的方法是在浏览器中手动更改编码方式。例如,在 Firefox 中使用“查看”->“字符编码”。 - Matthew Flaschen
我的火狐浏览器在添加了这行代码后设置为UTF-8,但是选项标签内的文本仍然显示那个字符。它在MySQL中存储时带有重音符号的字符完好无损。 - Kladskull
1
Mike,我在下面的答案中添加了一些SQL信息。 - Peter Bailey
1
htmlentities的东西是不必要的复杂化 - utf8可以编码任何内容,实际上latin1可以编码应用程序所需的任何字符。那个问号/钻石形状通常表示编码错误,如果它是一个浏览器找不到字体的字符,它将成为空心的“豆腐”框。 - user8599
@Matthew Flaschen 和其他四位用户 - 我使用查看->字符编码,然后页面重新加载,Firefox 会将其设置回应该是的 UTF-8。 - Kladskull

3

正如其他人所提到的,这是一个字符编码问题。您应该阅读Joel Spolsky的文章,了解字符编码。

设置

header('Content-Type: text/html; charset=utf-8');

如果您的PHP页面向浏览器输出UTF-8字符,那么这将解决您的问题。如果文本仍然混乱不清,可能是因为您的文本不是UTF-8编码; 在这种情况下,您需要在Content-Type标头中使用正确的编码名称。如果可以选择,请始终使用UTF-8或其他Unicode编码。

3

没有“扩展ASCII”这样的标准,只有一堆专有扩展

无论如何,可能存在各种可能的原因,但不是你的字体问题。您可以从检查MySQL中的字符集开始,然后查看PHP的操作。正如Dan所说,您需要确保PHP指定了它实际使用的字符编码。


1

最简单的修复方法

ini_set( 'default_charset', 'UTF-8' );

这样你就不必担心手动发送Content-Type头了。

编辑

确保你实际上将数据存储为UTF-8 - 将非UTF-8数据作为UTF-8发送到浏览器与将UTF-8数据作为其他字符集发送一样容易引起问题。

SELECT table_collation
  FROM information_schema.`TABLES` T
 WHERE table_name=[Table Name];

SELECT default_character_set_name
     , default_collation_name
  FROM information_schema.`SCHEMATA` S
 WHERE schema_name=[Schema Name];

检查这些值


1
改变表格编码既不是必要的也不是充分的。重要的是告诉 MySQL 在哪种编码下传输结果("show variables like character_set_results")。MySQL 可以正确地传输来自 Latin1 表格的 UTF-8 数据(反之亦然,在一定限度内)。 - user8599

1

有两个传输编码,PHP<->浏览器和Mysql<->PHP,它们需要彼此一致。设置Mysql<->PHP的编码在以下问题的答案中进行:

快速的答案是“SET NAMES UTF8”。

缓慢的答案是阅读其他答案中推荐的文章——理解正在发生的事情并进行精确更改要比应用试错法直到事情似乎起作用要好得多。这不仅是一个化妆UI问题,糟糕的编码配置可能会严重破坏您的数据。想想辛普森家庭中Lisa(丽莎)被嚼过的口香糖粘在头发上,而Marge(玛吉)试图用花生酱把它弄出来的那一集。


0

这些特殊字符通常是由于扩展引起的。如果我们提供一个带有 charset=utf-8 的元标签,我们可以通过添加以下内容来消除它们:

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

到你的元标签


0

在编程中,你应该将所有特殊字符编码为HTML实体,而不是依赖于字符集。

htmlentities()可以帮助你完成这项工作。


0
我将所有的表格都改成了UTF-8,并重新插入了所有数据(浪费时间),但这并没有起到任何作用。之前是latin1编码。
如果你的原始数据是latin1编码,那么将其插入到UTF-8数据库中并不会将其转换为UTF-8编码,据我所知,它会插入相同的数据,但现在认为它是UTF-8编码,从而导致错误。
如果你有一个SQL转储文件,我建议你通过工具将其转换为UTF-8编码。Notepad++做得很好 - 只需打开文件,检查重音字符是否正确显示,然后在菜单中找到“转换为UTF-8”。

现在进行 SQL 转储还来得及吗? - Kladskull
不,我认为还是可以的 - 但你当然可以尝试并查看结果。先进行 SQL 转储,然后转换为 utf8 并检查字符是否正确显示。如果是这样,那么插入回数据库应该是没问题的。如其他人所说,你仍需要在每个页面加载时运行 "SET NAMES UTF8"。 - DisgruntledGoat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接