如何用PHP发送带XML负载的SOAP请求对接自动电子立案服务
PHP对接密苏里州司法交换平台自动电子立案SOAP服务实现方案
核心问题定位
绝大多数PHP调用失败的核心原因是该服务采用MTOM格式的SOAP 1.1协议传输,同时携带XML业务payload和二进制立案文档,和普通纯XML结构的SOAP请求有本质区别:
- PHP原生
SoapClient默认关闭MTOM支持,手动拼接XML传二进制会出现MIME边界错误、编码不合法、鉴权头缺失等问题 - 通用HTTP客户端(包括WordPress自带的
wp_remote_post)默认会对请求体做转义处理,直接破坏MTOM报文结构 - 官方Java示例默认启用了MTOM自动处理、标准WS-Security鉴权头,很多人复刻时遗漏了这部分配置
前置准备
- 服务器PHP版本≥7.4,提前启用
soap、curl、fileinfo三个扩展 - 从Automated Filing IEPD安装包中提取对应环境(测试/生产)的WSDL文件,存到服务器本地可读取目录,不要通过远程地址加载WSDL,避免官方鉴权拦截导致解析失败
- 准备好已填入访问凭证的
request.xml业务报文、需要上传的立案二进制文件(PDF等)
可直接运行的实现代码
1. 客户端初始化(含鉴权配置)
根据你持有的凭证类型选择对应鉴权方式,绝大多数场景为WS-Security用户名令牌鉴权:
<?php // 替换为本地WSDL文件实际路径 $wsdlLocalPath = __DIR__ . '/mo-automated-filing-prod.wsdl'; $clientConfig = [ 'trace' => true, // 排错阶段必须开启,上线后可关闭 'exceptions' => true, 'soap_version' => SOAP_1_1, // 强制使用SOAP 1.1,该服务不支持SOAP 1.2 'mtom' => true, // 核心配置:开启MTOM附件传输支持 'encoding' => 'UTF-8', 'connection_timeout' => 30, 'cache_wsdl' => WSDL_CACHE_MEMORY, ]; $client = new SoapClient($wsdlLocalPath, $clientConfig); // 配置WS-Security鉴权头,替换为你自己的访问凭证 $wsseHeaderXml = <<<XML <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1"> <wsse:UsernameToken> <wsse:Username>你的专属访问用户名</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">你的专属访问密码</wsse:Password> </wsse:UsernameToken> </wsse:Security> XML; $securityHeader = new SoapHeader( 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', 'Security', new SoapVar($wsseHeaderXml, XSD_ANYXML), true ); $client->__setSoapHeaders([$securityHeader]);
2. 构造请求报文与附件
注意所有节点名、字段名必须和WSDL中定义的名称完全一致,大小写敏感:
// 加载已填好的业务XML payload $filingXmlContent = file_get_contents(__DIR__ . '/request.xml'); $filingPayload = new SoapVar( $filingXmlContent, XSD_ANYXML, null, null, 'FilingMessage' // 替换为WSDL中定义的业务报文节点名 ); // 构造二进制附件,多附件可循环生成对应对象 $caseDocPath = __DIR__ . '/complaint.pdf'; // 替换为实际立案文件路径 $caseDocContent = file_get_contents($caseDocPath); $caseDocMime = mime_content_type($caseDocPath); // 自动识别文件MIME类型,不要硬写 $docAttachment = new SoapVar( $caseDocContent, XSD_BASE64BINARY, null, null, 'DocumentAttachment' // 替换为WSDL中定义的附件节点名 ); // 组装完整请求参数 $requestParams = [ 'FilingMessage' => $filingPayload, 'DocumentAttachment' => $docAttachment ];
3. 发起请求与排错
调用的方法名必须和WSDL中定义的提交立案操作名完全一致:
try { // submitAutomatedFiling替换为WSDL中定义的实际提交方法名 $response = $client->submitAutomatedFiling($requestParams); // 处理成功响应,提取立案回执编号等信息 var_dump($response); } catch (SoapFault $e) { // 排错阶段打印全量请求响应报文,和官方Java示例的报文做逐段对比 echo "错误信息:{$e->getMessage()}" . PHP_EOL; echo "请求头:" . $client->__getLastRequestHeaders() . PHP_EOL; echo "请求体:" . $client->__getLastRequest() . PHP_EOL; echo "响应头:" . $client->__getLastResponseHeaders() . PHP_EOL; echo "响应体:" . $client->__getLastResponse() . PHP_EOL; }
常见失败场景排查清单
- 不要手动对二进制文件做
base64_encode处理,MTOM机制会自动完成编码,手动编码会导致文件损坏被平台驳回 - 注意区分测试/生产环境的WSDL、访问凭证、服务端点,跨环境调用会直接被鉴权拦截
- 所有XML节点的命名空间必须和官方示例、WSDL定义完全一致,缺失命名空间会被判定为非法请求
- WordPress环境集成时不要使用
wp_remote_post发送请求,该方法默认的请求体过滤逻辑会破坏MTOM报文的MIME边界结构,直接用上述SoapClient实现即可 - 如果PHP版本低于7.4出现MTOM兼容问题,可以通过CURL手动构造带MIME边界的multipart/related格式报文,边界字符串、Content-Type头必须和SOAP 1.1 MTOM规范完全对齐
内容的提问来源于stack exchange,提问作者Patrick Sasser
相关产品推荐
相关产品推荐

