Clickatell阿拉伯文本出现乱码问题

3

我正在尝试使用PHP从clickatell短信提供商发送阿拉伯文本,但到目前为止我只能发送乱码。我用于测试的文本是"غثس هفس"。

我尝试使用iconv将消息文本编码为Windows-1256、1250和ISO-8859-6格式,但每次都只发送乱码。

请问有人可以给我一些提示吗?

先行致谢。


Clickatell 的文档是否指定了任何编码方式?这可能也因语言、运营商和/或接收手机而有所不同。 - deceze
我在 Clickatell 的文档中没有看到任何特定的编码细节。现在我已经没有想尝试什么的主意了 :) - pinaki
4个回答

3

好的,这是留给以后遇到此问题的人的。在这里找到了解决方案(点击此处)。 保留Esailija答案中的代码。

<?php
$text = "غثس هفس خن";
$arr = unpack('H*hex', iconv('UTF-8', 'UCS-2BE', $text));
$message = strtoupper($arr['hex']);

$username = '';
$password = '';
$API_ID = '';
$to = '';

$url = "http://api.clickatell.com/http/auth?user=$username&password=$password&api_id=$API_ID";
$ret = file($url);
$sess = explode(":",$ret[0]);
if ($sess[0] == "OK") {
    $sess_id = trim($sess[1]);
    $url = "http://api.clickatell.com/http/sendmsg?session_id=$sess_id&to=$to&text=$message&unicode=1";
    $ret = file($url);
    $send = explode(":",$ret[0]);

    if ($send[0] == "ID") {
        echo "success - message ID: ". $send[1];
    } else {
        echo "send message failed";
    }
} else {
    echo "Authentication failure: ". $ret[0];
}

1
相当不错的发现,它需要使用临时十六进制编码,而不是标准的百分号编码。 - Esailija

1

基于this,默认是GSM,但您也可以选择UCS2。

因此:

<?php
                                 //Make sure the PHP source file is physically
                                //saved in utf-8
$text = rawurlencode(iconv( "UTF-8", "UCS-2", "غثس هفس "));

$url = "http://api.clickatell.com/http/auth?user=username&password=password&api_id=API_ID&encoding=UCS2";
$ret = file($url);
$sess = explode(":",$ret[0]);
if ($sess[0] == "OK") {

    $sess_id = trim($sess[1]);
    $url = "http://api.clickatell.com/http/sendmsg?session_id=$sess_id&to=$to&text=$text&encoding=UCS2";
    $ret = file($url);
    $send = explode(":",$ret[0]);

    if ($send[0] == "ID") {
        echo "successnmessage ID: ". $send[1];
    } else {
        echo "send message failed";
    }
} else {
    echo "Authentication failure: ". $ret[0];
}

谢谢回复。我尝试了相同的代码(复制/粘贴),但仍然发送垃圾文本作为短信。您有关于如何以GSM模式发送的任何指针吗? - pinaki
找到了解决方案。请查看下面的答案。再次感谢您的帮助。 - pinaki

1

我重写了Vtiger 6的ClickATell代码,以便可以容纳UTF-8扩展字符。我使用土耳其语。我使用以下代码进行转换。希望您能够移植。

/**
 * Function to handle UTF-8 Check and conversion
 * @author Nuri Unver
 * 
 */
public function smstxtcode($data){ 
$mb_hex = '';
$utf = 0;
for($i = 0 ; $i<mb_strlen($data,'UTF-8') ; $i++){ 
    $c = mb_substr($data,$i,1,'UTF-8');

    $o = unpack('N',mb_convert_encoding($c,'UCS-4BE','UTF-8')); 
    $hx = sprintf('%04X',$o[1]); 
    $utf += intval(substr($hx,0,2));
    $mb_hex .= $hx;
} 
if ($utf>0)
{
    $return=$mb_hex;
    $utf=1;
}
else
{
    $return=utf8_decode($data);
    $utf=0;
}
return array($utf,$return); 

}

当你使用此函数发送消息时,会得到一个数组作为响应,指示是否发送Unicode或普通文本,具体取决于消息内容,以及要发送的文本。如果没有扩展字符,则将其作为纯文本发送,其中unicode = 0以节省字符。如果消息包含扩展字符,则将消息转换为十六进制代码并作为Unicode发送。
此代码仅执行计算。您需要实现自己的代码将其移植到您的系统中。为演示起见,以下是我用于从Vtiger中提取数据和发送消息的代码:
/**
 * Function to handle SMS Send operation
 * @param <String> $message
 * @param <Mixed> $toNumbers One or Array of numbers
 */
public function send($message, $toNumbers) {
    if(!is_array($toNumbers)) {
        $toNumbers = array($toNumbers);
    }
    $params = $this->prepareParameters();
    $smsarray = $this->smstxtcode($message);
    $params['text'] = $smsarray[1];
    $params['unicode'] = $smsarray[0];
    $params['to'] = implode(',', $toNumbers);
    $serviceURL = $this->getServiceURL(self::SERVICE_SEND);

1

简短回答:你需要做两件事:

a)转换你的阿拉伯信息:

$data = iconv("UTF-8", "UCS-2BE", $data); $data = bin2hex($data);

使用生成的字符串作为你的信息文本。

b)在通过HTTP API发送时,包括unicode参数:

&unicode=1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接