PHP使用WSDL模式调用WebService无法获取返回值及响应匹配问题
问题解决思路
PHP端获取返回值的方案
1. 直接解析原始SOAP响应
当自动生成的响应对象属性为null但原始响应有内容时,绕过对象映射直接解析XML:
$client = new SoapClient('your_wsdl_url', ['cache_wsdl' => WSDL_CACHE_NONE]); try { $client->sayHello(['name' => 'Mauro']); // 获取原始响应XML $rawResponse = $client->__getLastResponse(); $xml = new SimpleXMLElement($rawResponse); // 根据实际响应的元素名提取结果(比如旧版的greeting) $result = (string)$xml->Body->sayHelloResponse->greeting; echo $result; // 输出 Hello Mauro! } catch (SoapFault $e) { echo $e->getMessage(); }
2. 强制关闭WSDL缓存
PHP默认会缓存WSDL文件,导致读取旧定义,构造SOAPClient时明确禁用缓存:
$client = new SoapClient('your_wsdl_url', [ 'cache_wsdl' => WSDL_CACHE_NONE, 'trace' => true // 开启trace才能获取原始响应 ]);
3. 自定义类映射(可选)
如果确定WSDL和实际响应的元素名不匹配(比如WSDL定义sayHelloResult,实际返回greeting),可以用classmap手动映射响应结构:
class SayHelloResponse { public $greeting; } $client = new SoapClient('your_wsdl_url', [ 'cache_wsdl' => WSDL_CACHE_NONE, 'classmap' => ['sayHelloResponse' => 'SayHelloResponse'] ]); $response = $client->sayHello(['name' => 'Mauro']); echo $response->greeting; // 直接访问属性
Python Zeep库解决元素不匹配问题
1. 彻底清除Zeep缓存
Zeep默认会缓存WSDL和XMLSchema,手动删除缓存目录:
- Linux/macOS: 删除
~/.cache/zeep目录 - Windows: 删除
C:\Users\<你的用户名>\AppData\Local\Temp\zeep目录
2. 调用时禁用缓存
创建Zeep Client时直接关闭缓存:
from zeep import Client client = Client('your_wsdl_url', cache=False) result = client.service.sayHello('Mauro') print(result)
3. 跳过响应验证(临时方案)
如果无法修改WSDL,可临时关闭严格模式跳过元素匹配检查:
from zeep import Client from zeep.wsdl import settings settings.strict = False client = Client('your_wsdl_url', cache=False) result = client.service.sayHello('Mauro') print(result)
4. 自定义响应元素映射(进阶)
如果明确知道WSDL和实际响应的差异,可手动修改Zeep的类型定义:
from zeep import Client, xsd client = Client('your_wsdl_url', cache=False) # 获取原有的响应类型 sayHello_response_type = client.wsdl.types.get_type('{your_namespace}sayHelloResponse') # 替换元素名:把sayHelloResult改成greeting sayHello_response_type.elements = [ xsd.Element( 'greeting', sayHello_response_type.elements[0][1] # 复用原有的类型 ) ] # 重新生成服务代理 service = client.create_service( '{your_namespace}YourServicePort', 'your_service_endpoint_url' ) result = service.sayHello('Mauro') print(result)
内容的提问来源于stack exchange,提问作者Muc
相关产品推荐
相关产品推荐

