You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP SoapClient调用返回base64压缩包的MTOM SOAP接口报错问询

报错信息:

SoapFault: Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'multipart/related; type="application/xop+xml"'. in file /app/app/Http/Middleware/MTOMSoapClient.php on line 8
报错底层原因
  • 目标SOAP接口启用了MTOM(消息传输优化机制),该机制专为二进制附件传输设计,要求请求头Content-Type必须为multipart/related; type="application/xop+xml",你当前发起的请求仍使用普通SOAP的text/xml请求头,因此被服务端拦截
  • 你之前使用的自定义MTOMSoapClient未正确改写请求头构造逻辑,也没有在请求体中声明XOP支持,导致请求格式不符合服务端要求
解决方案

方案1:使用修正版自定义MTOMSoapClient

第一步:编写正确的MTOMSoapClient类

class MTOMSoapClient extends \SoapClient
{
    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        // 构造MTOM请求边界标识
        $boundary = "MTOMBoundry_" . md5(uniqid(time()));
        // 替换请求头为MTOM要求的格式
        $headers = [
            "Content-Type: multipart/related; type=\"application/xop+xml\"; boundary=\"$boundary\"; start=\"<rootpart@soapui.org>\"; start-info=\"text/xml\"",
            "SOAPAction: \"$action\"",
        ];
        // 构造MTOM格式请求体
        $body = "--$boundary\r\n";
        $body .= "Content-Type: application/xop+xml; charset=UTF-8; type=\"text/xml\"\r\n";
        $body .= "Content-Transfer-Encoding: 8bit\r\n";
        $body .= "Content-ID: <rootpart@soapui.org>\r\n\r\n";
        $body .= $request . "\r\n";
        $body .= "--$boundary--";

        // 使用CURL发起请求
        $ch = curl_init($location);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        curl_close($ch);

        // 解析MTOM响应,提取XML内容
        $response = preg_replace('/--.*[\r\n]+/', '', $response);
        $response = preg_replace('/Content-Type: [^\r\n]+[\r\n]+/', '', $response);
        $response = preg_replace('/Content-Transfer-Encoding: [^\r\n]+[\r\n]+/', '', $response);
        $response = preg_replace('/Content-ID: [^\r\n]+[\r\n]+/', '', $response);
        $response = trim($response);

        return $response;
    }
}

第二步:调用代码示例

// 初始化客户端
$client = new MTOMSoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));

$user_param = array (
    'DealerCode' => "1234",
    'Hash' => "asjdfasjda1231231231",
    'Password' => "somerandompassword",
    'UserName' => "somerandomusername"
);

$result = $client->__soapCall("DownloadOffer", array($user_param));
// 提取返回的base64编码zip内容,字段名根据实际接口返回调整
$zipContent = base64_decode($result->DownloadOfferResult->FileContent);
// 保存到本地文件
file_put_contents('./offer.zip', $zipContent);

方案2:使用成熟组件laminas-soap(推荐)

laminas-soap原生支持MTOM处理,无需自己开发底层逻辑,使用步骤如下:

  1. 安装依赖
composer require laminas/laminas-soap
  1. 调用代码示例
use Laminas\Soap\Client;

$client = new Client($url, [
    'soap_version' => SOAP_1_1,
    'mtom' => true, // 直接开启MTOM支持
]);

$user_param = array (
    'DealerCode' => "1234",
    'Hash' => "asjdfasjda1231231231",
    'Password' => "somerandompassword",
    'UserName' => "somerandomusername"
);

$result = $client->DownloadOffer($user_param);
// 提取附件内容保存即可

内容的提问来源于stack exchange,提问作者Susy11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 21:45:03