【发布时间】:2022-01-14 15:56:02
【问题描述】:
我正在尝试从 mysql 获取 UTF-8 重音字符“锓ê”,并在通过 SMPP 发送时将它们转换为 UCS-2。数据存储为 utf8_general_ci,我在打开数据库连接时执行以下操作:
$dbh->{'mysql_enable_utf8'}=1;
$dbh->do("set NAMES 'utf8'");
如果我通过使用 data_encoding=8 用“锓ê”对字符串值进行硬编码来测试发送部分,它会完美地通过。但是,如果我注释掉第一行并只使用来自数据库的内容,它就会失败。此外,如果我尝试使用 DB 发送字符并设置 data_encoding=3,它也可以正常工作,但是不会出现“ê”,这也是预期的。这是我使用的:
$fred = 'éêcole'; <-- If I comment out this line, the SMPP call fails
$fred = decode('utf-8', $fred);
$fred = encode('UCS-2', $fred);
$resp_pdu = $short_smpp->submit_sm(
source_addr_ton => 0x00,
source_addr_npi => 0x01,
source_addr => $didnb,
dest_addr_ton => 0x01,
dest_addr_npi => 0x01,
destination_addr => $number,
data_coding => 0x08,
short_message => $fred
) or do {
Log("ERROR: submit_sm indicated error: " . $resp_pdu->explain_status());
$success = 0;
};
data_coding 字段的不同值如下: Meaning of "data_coding" field in SMPP
00000000 (0) - usually GSM7
00000011 (3) for standard ISO-8859-1
00001000 (8) for the universal character set -- de facto UTF-16
SMPP 提供程序的文档还提到应通过 UCS-2 处理特殊字符: https://community.sinch.com/t5/SMS-365-enterprise-service/Handling-Special-Characters/ta-p/1137
我应该如何准备来自数据库的数据以使这个 SMPP 调用正常工作?
我正在使用 Perl v5.10.1
谢谢!
【问题讨论】:
-
decode('utf-8', $fred)在我看来很可疑。$dbh->{'mysql_enable_utf8'}=1;的目的不是解码返回的值吗?如果是这样,解决方法是删除$fred = decode('utf-8', $fred);。如果是这样,您的工作程序可以正常工作,因为它是使用 UTF-8 编码的,但您隐含地告诉 Perl 它是使用 ASCII 编码的,而不是使用use utf8;。 -
请提供
sprintf "%vX", $s的工作值和失败值(从解码/编码之前开始)。如果我在前面的评论中是对的,那么当它失败时你会看到代码点(E9 代表 é),而当它成功时你会看到一个使用 UTF-9 编码的字符串(C3 A9 代表 é IIRC)。 -
所以当我使用存储的值并在编码/解码之前打印 sprintf 时,我得到的是:E9.EA.63.6F.6C.65,所以你是对的。然后,如果我删除解码 utf-8 部分并只留下编码 ucs-2,我现在得到“é cole”,缺少 ê。然后,如果我添加使用 utf8;在顶部,我得到了相同的结果。
-
所以如果我添加使用 utf8;编码 ucs-2 之前的输出为 E9.EA.63.6F.6C.65,一旦编码完成,输出变为 0.E9.0.EA.0.63.0.6F.0.6C.0.65
-
如果我将 use utf-8 放在顶部,并解码 utf8,解码后的输出是 FFFD.FFFD.63.6F.6C.65 并且一旦编码回 ucs-2输出为 FF.FD.FF.FD.0.63.0.6F.0.6C.0.65
标签: mysql perl encoding smpp ucs2