如何转储 SoapClient 请求以进行调试?

2021-12-24 00:00:00 php soap

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

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);

?>

代码执行结果:

$php soap_test.php 

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

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

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

推荐答案

调试 SOAP 请求

  1. 使用 SOAP 扩展

调试 SOAP 请求的最简单和最好的* 方法确实是创建一个 SOAP 扩展,它使用 SoapClient 类:

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:

  • SoapClient::__getLastRequestHeaders
  • SoapClient::__getLastRequest
  • SoapClient::__getLastResponseHeaders
  • SoapClient::__getLastResponse

要使其工作,您必须在启用跟踪选项的情况下创建 SoapClient 对象,如 xdazz 所述:

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));

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

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());
}

在用 PHP 开发 SOAP 解决方案时,当您的 WSDL 合同更改时清理 PHP tmp 文件夹也是一个好主意(请参阅 phpinfo() 中的 tmp 文件夹路径)) 强制 PHP SoapClient 再次下载 WSDL 和 XSD 文件,而不是使用缓存文件(直到它们过期).

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).

此外,在开发时设置exceptionscache_wsdlsoap_version 版本等选项很有用:

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 
);

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

  1. 使用 Xdebug

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

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. 使用专门的 SOAP Tracer &调试器

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

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.

还有一些值得花钱的商业 SOAP 调试器,例如 XML SpySOAP Debugger 或 SOAPSonar 进行验证和调用.无论如何,SoapUI 永远是一个好伙伴.

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.

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

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

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

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

相关文章