如何转储SoapClient请求以便调试


How to dump SoapClient request for debug?

我需要调试一些使用soap客户端的代码。我发现getLast*方法在php.net,但当我试图得到最后的请求调试它返回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和header的内容?

这些函数只有当SoapClient对象被创建并将跟踪选项设置为TRUE时才有效。

试题:

$client = new SoapClient("http://www.webservicex.net/ConverPower.asmx?WSDL", array('trace' => 1));

调试SOAP请求

  1. 使用SOAP扩展

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

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

要使其工作,您必须创建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文件夹也是一个好主意(参见phpinfo()tmp文件夹路径),以强制PHP SoapClient再次下载WSDL和XSD文件,而不是使用缓存文件(直到它们过期)。

此外,在开发时设置exceptionscache_wsdl以及soap_version版本等选项是有用的:

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

*使用SOAP扩展调试的缺点是证书错误发生在实际请求或其他事情之前。因此,当存在某种类型的连接失败时,不可能使用getLastRequest()或getLastResponse()。

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

    $client = new SoapClient(
        'http://example.loc/index.php/api/v2_soap/?wsdl'
    );
    $client->__setCookie('XDEBUG_SESSION', 'NETBEANS');
    
  • 使用专用SOAP跟踪器&调试器
  • 专用SOAP跟踪&调试应用程序也非常有用:除了常见的SoapUI之外,还有中间跟踪代理,如本文所述的Charles。这种方法的缺点是增加了更多的层,因此可能会引入新的问题,例如握手问题。

    也有一些商业SOAP调试器是物有所值的,比如XML Spy SOAP调试器或SOAPSonar,它们可以进行验证和调用。在任何情况下,SoapUI都是一个很好的伙伴。

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

    日志、日志、日志

    基本错误信息也可以在PHP日志和web服务器日志中找到。

    我只是把它包起来。

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