在发送请求之前/不发送请求之前检查由 PHP SoapClient 调用创建的 XML

Posted

技术标签:

【中文标题】在发送请求之前/不发送请求之前检查由 PHP SoapClient 调用创建的 XML【英文标题】:Inspect XML created by PHP SoapClient call before/without sending the request 【发布时间】:2010-12-10 05:32:45 【问题描述】:

问题: 有没有办法在实际发送请求之前查看使用 php SoapClient 函数调用创建的 XML?

背景:

我是 WSDL 通信的新手,我有一个客户希望我用 PHP 进行开发,这是一种与用 ASP.NET 编写的 WSDL 服务进行通信的方法。我已经走了很远,但是在传递复杂类型时遇到了问题。到目前为止,我已经尝试了几种不同的方法。

1) 设置单个数组如$params->Person->name$params->Person->address

2) 设置单个数组$Person = array('name'=>"joe",'address' = "123");

然后作为参数 "Person" => $Person; 传递给调用 和其他一些人。但是每次我得到错误

SoapException:服务器无法 处理请求---> System.Exception: 人是必需的。在服务名称处。

为了进一步排除故障,我想查看正在发送的 XML 文档,以查看它是否正在按照我期望的方式创建复杂类型。 我正在使用$client = new SoapClient('wsdldoc.asmx?WSDL'); 创建服务,并使用$client->CreateUser($params); 调用它,然后尝试使用函数$client->__getLastRequest(); 查看它,但它从未到达__getLastRequest,因为它在调用CreateUser($params) 时遇到致命错误。

问题又来了: 有什么方法可以查看由 CreateUser($params) 调用创建的 XML,而无需实际发送它并导致致命错误

【问题讨论】:

【参考方案1】:

前言:为了成功使用__getLastRequest()方法,您必须在客户端构造时将'trace'选项设置为true:

$client = new SoapClient('wsdldoc.asmx?WSDL', array('trace' => TRUE));

这样,您的请求仍将被发送(因此仍然失败),但您可以通过调用$client->__getLastRequest() 来检查发送的xml之后


主要答案:

要在发送请求之前/不访问生成的 XML,您需要子类化 SoapClient 以覆盖 __doRequest() 方法:

class SoapClientDebug extends SoapClient

  public function __doRequest($request, $location, $action, $version, $one_way = 0) 
      // Add code to inspect/dissect/debug/adjust the XML given in $request here

      // Uncomment the following line, if you actually want to do the request
      // return parent::__doRequest($request, $location, $action, $version, $one_way);
  

然后在调试问题时,您将使用这个扩展类而不是原来的 SoapClient。

【讨论】:

我确实将 trace 设置为 true,但由于某种原因,调用后脚本仍然死掉了。甚至不能做一个 $client->createuser(); 后跟一个 echo "finished call";它永远不会超过呼叫。然而,你的主要答案正是我想要的。谢谢你。我现在发现由于某种原因,我的任何参数都没有在 XML 文档中传递。也许我没有正确调用函数或其他东西。 . . .我会继续寻找。再次感谢。 从未想过重写 __doRequest。这让我看到了解决类似问题需要什么。 SoapClient 失败时会抛出异常。您可能需要将调用包装在 try/catch 块中,以便之后调用 __getLastRequst() 这是一个非常有用的答案,谢谢 Henrik!【参考方案2】:

我在处理同一个问题时发现了这个线程,并且很沮丧,因为我使用的类已经扩展了 SoapClient() 类并且不想过多地使用它。

但是,如果您在启动类时添加"exceptions"=>0 标签,它不会抛出致命错误(尽管它会打印异常):

SoapClient($soapURL, array("trace" => 1, "exceptions" => 0));

这样做让我可以运行 __getLastRequest() 并分析我发送的 XML。

【讨论】:

如果在 __call 或 __soapcall 内验证失败,则返回 null。 为我节省一天时间。没有异常设置为 0 __getLastRequest 不返回任何内容。【参考方案3】:

我不相信有一种方法可以让您看到正在创建的任何 XML...主要是因为该函数在尝试创建/传递它时失败。

不确定您是否已经尝试过,但如果您在尝试确定需要传递给您可以使用的函数的确切内容时遇到问题:

$client->__getTypes();

http://us3.php.net/manual/en/soapclient.gettypes.php

希望这会有所帮助!

【讨论】:

鉴于他得到的异常('SoapException:服务器无法处理请求'),在服务器端引发错误,所以他应该能够通过__getLastRequest()检查发送的XML,如果他使用“跟踪”选项。

以上是关于在发送请求之前/不发送请求之前检查由 PHP SoapClient 调用创建的 XML的主要内容,如果未能解决你的问题,请参考以下文章

在发送通知触发之前完成通知请求

Angular在发送之前获取原始http请求

如何让 Javascript 在发送请求之前等待 Promise?

Axios:网络错误且未发送请求

spring框架发送ajax检查session是不是过期

Camel-netty4:如何在发送下一个请求之前等待响应