土耳其字符无法正确呈现

时间:2017-05-02 09:30:42

标签: windows apache perl character-encoding cgi

我在Perl中遇到土耳其语问题。我设置了土耳其语字符集,但我的土耳其字符显示不正确。

这是我的Perl脚本。

#!"c:\xampp\perl\bin\perl.exe"

use strict;
use warnings;

use CGI qw(:standard);

my $name    = param('name');
my $surname = param('surname');
my $age     = param('age');
my $gender  = param('gender');

my $q = new CGI;

# We're outputting plain text, not HTML
print $q->header(-content_type => 'text/plain' ,  -charset => 'ISO-8859-9');

my $text = $name." ".$surname." ".$age." ".$gender." kaydı, sistemde yapılacak olan güncellemelerden sonra sisteme başarıyla eklenecektir."; 

# printf("%s %s %d %d kaydı, sistemde yapılacak olan güncellemelerden sonra sisteme başarıyla eklenecektir.", $name , $surname , $age , $gender);

print $text;

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

首先:不要在CGI.pm中使用HTML生成功能。使用它们会导致表达层无法维护。相反,使用基于Template Toolkit的模板来分隔演示文稿和功能。

其次,请勿使用indirect object notation。也就是说,不要写:

my $cgi = new CGI;

相反,写一下

my $cgi = CGI->new

使用$q$query来引用CGI对象是很奇怪的,它源于WWW的早期阶段。当你从零开始学习时,没有理由使它永久化。

此外,假设您刚刚实例化了一个对象,请不要使用param之类的普通子进程,也不要污染脚本的命名空间。使用以下方法访问参数值:

 my $value = $cgi->param('surname');

最后,如果您要在源代码中使用“有趣”字符,例如Ş,请将源代码保存为UTF-8并指定

 use utf8;

位于脚本的顶部。

最后,还要将所有HTML模板保存为UTF-8,并从UTF-8编码的脚本生成所有输出,并将文档编码指定为UTF-8。所有其他路径都会导致精神错乱。

另外,请勿使用sexual作为参数名称。使用名词作为参数和变量名。而且,对我来说,作为土耳其人的最令人愤怒的是,(Bay)先生和Bayan女士只是头衔,并且他们不适合询问受访者性别的输入领域。

另请参阅How can I deal with diverse gender identities in user profiles?目前在土耳其可能不会出现这种情况,但您最终会遇到此问题。

这是一个可能适合您的未经测试的脚本:

#!"c:\xampp\perl\bin\perl.exe"

use utf8;
use strict;
use warnings;
use warnings  qw(FATAL utf8);

# Provides only object oriented interface
# without HTML generation cruft

use CGI::Simple;

run( CGI::Simple->new );

sub run {
    my $cgi = shift;
    binmode STDOUT, ':encoding(UTF-8)';

    my ($name, $surname, $age, $gender) = map $cgi->param($_), qw(name surname age gender);
    print $cgi->header(-type => 'text/plain', -charset => 'utf-8');

    printf("%s %s %d %d kaydı, sistemde yapılacak olan güncellemelerden sonra sisteme başarıyla eklenecektir.\n",
        $name , $surname , $age , $gender);

    return;
}

答案 1 :(得分:1)

我认为您误解了charset标题上Content-type属性的用途。您的程序正在发出此标题:

Content-Type: text/plain; charset=ISO-8859-9

这说到HTTP客户端(例如浏览器)“我将向您发送一些编码为ISO-8859-9的纯文本”。但重要的是要注意标题纯粹是信息性的。它告诉全世界您的文本被编码为ISO-8859-9。 为您执行编码。这取决于你。

这就是为什么鲍罗丁和其他人一直在问你一些你没有回答过的问题。大多数编辑器将创建以ISO-8859-1或UTF-8编码的文本。除非您有一个特殊的土耳其语编辑器或者您更改了编辑器的配置,否则您似乎不太可能在ISO-8859-9中生成文本。

如果您决定发出ISO-8859-9文本,那么您需要自己进行编码。您可以使用Encode模块中的encode()函数来执行此操作。

use Encode;

my $encoded_text = encode('ISO-8859-9', $text);
print $encoded_text;

但我想知道你为什么要使用像ISO-8859-9这样相对模糊的编码。 UTF-8涵盖了土耳其语中使用的所有字符。为什么不用它呢?如果你采用与网络相同的标准,你的生活将变得容易得多。

顺便说一下,你在代码中引入了一个小小的陌生感。您在“函数”模式下使用CGI.pm并以一种将其大量函数导入命名空间的方式加载它。

use CGI qw(:standard);

然后以这种方式使用param()函数几次。但之后,您创建一个CGI查询对象,以便在其上调用header()方法。

my $q = new CGI;
print $q->header(...);

您可能没有意识到,但header()函数包含在:standard导入集中,因此您可以在不创建CGI对象的情况下调用它。

print header(...);

我在回答你之前的问题时就这样使用了它。我不确定你为什么改变代码使它变得更复杂。

我还应该指出,如果你想创建一个CGI查询对象,那么就不应该使用间接对象表示法:

my $q = new CGI;

这会在某些时候引起问题。写得好得多:

my $q = CGI->new;

(如the CGI.pm documentation中所示)