我正在帮助客户将他们的Perl平面文件公告板网站从ISO-8859-1转换为Unicode.
由于这是我第一次,我想知道以下"清单"是否完整.一切都在测试中很好用,但我可能会遗漏一些只会在极少数情况下发生的事情.
这是我到目前为止所做的事情(请原谅我只包括"摘要"代码示例):
确保文件始终以UTF-8读写:
use open ':utf8';
Run Code Online (Sandbox Code Playgroud)确保收到CGI输入为UTF-8(该站点未使用CGI.pm):
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 $_;
Run Code Online (Sandbox Code Playgroud)确保文本打印为UTF-8:
binmode STDOUT, ':utf8';
Run Code Online (Sandbox Code Playgroud)确保浏览器将我的内容解释为UTF-8:
Content-Type: text/html; charset=UTF-8
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
Run Code Online (Sandbox Code Playgroud)确保表单发送UTF-8(只要设置了页面编码,可能不需要):
accept-charset="UTF-8"
Run Code Online (Sandbox Code Playgroud)不要认为我需要以下内容,因为内联文本(菜单,标题等)仅以ASCII格式显示:
use utf8;
Run Code Online (Sandbox Code Playgroud)这看起来合理还是我错过了什么?
编辑:我可能还应该提到,我们将运行一次性批处理来读取所有现有的文本数据文件并将其保存为UTF-8编码.
以下是自定义组件的示例.它只是一个带有标题标签和近距离图像(X)的框:
<?xml version="1.0"?>
<mx:Canvas ... >
<s:VGroup>
<s:Label text="(HEADING TEXT)" ... />
(INSTANCE MXML)
</s:VGroup>
<mx:Image ... />
</mx:Canvas>
Run Code Online (Sandbox Code Playgroud)
在MXML文档中使用组件时,我希望将"(HEADING TEXT)"替换为参数(应该很简单)以及"(INSTANCE MXML)",其中包含多个标签,文本输入,复选框,等等(也许更难).
我找到了这个基于脚本的方法,但如果存在,我想要一个更清晰的编译时解决方案.有什么建议?
好的,这应该非常简单,但我已经搜索了所有答案并阅读了以下主题: 如何在Perl中找到Unicode字符串的长度?
它对我没有帮助.我知道如何让Perl将字符串常量视为UTF-8并返回正确数量的字符(而不是字节),但是当Perl通过我的AJAX调用接收字符串时,它会以某种方式起作用.
下面,我将在unicode中发布三个希腊字母Alpha,Beta和Omega.Perl告诉我长度是6(字节),它应该告诉我只有3(字符).如何获得正确的字符数?
#!/usr/bin/perl
use strict;
if ($ENV{CONTENT_LENGTH}) {
binmode (STDIN, ":utf8");
read (STDIN, $_, $ENV{CONTENT_LENGTH});
s{%([a-fA-F0-9]{2})}{ pack ('C', hex ($1)) }eg;
print "Content-Type: text/html; charset=UTF-8\n\nReceived: $_ (".length ($_)." chars)";
exit;
}
print "Content-Type: text/html; charset=UTF-8\n\n";
print qq[<html><head><script>
var oRequest;
function MakeRequest () {
oRequest = new XMLHttpRequest();
oRequest.onreadystatechange = zxResponse;
oRequest.open ('POST', '/test/unicode.cgi', true);
oRequest.send (encodeURIComponent (document.oForm.oInput.value));
}
function zxResponse () {
if (oRequest.readyState==4 && oRequest.status==200) {
alert (oRequest.responseText);
}
}
</script></head><body>
<form name="oForm" method="POST">
<input type="text" name="oInput" …Run Code Online (Sandbox Code Playgroud) 如何将长Perl脚本拆分为两个或多个可以访问相同变量的不同文件 - 而不必将所有共享变量从例如重命名$count为$::count(或者$main::count相同)?
换句话说,什么是将Perl脚本拆分成多个文件而不必导入大量变量/函数和/或进行大量手动编辑的最佳和最简单的方法.
我假设它与使代码成为相同的包/范围/命名空间的一部分有关,但到目前为止我的实验都失败了.
我不确定它是否有所作为,但该脚本用于web/CGI目的,并将在mod_perl下运行.
编辑 - 背景:
我知道我会得到那种回应.我想拆分文件的原因如下:
目前我有一个非常古老且非常长的Perl文件.我知道它不遵循Perl最佳实践,但它有效.
问题是,我需要在不同的Web服务器之间分发它使用的数据文件,首先是出于性能原因.将有一个"主"服务器和一个或几个"从属".
大约20%的提到的Perl文件包含共享功能,40%的代码需要在主服务器上运行,40%在从服务器上运行.因此,我想将代码分成三个文件:1.共享,2.仅限master,3.仅奴隶.在主服务器上,将加载1和2,在从站上将加载1和3.
我假设这种方法将使用更少的进程RAM,更重要的是,我将最小化不正确分割代码的风险(例如,从属进程调用主数据文件).我不认为对模块化的需求很大,因为系统工作并且代码不需要与其他项目进行大量更改或交换.
编辑2 - 解决方案:
找到我在这里寻找的解决方案:http: //www.perlmonks.org/?node_id = 95813
在主包属于变量的所有权的情况下,可以省略实际的单词"main"以产生类似于:$ :: var的内容
当严格使用时,可以绕过必须完全限定变量名称.将一个简单的使用变量应用于您的脚本,使用变量名称作为参数将获得显式包名称.
实际上,我最终重复our ($count, etc...)了所需变量的语句,而不是use vars ();
如果我错过了一些重要的事情,除了不使用模块之外,请告诉我!:)
@Axeman,谢谢,我会接受你的回答,既是为了你的努力,也是为了让我朝着正确的方向前进.
通过这个论坛,我了解到使用以下内容将CGI输入(从escape()d Ajax调用或普通HTML表单发送)转换为UTF-8 不是一个好主意:
read (STDIN, $_, $ENV{CONTENT_LENGTH});
s{%([a-fA-F0-9]{2})}{ pack ('C', hex ($1)) }eg;
utf8::decode $_;
Run Code Online (Sandbox Code Playgroud)
更安全的方式(例如,不允许伪造字符通过)是执行以下操作:
use Encode qw (decode);
read (STDIN, $_, $ENV{CONTENT_LENGTH});
s{%([a-fA-F0-9]{2})}{ pack ('C', hex ($1)) }eg;
decode ('UTF-8', $_, Encode::FB_CROAK);
Run Code Online (Sandbox Code Playgroud)
但是,我非常希望避免使用任何模块(包括XSLoader,Exporter以及它们带来的任何其他模块).该函数适用于大量mod_perl驱动的网站,我认为没有模块,性能和可维护性都会更好(特别是因为当前代码不使用任何模块).
我想一种方法是检查Encode模块并去除用于"decode('UTF-8',$ _,Encode :: FB_CROAK)"调用的函数和常量.我不熟悉Unicode和Perl模块来做到这一点.也许其他人有能力这样做或者知道一种类似的,安全的"原生"方式进行UTF-8转换?
更新:
我更喜欢保持非模块化的东西,因为那时唯一的黑盒子是Perl自己的编译器(当然除非你深入到模块库中).
有时您会看到大型模块被一些特定的代码行替换.例如,代替CGI.pm模块(人们也喜欢它),可以使用以下内容来解析AJAX帖子:
my %Input;
if ($ENV{CONTENT_LENGTH}) {
read (STDIN, $_, $ENV{CONTENT_LENGTH});
foreach (split (/&/)) {
tr/+/ /; s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
if (m{^(\w+)=\s*(.*?)\s*$}s) { $Input{$1} = $2; }
else { die ("bad input ($_)"); }
}
}
Run Code Online (Sandbox Code Playgroud)
以类似的方式,如果可以提取或复制Encode的UTF-8解码功能,那将会很棒.