【发布时间】:2017-10-27 22:04:51
【问题描述】:
我已经在这个问题上讨论了一段时间,但还是不太明白。这是 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( ) 行,但在此处删除它会产生正确的结果。什么给了?
【问题讨论】:
-
您需要检查 $record->{'lastname'} 和 $record->{'firstname'} utf8 标志使用 Encode:is_utf8()。如果它们都是 utf8 或者不是,你可以将它们连接起来。
-
请为不能正常工作的字符串提供
sprintf "%vX", $value的输出,并提供您希望看到的该字符串的输出。 -
从不使用
Encode::is_utf8,调试语句除外。依赖其结果的代码肯定是有问题的。 -
谢谢@ikegami。我得到:53.C3.B8.72.65.6E,对于我希望显示为“Søren”但显示为“Søren”的字符串。我的测试脚本正确地将“Søren”和“53.F8.72.65.6E”打印到控制台。
-
看来我从数据库中读取数据还不错,并且是 HTTP 响应编码导致了问题(我认为,正如 Dave 所建议的那样)。
标签: perl unicode encoding utf-8