2014-05-12 120 views
0

我們的一位客戶要求我們使用SOAP將一些事務信息發送到其API。需要一個字段被修剪到30個字符,所以我們我們mb_substr()如下:PHP SoapClient中損壞的unicode字符

$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個字節。

Sound of Contact - Möbius Slip正在發送爲Sound of Contact - Möbius SlipCall 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> 

感謝

回答

0

所以事實證明我們是正確的做的一切,但我們有處理字符串的UTF-8字符的問題當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()),但如果它通過一個多字節字符中途修剪它將前的反向跟蹤到當前字符,並且只返回全字符< = 30個字節。

由於我們部署了這個解決方案,我們沒有進一步的問題。其原因是看起來像就像我們發送破碎的信息是由於日誌輸出糟糕(facepalm)