如何调试 SOAP 调用?
How to debug a SOAP call?
我正在为 SOAP API 编写集成测试(下面的代码示例)。
现在我遇到了一个错误,想调试我的服务器端代码(在 PhpStorm 中)。但是调试器只考虑测试中的断点而忽略服务器端代码。
OK,我大概明白了为什么:$soapClient->doSomething(...);
的调用开始了一个新的HTTP请求。 如何调试这个 "sub-request"(从 PhpUnit 的角度来看)?
集成测试代码:
class UserIntegrationTest extends TestCaseBase
{
const URL = "http://my-server.loc/soapapi/user/wsdl";
public static $classMap = [];
/** @var SoapClient */
private $soapClient;
/** @var ConfigurationServiceInterface */
private $config;
public function setUp()
{
parent::setUp();
$options = [
'exceptions' => true,
'login' => 'foo',
'password' => 'pwd',
'encoding' => 'utf-8',
// 'proxy_host' => '192.168.2.96',
// 'proxy_port' => '8080',
'classmap' => [],
'connection_timeout' => 5,
];
$this->soapClient = new SoapClient(self::URL, $options);
}
/**
* @test
* @group integration
*/
public function testDoSomething()
{
$options = array(
'exceptions' => true,
'login' => 'foo',
'password' => 'pwd',
'encoding' => 'utf-8',
// 'proxy_host' => '192.168.2.96',
// 'proxy_port' => '8080',
'classmap' => [],
'connection_timeout' => 5,
);
$soapClient = new SoapClient(self::URL, $options);
$message = new MyMessage();
$message->x = 1;
$message->y = 2;
$result = $soapClient->doSomething($message);
}
protected function getDataSet()
{
return new ArrayDataSet([
'users' => [
[
'id' => 1,
'username' => 'foo',
'password' => '...',
],
],
...
]);
}
}
解决方法是在SOAP客户端调用的URI后面追加?XDEBUG_SESSION_START=ECLIPSE_DBGP
。所以在 WSDL
的 port
段中
<port name="UserPort" binding="tns:UserBinding">
<soap:address location="http://my-server.loc/soapapi/user"/>
</port>
位置需要通过 Xdebug 查询扩展,如下所示:
http://my-server.loc/soapapi/user?XDEBUG_SESSION_START=ECLIPSE_DBGP
当然,高效的 WSDL 不应该包含这样的 location
。但是通常会生成 WSDL(例如通过 Zend\Soap\AutoDiscover
)并且 URI 可以很容易地动态配置。
您可以通过在客户端应用程序中设置 XDEBUG_SESSION
cookie 来做到这一点。
我认为这是比 更好的选择,因为它不需要更改服务器端代码 (WSDL)。
例如,根据 OP 的代码示例使用 PHP SoapClient
$soapClient = new SoapClient(self::URL, $options);
$soapClient->__setCookie('XDEBUG_SESSION', 'PHPSTORM');
然后在 PhpStorm 中,开始侦听 PHP 调试连接 和 运行 您的测试脚本。
我正在为 SOAP API 编写集成测试(下面的代码示例)。
现在我遇到了一个错误,想调试我的服务器端代码(在 PhpStorm 中)。但是调试器只考虑测试中的断点而忽略服务器端代码。
OK,我大概明白了为什么:$soapClient->doSomething(...);
的调用开始了一个新的HTTP请求。 如何调试这个 "sub-request"(从 PhpUnit 的角度来看)?
集成测试代码:
class UserIntegrationTest extends TestCaseBase
{
const URL = "http://my-server.loc/soapapi/user/wsdl";
public static $classMap = [];
/** @var SoapClient */
private $soapClient;
/** @var ConfigurationServiceInterface */
private $config;
public function setUp()
{
parent::setUp();
$options = [
'exceptions' => true,
'login' => 'foo',
'password' => 'pwd',
'encoding' => 'utf-8',
// 'proxy_host' => '192.168.2.96',
// 'proxy_port' => '8080',
'classmap' => [],
'connection_timeout' => 5,
];
$this->soapClient = new SoapClient(self::URL, $options);
}
/**
* @test
* @group integration
*/
public function testDoSomething()
{
$options = array(
'exceptions' => true,
'login' => 'foo',
'password' => 'pwd',
'encoding' => 'utf-8',
// 'proxy_host' => '192.168.2.96',
// 'proxy_port' => '8080',
'classmap' => [],
'connection_timeout' => 5,
);
$soapClient = new SoapClient(self::URL, $options);
$message = new MyMessage();
$message->x = 1;
$message->y = 2;
$result = $soapClient->doSomething($message);
}
protected function getDataSet()
{
return new ArrayDataSet([
'users' => [
[
'id' => 1,
'username' => 'foo',
'password' => '...',
],
],
...
]);
}
}
解决方法是在SOAP客户端调用的URI后面追加?XDEBUG_SESSION_START=ECLIPSE_DBGP
。所以在 WSDL
port
段中
<port name="UserPort" binding="tns:UserBinding">
<soap:address location="http://my-server.loc/soapapi/user"/>
</port>
位置需要通过 Xdebug 查询扩展,如下所示:
http://my-server.loc/soapapi/user?XDEBUG_SESSION_START=ECLIPSE_DBGP
当然,高效的 WSDL 不应该包含这样的 location
。但是通常会生成 WSDL(例如通过 Zend\Soap\AutoDiscover
)并且 URI 可以很容易地动态配置。
您可以通过在客户端应用程序中设置 XDEBUG_SESSION
cookie 来做到这一点。
我认为这是比
例如,根据 OP 的代码示例使用 PHP SoapClient
$soapClient = new SoapClient(self::URL, $options);
$soapClient->__setCookie('XDEBUG_SESSION', 'PHPSTORM');
然后在 PhpStorm 中,开始侦听 PHP 调试连接 和 运行 您的测试脚本。