既然这是我第一次,我想知道下面的“清单”是否完整。一切都在测试中运行良好,但我可能会错过只会在极少数情况下发生的事情。
确保文件始终以UTF-8读取和写入:
@H_404_8@use open ':utf8';>确保CGI输入以UTF-8收到(站点不使用CGI.pm):
@H_404_8@s{%([a-fA-F0-9]{2})}{ pack ("C",hex ($1)) }eg; # Kept from existing code s{%u([0-9A-F]{4})}{ pack ('U*',hex ($1)) }eg; # Added utf8::decode $_;>确保文本打印为UTF-8:
@H_404_8@binmode STDOUT,':utf8';确保浏览器将我的内容解释为UTF-8:
@H_404_8@Content-Type: text/html; charset=UTF-8 <Meta http-equiv="content-type" content="text/html;charset=UTF-8">>确保表单发送UTF-8(只要设置页面编码,可能就不需要):
@H_404_8@accept-charset="UTF-8">不要以为我需要以下内容,因为内联文本(菜单,标题等)仅在ASCII中:
@H_404_8@use utf8;这看起来很合理还是我错过了什么?
编辑:我也应该提到,我们将运行一次性批次来读取所有现有的文本数据文件并将其保存为UTF-8编码。
解决方法
PerlIO
层是
not strict enough.它允许满足UTF-8字节序列的结构要求的输入,但为了很好的安全性,你想拒绝不是真正有效的Unicode的内容。用
PerlIO::encoding
层替代它,因此::encoding(UTF-8)。
>因为同样的原因,总是Encode :: decode(‘UTF-8’,…),而不是Encode :: decode_utf8(…)。
>使解码失败,异常,比较: @H_404_8@perl -E'use Encode qw(decode); say decode(q(UTF-8),qq(\x{c0})); say q(survived)' perl -E'use Encode qw(decode); say decode(q(UTF-8),qq(\x{c0}),Encode::FB_CROAK); say q(survived)'
>你没有在%u符号中照顾代理对。这是列表中唯一可以看到的主要错误。 2.正确写为:
@H_404_8@use Encode qw(decode); use URI::Escape::XS qw(decodeURIComponent); $_ = decode('UTF-8',decodeURIComponent($_),Encode::FB_CROAK);>不要乱用utf8
模块的功能。它的文档也是这样说的。它的目的是为了告诉Perl源代码是UTF-8。如果要进行编码/解码,请使用Encode
模块。
>在每个模块中都添加utf8 pragma。它不会受到伤害,但是如果有人添加了这些字符串文字,您将会进行未来的代码维护。参见CodeLayout::RequireUseUTF8
。
>雇用encoding::warnings
抽出剩余的隐式升级。验证每种情况是否有意/需要。如果是,请将其转换为Unicode::Semantics
的显式升级。如果不是,这是一个提示,您应该有更早的解码步骤。 http://p3rl.org/UNI的文档提供了从源头收到数据后立即解码的建议。查看代码正在读/写数据的地方,并验证您是否具有解码/编码步骤,无论是显式地(解码(‘UTF-8’,…))或隐含地通过一个层(使用打开的pragma,binmode,3个参数开放形式)。
>对于调试:如果您不确定某个变量中的某个字符串在某个特定时间的表示形式,则不能打印,请改用工具Devel::StringInfo
和Devel::Peek
。