欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

How to dump SoapClient request for debug? 如何转储 SoapClient 请求进行调试? 有大用

问过 
查看 85k 次
60

我需要调试一些使用 soap 客户端的代码。我在 php.net 中找到了 getLast* 方法,但是当我尝试获取最后一个调试请求时,它返回 NULL

<?php

    $client = new SoapClient("http://www.webservicex.net/ConverPower.asmx?WSDL");
    
    $response = $client->ChangePowerUnit(array(
        "PowerValue" => 100,
        "fromPowerUnit" => "horsepower",
        "toPowerUnit" => "megawatts"
    ));
    
    
    echo "====== REQUEST HEADERS =====" . PHP_EOL;
    var_dump($client->__getLastRequestHeaders());
    echo "========= REQUEST ==========" . PHP_EOL;
    var_dump($client->__getLastRequest());
    echo "========= RESPONSE =========" . PHP_EOL;
    var_dump($response);

?>

代码执行结果:

$php soap_test.php 

====== REQUEST HEADERS =====
NULL
========= REQUEST ==========
NULL
========= RESPONSE =========
object(stdClass)#2 (1) {
  ["ChangePowerUnitResult"]=>
  float(0.0746)
}

如何获取上次SoapClient 请求的body 和headers 的内容?

3 个回答

59

只有在创建 SoapClient 对象时跟踪选项设置为 TRUE 时,这些函数才有效

尝试:

$client = new SoapClient("http://www.webservicex.net/ConverPower.asmx?WSDL", array('trace' => 1));
  • 3个
    尽管@xdazz 是正确的,但我强烈建议您也添加"exceptions" => 0到 SoapClient 方法中的参数,这样即使收到错误的响应,您也可以查看正在进行的调用。 
    – 龙54
     2017 年 2 月 27 日 19:06 
34

调试 SOAP 请求   

 正确答案


  1. 使用 SOAP 扩展

调试 SOAP 请求的最简单和最好的*方法确实是创建一个SOAP 扩展,它使用SoapClient的以下函数记录来自 Web 服务或 Web 服务客户端的原始 SOAP 请求和原始 SOAP 响应:

要使其工作,您必须创建 SoapClient 对象并打开跟踪选项,如 xdazz 所述:

$client = new MySoapClient($wsdlUrl, array('trace' => 1));

然后运行包含在 try-catch 块中的 SOAP 调用:

try{
   $result = $client->__SoapCall('routeCase', $params);
}catch (\Exception $e){
   throw new \Exception("Soup request failed! Response: ".$client->__getLastResponse());
}

在 PHP 中开发 SOAP 解决方案时,最好在 WSDL 合同更改时清理 PHP tmp 文件夹(请参阅参考资料中的tmp文件夹路径phpinfo())以强制 PHP SoapClient 再次下载 WSDL 和 XSD 文件而不是使用缓存文件(直到它们会过期)。

exceptions此外,在开发时设置诸如和版本之类cache_wsdl选项很有用soap_version

$options = array( 
    'soap_version'=>SOAP_1_2, 
    'exceptions'=>false, 
    'trace'=>1, 
    'cache_wsdl'=>WSDL_CACHE_NONE 
);

*使用 SOAP 扩展调试的缺点是证书错误发生在实际请求之前。因此,当出现某种连接故障时,无法使用 getLastRequest() 或 getLastResponse()。

  1. 使用 Xdebug

调试 SoapClient 的另一个有趣选项是为 Xdebug 和您最喜欢的 IDE 设置调试会话 cookie

$client = new SoapClient(
    'http://example.loc/index.php/api/v2_soap/?wsdl'
);
$client->__setCookie('XDEBUG_SESSION', 'NETBEANS');
  1. 使用专门的 SOAP 跟踪器和调试器

专门的 SOAP 跟踪和调试应用程序也非常有用:除了像SoapUI这样的常见嫌疑人之外,还有像这里描述的 Charles 这样的中间跟踪代理。这种方法的缺点是添加了更多的层,因此可能会引入新的问题,例如握手问题。

还有一些物有所值的商业 SOAP 调试器,如XML Spy SOAP 调试器SOAPSonar ,它们执行验证和调用。无论如何,SoapUI 始终是一个很好的伴侣。

如果您怀疑网络协议级别存在问题,请尝试使用Wireshark,这是一种适用于 Unix 和 Windows 的网络协议分析器。

日志,日志,日志

基本错误信息也可以在 PHP 日志和 Web 服务器日志中找到。确保您已打开完整的错误日志记录。

1个

我只是把它包起来以备不时之需:

$client = new \SoapClient("http://127.0.0.1/services/wsdl2",array('trace' => 1,));
try{
   $result = $client->__SoapCall('routeCase', $params);
}catch (\Exception $e){
   throw new \Exception("Soup Request Failed! Response:\n".$client->__getLastResponse());
}

你的答案


来自  https://stackoverflow.com/questions/14030228/how-to-dump-soapclient-request-for-debug



Asked 
Viewed 85k times
60

I need to debug some code which uses soap client. I found getLast* methods in php.net, but when I try to get last request for debug it returns NULL

<?php

    $client = new SoapClient("http://www.webservicex.net/ConverPower.asmx?WSDL");
    
    $response = $client->ChangePowerUnit(array(
        "PowerValue" => 100,
        "fromPowerUnit" => "horsepower",
        "toPowerUnit" => "megawatts"
    ));
    
    
    echo "====== REQUEST HEADERS =====" . PHP_EOL;
    var_dump($client->__getLastRequestHeaders());
    echo "========= REQUEST ==========" . PHP_EOL;
    var_dump($client->__getLastRequest());
    echo "========= RESPONSE =========" . PHP_EOL;
    var_dump($response);

?>

The result of code execution:

$php soap_test.php 

====== REQUEST HEADERS =====
NULL
========= REQUEST ==========
NULL
========= RESPONSE =========
object(stdClass)#2 (1) {
  ["ChangePowerUnitResult"]=>
  float(0.0746)
}

How to get the content of body and headers of the last SoapClient request?

3 Answers

59

These functions only works if the SoapClient object was created with the trace option set to TRUE.

Try:

$client = new SoapClient("http://www.webservicex.net/ConverPower.asmx?WSDL", array('trace' => 1));
  • 3
    Even though @xdazz is correct I highly recommend to also add "exceptions" => 0 to the parameters in the SoapClient method so you can view the call you're making even if you receive a erroneous response.  Feb 27, 2017 at 19:06 
34

Debug a SOAP request  正确答案

  1. Using a SOAP extension

The easiest and best* way to debug a SOAP request is indeed to create a SOAP extension that logs the raw SOAP request and the raw SOAP response from the Web service or Web service client using the following functions of the SoapClient class:

To make it work, you do have to create your SoapClient object with the trace option turned on, as mentioned by xdazz:

$client = new MySoapClient($wsdlUrl, array('trace' => 1));

and then run your SOAP calls wrapped in a try-catch block:

try{
   $result = $client->__SoapCall('routeCase', $params);
}catch (\Exception $e){
   throw new \Exception("Soup request failed! Response: ".$client->__getLastResponse());
}

When developing SOAP solutions in PHP it is also a good idea to clean the PHP tmp folder when your WSDL contract changes (see your tmp folder path in phpinfo()) to force the PHP SoapClient to download WSDL and XSD files again instead of using the cached files (until they expire).

Furthermore, it's useful to set options like exceptions and cache_wsdl and the soap_version version whilst developing:

$options = array( 
    'soap_version'=>SOAP_1_2, 
    'exceptions'=>false, 
    'trace'=>1, 
    'cache_wsdl'=>WSDL_CACHE_NONE 
);

*The downside of debugging using a SOAP extension is that certificate-errors happen before the actual request or something. So it's not possible to use getLastRequest() or getLastResponse() when there is a connection failure of some kind.

  1. Using Xdebug

Another interesting option to debug a SoapClient is setting a debug session cookie for Xdebug and your favorite IDE

$client = new SoapClient(
    'http://example.loc/index.php/api/v2_soap/?wsdl'
);
$client->__setCookie('XDEBUG_SESSION', 'NETBEANS');
  1. Using specialized SOAP Tracer & Debugger

Specialized SOAP Trace & Debug apps are very useful too: In addition to usual suspects like SoapUI, there are also intermediate tracing proxies like Charles as described here. The downside of this method is that more layers are added and therefore are likely to introduce new problems, e.g. handshake problems.

There are also some commercial SOAP Debuggers out that are worth the money, like the XML Spy SOAP Debugger or SOAPSonar which do validation and invocation. In any event, SoapUI is always a good companion.

If you suspect there is an issue on the network protocol level try Wireshark, a network protocol analyzer for Unix and Windows.

Logs, logs, logs

Basic error information can also be found in the PHP log and the web server log. Ensure you have turned on full error logging.

  • I've added this since this comes up so often and the only answer adds no context. 
    – wp78de
     Jun 14, 2018 at 0:25
  • 3
    When developing SOAP solutions in PHP it is also a good idea to clean the PHP tmp folder <- This fixed things for me when nothing else left any trace of logs anywhere. 
    – Mahn
     May 3, 2019 at 16:26
  • 1
    Thank you very much about the cache information, didn't know about that and it helped me alot!  May 15, 2019 at 19:01
1

I just wrap it up for action:

$client = new \SoapClient("http://127.0.0.1/services/wsdl2",array('trace' => 1,));
try{
   $result = $client->__SoapCall('routeCase', $params);
}catch (\Exception $e){
   throw new \Exception("Soup Request Failed! Response:\n".$client->__getLastResponse());
}

Your Answer


来自   https://stackoverflow.com/questions/14030228/how-to-dump-soapclient-request-for-debug




普通分类: