【问题标题】:PHP SoapClient malformed xmlPHP SoapClient 格式错误的 xml
【发布时间】:2015-08-17 22:16:37
【问题描述】:

我正在使用 php 与 SOAP 中的 web 服务进行通信。这是我的代码:

$data = array('name' => 'test', 'age' => 20);
$WDSL = 'http://xxx.xxxxx.xxx/wdsl.ibs?wsdl';
$SOAP = new SoapClient($WDSL, array('trace' => true));
$RESULT = $SOAP->__soapCall('Some_Service', $data);

由于某种原因,XML 是错误的:

<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Some_Crap"><SOAP-ENV:Body><ns1:Some_Service/><param1>test</param1><param2>20</param2> ...

当它应该是变量名时,为什么XML节点名是paramX?我做错了什么??

谢谢

更新: 所以我列出了该网络服务的功能,我得到的是:

Some_Service_Response Some_Service(Some_Service $parameters))

我改变了我的电话,现在是这样:

$SOAP->__call('Some_Service', array('Some_Service', $data));

而且 XML 仍然是错误的:

<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="
http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:iwaysoftware:ibse:jul2003:HR_Master"><SOAP-ENV:Body><ns1:Some_Service/>
<param1><item><key>SomeKey</key><value>SomeValue</value> ....

我仍然收到<param1><item><key>SomeKey</key><value>SomeValue</value> instead of <Somekey>SomeValue</Somekey>

所以问题是,Web 服务是否工作不正常,还是我这边?

【问题讨论】:

    标签: php soap


    【解决方案1】:

    SoapClient 类根据服务的 WSDL 进行了许多更正,例如删除无效标签。检查WSDL,它可能包含参数的名称是param1param2

    调用 SoapClient::__getFunctions()SoapClient::__getTypes() 并转储结果可以很好地总结 PHP 从您的 WSDL 中理解的内容。


    (OP更新后SoapClient::__getFunctions()输出的问题是:

    Some_Service_Response Some_Service(Some_Service $parameters))
    

    )

    通常数组键是参数名,而不是类型。所以我的第一个猜测是:

    $SOAP->__call('Some_Service', array('parameters', $data));
    

    问题可能出在服务器端。 WSDL 不兼容有时需要手动调整 WSDL 文件,以便 PHP 发出您想要的相同 XML。

    但在进行任何黑客攻击之前(如果有机会)请务必在没有 PHP 的情况下试用该服务,以查看该服务对不同 XML 文件的反应。一个名为SoapUI 的好程序可以为您执行此操作,它会自动生成要测试的 XML 存根。 (我只遇到了需要数字签名的 Web 服务的 SoapUI 问题。)

    根据 XML 测试的结果,您可能需要:

    • 手动调整 WSDL
    • 手动生成 XML 文件并将其发送到 Web 服务器(最后的手段)
    • 如果 XML 几乎是正确的,它只需要一个小的微调你也可以从 SoapClient 类派生并覆盖 SoapClient::__doRequest 方法在提交到服务器之前对 XML 文件进行字符串操作(通过调用基类的__dorequest)。例如,当 Web 服务需要在某些标签上重新发送某些 XML 属性时,我使用了此解决方案。

    【讨论】:

    • 这是我得到的:Array ( [0] => struct ibsinfo { string service; string method; string license; string disposition; string Username; string Password; string language; } [1] => struct adapterexception { string error; } [2] => struct Some_Service { Some_Service_ComplexType hr_master; } [3] => struct Some_Service_ComplexType { WS_Transaction_ID WS_Transaction_ID; Web_Service_Request_Type...
    • 请把它放在问题中,因为 (a) 它属于那里 (b) cmets 不能有换行符以提高可读性 (c) cmets 长度有限,并且缺少有趣的部分
    • Csq,感谢您的解释。 array('parameters', $data) 没有好处,实际上与 array('somecrap', $data) 一样。即使我不能很好地解决这个问题,我也会给你奖励。
    【解决方案2】:

    如果我是你,我会尝试以对象格式设置 $data。

    $data = array('name' => 'test', 'age' => 20);
    

    例如:

    $data = null;
    $data->name = "test";
    $data->age = 20;
    
    $RESULT = $SOAP->__soapCall('Some_Service', $data);
    

    【讨论】:

    • 这是如何工作的?文档 (php.net/manual/pl/soapclient.soapcall.php) 说 __soapCall 的第二个参数必须是一个数组。
    • 我知道..因此那个帖子和那个答案并没有真正“匹配”文档......所以我猜文档不是最新的?
    • 对于那些对此有疑问的人,您必须使用带有soapCall的数组,但是如果您直接调用该函数,则可以使用此处建议的对象类型。
    猜你喜欢
    • 2015-10-14
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多