我一直在讨论这个问题已经有一段时间了,并且不能完全理解。这是Ubuntu上的Perl 5。我的网页上有一个下拉列表:
$output .= start_form . "Student: " . popup_menu(-name=>'student', -values=>['', @students], -labels=>\%labels, -onChange=>'Javascript:submit()') . end_form;
它只是来自SQL Server表格的“Last,First”形式的一组名称。标签是从SQL列创建的,如下所示:
$labels{uc($record->{'id'})} = $record->{'lastname'} . ", " . $record->{'firstname'};
问题是下拉列表没有正确显示某些Unicode字符。例如,“Søren”在下拉列表中显示为“Søren”。我有我的标题:
use utf8;
binmode(STDOUT, ":utf8");
...而且我也玩过“ decode()”功能,但无济于事。对我来说,有趣的是,如果我将 $ labels 拉入测试脚本并将列表打印到控制台,名称就会显得很好!那么导致这种下拉的原因是什么呢?提前谢谢。
编辑:
这是相关的功能,我已经剥离了这个在控制台中运行的脚本,为三个具有Unicode字符的条目生成了正确的结果:
#!/usr/bin/perl
use DBI;
use lib '/home/web/library';
use mssql_util;
use Encode;
binmode(STDOUT, ":utf8");
$query = "[SQL query here]";
$dbh = &connect;
$sth = $dbh->prepare($query);
$result = $sth->execute();
while ($record = $sth->fetchrow_hashref())
{
if ($record->{'id'})
{
$labels{uc($record->{'id'})} = Encode::decode('UTF-8', $record->{'lastname'} . ", " . $record->{'nickname'} . " (" . $record->{'entryid'} . ")");
}
}
$sth->finish();
print "$labels{'ST123'}\n";
print "$labels{'ST456'}\n";
print "$labels{'ST789'}\n";
生产脚本的不同之处在于,不是像上面那样打印到控制台,而是打印到HTTP:
$my_output = "<p>$labels{'ST123'}</p><br>
<p>$labels{'ST456'}</p><br>
<p>$labels{'ST789'}</p>";
$template =~ s/\$body/$my_output/;
print header(-cookie=>$cookie) . $template;
这会在页面上显示“ZoÔ和“Søren”之类的字符串。但是,如果我从生产脚本的顶部删除binmode(STDOUT, ":utf8");
,那么字符串在页面上显示就好了(即我得到“Zoë”和“Søren”)。
我认为在将UTF-8写入输出时必须使用binmode()行,而在此处删除它会产生正确的结果。是什么给了什么?
答案 0 :(得分:3)
问题#1:解码输入
53.C3.B8.72.65.6E
是Søren
的UTF-8编码。当你指示Perl重新编码它时(通过打印它来处理:utf8
图层),你就会产生垃圾。
您需要解码输入($record->{id}
,$record->{lastname}
,$record->{firstname}
等)!这会将UTF-8字节53.C3.B8.72.65.6E
(“编码文本”)转换为Unicode代码点53.F8.72.65.6E
(“已解码文本”)。
在此表单中,您将能够使用uc
,正则表达式匹配等。您还可以将它们打印到带有编码层的句柄(例如:encoding(UTF-8)
),或者不正当:utf8
)。
您可以告诉我们这些输入来自数据库。大多数DBD都有一个标志,可以解码字符串。例如,如果它是MySQL数据库,则应将mysql_enable_utf8mb4 => 1
传递给connect
。
问题#2:传达编码
如果您要输出UTF-8,请不要告诉浏览器它是ISO-8859-1!
$ perl -e'use CGI qw( :standard ); print header()'
Content-Type: text/html; charset=ISO-8859-1
修正:
$ perl -e'use CGI qw( :standard ); print header( -type => "text/html; charset=UTF-8" )'
Content-Type: text/html; charset=UTF-8
答案 1 :(得分:2)
很难给出明确的解决方案,因为您没有给我们提供更多有用的信息。但这里有一些可能会有所帮助的指示。
p
只告诉Perl您的源代码编码为UTF-8。它没有任何用处。