在yii中使用utf8字符和htmlspecialchars时出错

时间:2012-06-11 21:59:36

标签: php html utf-8 character-encoding yii

我在yii中遇到char编码问题。 如果我创建一个新的webapp:

 ./Yii-framework/framework/yiic webapp MyTest

然后转到/protected/views/layouts/main.php并将页脚更改为带有utf8字符的文本,例如

<div id="footer">
        Cópyrîgth <br />
</div>

刷新页面,一切正常。太好了! ;)

然后我尝试使用用户名中的utf8字符登录,例如ádmin,它崩溃说:

Error 500

htmlspecialchars(): Invalid multibyte sequence in argument

所以我查看了这篇关于unicode in yii

的文章

然后我去了 /protected/config/main.php 并在开头添加了这一行:

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

再次重试相同的登录工作(不会崩溃),但现在页脚已损坏并显示:

C�pyr�ght

我尝试了其他组合,如“在yii中的Unicode”一文中所解释的那样,但它们都没有让两件事同时发挥作用。

解决这个问题的想法是什么?

注意:我无法更改为php.ini文件。

我还尝试了.htaccess文件中的 AddDefaultCharset UTF-8 选项并将其放在/ MyTest /的文件夹中,是文章中引用的正确文件夹:您的 DocumentRoot

由于

7 个答案:

答案 0 :(得分:6)

我对yii并不熟悉,但是,如果要将文字unicode字符粘贴到文件中,则需要确保文本编辑器使用unicode编码保存文件,例如utf8。尝试utf8,没有BOM。

我的经验是,当您更改编码设置并且其中已经编码了字符时,文本编辑器会表现得很奇怪。重新开始使用新文件,更改编码,然后粘贴字符。

答案 1 :(得分:4)

首先,您需要了解具有变音符号character或î(从您的示例中)的字符不会自动成为“utf-8字符”。它只是一个在不同字符集中具有不同编码(如果有的话)的字符,即使在那些具有基本单字节ASCII部分的字符集中(即英文字母,数字,最常见的标点符号,以及再多一点)。你可以称之为“有问题的角色”,但不是“utf-8角色”。

因此,当您编写页脚<div>时,您没有编写UTF-8编码。您的编辑器以单字节编码保存这些字符,如ISO 8859-1或其中一个亲戚。

浏览器通常会自动检测页面中使用的编码(如果未指定)。这就是为什么你最初能够在浏览器中看到你在编辑器中写下的内容。

然后您尝试使用用户名中的“有问题的字符”登录。浏览器将您的页面解释为具有单字节编码,因此这导致它以相同的方式对表单输入进行编码,并将其单字节编码发送回服务器。显然,PHP代码并没有考虑到这种可能性,因为它没有正确设置htmlspecialchars()的第三个参数,默认为"UTF-8"(从PHP 5.4.0开始 - 它是"ISO-8859-1"之前)。由于带有“有问题字符”的单字节编码字符串几乎从不是有效的UTF-8字符串(请参阅我对您的问题的评论,这是第二条评论),htmlspecialchars()拒绝了它。

然后您正确添加了header('Content-Type: text/html; charset=utf-8');,它禁用了浏览器的自动字符集检测功能。此时很明显,您的页脚<div>的文件不是UTF-8编码的(请参阅我的评论,以解释出现的问号,而不是“有问题的字符”)。

所以你要做的就是说服你的编辑保存UTF-8编码的文件。正如其他人所说,以不同的编码保存文件并不适用于所有编辑器。从新文件开始有时是解决方案,可能是在将编辑器的默认编码设置为UTF-8之后。

要检查编码,可以在shell中使用file命令。它的输出应该是

main.php: PHP script, UTF-8 Unicode text

否则,您可以使用od -tx1z命令将您的文件(可能是| less)转储为一个十六进制字节序列,并在旁边添加相应的字符串。如果文件是单字节编码的,那么“有问题的字符”将是单字节&gt; = 0x80。如果是UTF-8编码,它们将是2个字节的序列(其他将是3个或更多个字节),全部> = 0x80,而“无问题字符”将继续是单个字节&lt; 0x80的。

你提到的文章似乎写得很好,只需遵循它。

如果所有页面都是使用AddDefaultCharset HTTP标头生成的,那么.htaccess文件中不需要Content-Type: text/html; charset=utf-8指令,因为Apache指令的效果是完全相同(最好保持对PHP内编码的控制)。

对于浏览器,添加<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>与上述HTTP标题具有相同的效果(请注意http- equiv )。 HTTP标头更干净,但如果保存页面而没有标题信息,则此附加元标记可能会有所帮助。

最重要的是,不要害怕UTF-8,因为这是你的朋友!

(...但是,从得到赏金的答案中,我看到你和许多人一样,继续认为理解字符编码对你来说太难了☹)

答案 2 :(得分:2)

首先,您应该删除main.php文件中的标题调用,这可能会在将来为您带来问题。

其次,我会做rambo编码器建议的,并确保你的文件在编辑器中保存为UTF8。

答案 3 :(得分:1)

以上解决方案似乎是正确的方法,因为Yii确实没有unicodes的问题,但你也可以执行一些额外的检查,比如你的Html页面中元标记内的charset设置为utf-8而不是写普通的HTML你可以使用Chtml :: encode(版权),以便yii处理编码。对于用户名部分,请确保数据库中的Default Charset也设置为utf8。

答案 4 :(得分:1)

对于htmlspecialchars问题,请查看以下答案:https://stackoverflow.com/a/3803972/133408

您必须将编码指定为htmlspecialchars

的第三个参数

答案 5 :(得分:0)

解决此问题的最佳方法是使用http://www.utexas.edu/learn/html/spchar.html - 在您的情况下 Cópyrîght将显示为C&#243;pyr&#238;ght

另外,我会添加HTML <meta charset="utf-8">以确保浏览器自行运行。

答案 6 :(得分:0)

我也有这个问题 - 特别是当我试图从db显示utf文本时。 我将mysql中的所有colations和类型更改为utf8-bin - 但仍然没有爱...然后我尝试使用meta标签等我的所有布局和视图...地狱,我甚至看了日本网站的源代码然后粘贴那些东西......没有工作_ ...直到...我发现了这篇文章:Yii And UTF8 Display, UTF8 works with mysqli but not yii backend原来,你需要在配置文件中的main.php中调整一个设置,在组件下面.. f