PHP SoapClient中的unicode字符损坏

时间:2014-05-12 13:47:23

标签: php soap unicode utf-8

我们的一个客户要求我们使用SOAP将一些交易信息发送到他们的API。其中一个字段需要修剪为30个字符,因此我们mb_substr()如下:

$params->Request->Description = mb_substr($title, 0, 30, 'UTF-8');

我们按如下方式实例化SoapClient对象:

$client = new SoapClient(
                    $wsdlUri,
                    array(
                        'trace' => 1,
                        'exceptions' => true, 
                        'cache_wsdl' => WSDL_CACHE_NONE, 
                        'soap_version' => SOAP_1_2, 
                        'encoding' => 'UTF-8'
                    )
                );

我的理解是,这将告诉SoapClient字符串将以UTF-8格式提供,当我们修剪为30个字符时,我们将其设置为30个UTF-8字符,而不是30个字节。 / p>

Sound of Contact - Möbius Slip正在Sound of Contact - Möbius Slip发送。 Call of Duty®: Ghosts Gold Edition正在Call of Duty®: Ghosts Gold Edi发送。我可以看到这里有31个字符,这就是远程服务拒绝呼叫的原因。如果标题少于31个字符,那么它就会很好,即使字符被编码损坏了。

我们知道$title是可以的,因为我们通过SOAP将这个(整个事情)发送到其他来源没有问题;它存储在远程系统中并正确显示。这只是我们遇到问题的一个Web服务。我在实例化SoapClient对象时做错了什么?我错误地使用mb_substr()了吗?还有其他我错过的东西吗?

这是正在生成的XML的示例:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ourclient/webservices/" xmlns:ns2="http://ourclient/webservices/method/" xmlns:ns3="http://www.w3.org/2005/08/addressing">
  <env:Header>
    <ns3:Action>http://ourclient/webservices/method/action</ns3:Action>
  </env:Header>
  <env:Body>
    <ns1:Method>
      <ns1:Request>
        <!-- CROPPED -->
        <ns1:Description>Call of Duty®: Ghosts Gold Edi</ns1:Description>
      </ns1:Request>
    </ns1:Method>
  </env:Body>
</env:Envelope>

由于

1 个答案:

答案 0 :(得分:0)

事实证明我们做的一切都是正确的,但是我们遇到了字符串UTF-8字符的问题,其中字符串是&gt; API拒绝此数据时为30个字节。经过大量测试并与服务提供商来回,我们最终确定问题实际上已经结束。他们告诉我们他们会接受30个UTF-8字符,但实际上它是30字节的UTF-8字符。解决方案实际上是使用mb_strcut()方法:http://php.net/manual/en/function.mb-strcut.php

$params->Request->Description = mb_strcut($title, 0, 30, mb_detect_encoding($title));

这将修剪为30个字节(简单substr()会)但是如果它在多字节字符的中途修剪它将在当前字符之前回溯到仅在&lt; =返回完整字符30个字节。

自从我们部署此解决方案以来,我们没有进一步的问题。 看起来的原因就像我们发送破碎的信息一样,原因是日志输出严重(facepalm)