3

SoapClient を直接使用すると、「XML ドキュメントがないように見えます」という例外が発生しますが、例外をキャッチしてにアクセスすると、$client->__lastReponse()ここで説明されている完全なメッセージが表示されます: http://www.w3.org/TR/ SOAP 添付ファイル#SOAPMultipart

例:

------=_Part_13_5075710.1359624351743
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <740ABC2FC7835A4DF5526C699A3C302D>

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:GetOneFileResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://schemas.cisco.com/ast/soap/"><DataHandler href="cid:8D6C4A5AD0F2C0339324FBFC92417B5C" xsi:type="ns2:DataHandler" xmlns:ns2="DimeGetFileService"/></ns1:GetOneFileResponse></soapenv:Body></soapenv:Envelope>
------=_Part_13_5075710.1359624351743
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Id: <8D6C4A5AD0F2C0339324FBFC92417B5C>

Binary data here 

------=_Part_13_5075710.1359624351743--

これを解析する適切な方法は何ですか。バイナリ データが、SOAP サービスを介してダウンロードしようとしているテキストとしての私の要求の例であると仮定します。

バイナリ添付ファイル ( MTOM ) の処理機能を持っているように見えるが、拡張が必要な​​ WSO2などの追加の拡張なしでこれを解決したい

4

1 に答える 1

1

これは間違いなくこれを行うための「適切な方法」ではありませんが、私のユースケースではうまくいきました:

$client = new SoapClient($wsdl);
try {
  $client->MySoapFunction($argument);
} catch (SoapFault $e)
    {
        if ($e->getMessage() == 'looks like we got no XML document') {
            $response = $client->__getLastResponse();

            $data = $this->_stripSoapHeaders($response);
            return $this->_parseMimeData($data);
        }

protected function _stripSoapHeaders($response)
{
    // Find first occurance of xml tag
    preg_match('/(?<xml><.*?\?xml version=.*>)/', $response, $match);
    $xml = $match['xml'];

    // Strip SOAP http headers, and SOAP XML
    $offset = strpos($response, $xml) + strlen($xml . PHP_EOL);
    return substr($response, $offset);
}
protected function _parseMimeData($data)
{
    // Find MIME boundary string
    preg_match('/--(?<MIME_boundary>.+?)\s/', $data, $match);
    $mimeBoundary = $match['MIME_boundary']; // Always unique compared to content

    // Copy headers to client
    if (preg_match('/(Content-Type: .+?)'.PHP_EOL.'/', $data, $match)) {
        header($match[1]);
    }
    $contentType = $match[1];
    if (preg_match('/(Content-Transfer-Encoding: .+?)'.PHP_EOL.'/', $data, $match)) {
        header($match[1]);
    }

    // Remove string headers and MIME boundaries from data
    preg_match('/(.*Content-Id.+'.PHP_EOL.')/', $data, $match);
    $start = strpos($data, $match[1]) + strlen($match[1]);
    $end = strpos($data, "--$mimeBoundary--");
    $data = substr($data, $start, $end-$start);

    return trim($data, "\r\n");
}

上記のコードを使用して、SOAP API を介して gzip されたバイナリ ファイルを正常にダウンロードしました。

于 2013-02-01T15:08:44.413 に答える