paxport / soap-react
基于 ReactPHP 的简单、异步 SOAP Web 服务客户端库
Requires
- php: >=5.3
- ext-soap: *
- clue/buzz-react: ^2.5
- react/event-loop: ^1.0 || ^0.5 || ^0.4 || ^0.3
- react/promise: ^2.1 || ^1.2
Requires (Dev)
- clue/block-react: ^1.0
- phpunit/phpunit: ^6.4 || ^5.7 || ^4.8.35
This package is auto-updated.
Last update: 2024-09-17 17:05:47 UTC
README
简单、异步 SOAP Web 服务客户端库,基于 ReactPHP 构建。
最值得注意的是,SOAP 通常用于分布式系统中调用 远程过程调用 (RPCs)。内部,SOAP 消息被编码为 XML 并通常通过 HTTP POST 请求发送。就大部分而言,SOAP(最初称为 简单对象访问协议)是过去的一种协议,实际上并非真正简单。它仍然被许多(通常是 遗留)系统使用。该项目提供了一个简单的 API 来调用远程 Web 服务的异步 RPCs。
- 异步执行函数 - 并行向远程 Web 服务发送任意数量的函数(RPCs),并在结果到来时立即处理其响应。基于 Promise 的设计提供了与边界外响应交互的合理接口。
- 异步处理 WSDL - WSDL(Web 服务描述语言)文件将在后台下载和处理。
- 事件驱动核心 - 内部,所有内容都使用事件处理程序来响应传入的事件,例如传入的 RPC 结果。
- 轻量级、SOLID 设计 - 提供了一个足够好的抽象层,不会妨碍你,而是在测试组件的基础上构建,而不是重新发明轮子。
- 良好的测试覆盖率 - 附带自动化测试套件,并定期针对实际野外的 Web 服务进行测试。
目录
快速入门示例
安装后,您可以使用以下代码通过 SOAP 查询示例 Web 服务
$loop = React\EventLoop\Factory::create(); $browser = new Browser($loop); $wsdl = 'http://example.com/demo.wsdl'; $browser->get($wsdl)->then(function (ResponseInterface $response) use ($browser) { $client = new Client($browser, (string)$response->getBody()); $api = new Proxy($client); $api->getBank(array('blz' => '12070000'))->then(function ($result) { var_dump('Result', $result); }); }); $loop->run();
另请参阅 示例。
使用方法
客户端
Client
类负责与远程 SOAP Web 服务服务器进行通信。
它需要一个绑定到主 EventLoop
的 Browser
对象来处理异步请求、WSDL 文件内容和可选的 SOAP 选项数组
$loop = React\EventLoop\Factory::create(); $browser = new Clue\React\Buzz\Browser($loop); $wsdl = '<?xml …'; $options = array(); $client = new Client($browser, $wsdl, $options);
如果您需要自定义连接器设置(DNS 解析、TLS 参数、超时、代理服务器等),则可以显式传递一个自定义的 ConnectorInterface
实例到 Browser
实例
$connector = new \React\Socket\Connector($loop, array( 'dns' => '127.0.0.1', 'tcp' => array( 'bindto' => '192.168.10.1:0' ), 'tls' => array( 'verify_peer' => false, 'verify_peer_name' => false ) )); $browser = new Browser($loop, $connector); $client = new Client($browser, $wsdl);
Client
的工作方式与 PHP 的 SoapClient
(它底层使用)相似,但让您负责加载 WSDL 文件。这允许您使用本地 WSDL 文件、缓存中的 WSDL 文件或最常见的形式,通过 Browser
从 URL 下载 WSDL 文件内容
$browser = new Browser($loop); $browser->get($url)->then( function (ResponseInterface $response) use ($browser) { // WSDL file is ready, create client $client = new Client($browser, (string)$response->getBody()); // do something… }, function (Exception $e) { // an error occured while trying to download the WSDL } );
Client
构造函数将给定的 WSDL 文件内容加载到内存中,并解析其定义。如果给定的 WSDL 文件无效且无法解析,这将抛出 SoapFault
try { $client = new Client($browser, $wsdl); } catch (SoapFault $e) { echo 'Error: ' . $e->getMessage() . PHP_EOL; }
请注意,如果您已加载
ext-xdebug
,则可能会因为致命错误而停止,而不是抛出SoapFault
。不建议在生产环境中使用此扩展,因此这应该只会影响测试环境。
Client
构造函数接受一个选项数组。所有提供的选项都将传递给底层的SoapClient
。但是,并非所有选项都适用于此异步实现,因此可能不会产生预期效果。有关更多详细信息,请参阅SoapClient
文档:SoapClient。
如果在WSDL模式下工作,则$options
参数是可选的。如果在非WSDL模式下工作,则必须将WSDL参数设置为null
,并且选项参数必须包含location
和uri
选项,其中location
是要发送请求的SOAP服务器URL,而uri
是SOAP服务的目标命名空间。
$client = new Client($browser, null, array( 'location' => 'http://example.com', 'uri' => 'http://ping.example.com', ));
类似地,如果在WSDL模式下工作,可以使用location
选项显式覆盖要发送请求的SOAP服务器的URL。
$client = new Client($browser, $wsdl, array( 'location' => 'http://example.com' ));
可以使用soap_version
选项将默认的SOAP 1.1更改为使用SOAP 1.2。
$client = new Client($browser, $wsdl, array( 'soap_version' => SOAP_1_2 ));
可以使用classmap
选项将某些WSDL类型映射到PHP类,如下所示:
$client = new Client($browser, $wsdl, array( 'classmap' => array( 'getBankResponseType' => BankResponse::class ) ));
proxy_host
选项(及其家族)不受此库支持。作为替代,您可以配置给定的$browser
实例使用HTTP代理服务器。如果您发现此处缺少或不受支持的其他选项,则非常欢迎提交PR!
Client
的所有公共方法都被视为高级使用。如果您想调用RPC函数,请参阅下文的Proxy
类。
soapCall()
可以使用soapCall(string $method, mixed[] $arguments): PromiseInterface<mixed, Exception>
方法将给定函数排队通过SOAP发送,并等待来自远程Web服务的响应。
// advanced usage, see Proxy for recommended alternative $promise = $client->soapCall('ping', array('hello', 42));
注意:这被视为高级使用,您可能想考虑使用Proxy
。
$proxy = new Proxy($client); $promise = $proxy->ping('hello', 42);
getFunctions()
可以使用getFunctions(): string[]|null
方法返回在WSDL中定义的函数数组。
它返回PHP的SoapClient::__getFunctions()
的等效功能。在非WSDL模式下,此方法返回null
。
getTypes()
可以使用getTypes(): string[]|null
方法返回在WSDL中定义的类型数组。
它返回PHP的SoapClient::__getTypes()
的等效功能。在非WSDL模式下,此方法返回null
。
getLocation()
可以使用getLocation(string|int $function): string
方法返回给定webservice $function
的位置(URI)。
请注意,这不要与WSDL文件位置混淆。WSDL文件可以包含任意数量的函数定义。所有这些函数使用相同的位置定义是非常常见的。然而,技术上每个函数都可以使用不同的位置。
$function
参数应是一个包含SOAP函数名的字符串。有关所有可用函数的列表,请参阅getFunctions()
。
assert('http://example.com/soap/service' === $client->getLocation('echo'));
为了便于访问,此函数还接受一个数字函数索引。然后它使用getFunctions()
内部获取给定索引的函数名。这在所有函数使用相同位置且访问第一个位置就足够的情况下特别有用。
assert('http://example.com/soap/service' === $client->getLocation(0));
当在Client
构造函数中设置location
选项(例如,在非WSDL模式下)或通过withLocation()
方法时,此方法返回给定位置的价值。
传递一个在WSDL文件中未定义的$function
将会抛出SoapFault
异常。
withLocation()
可以使用withLocation(string $location): self
方法返回一个所有函数更新位置(URI)的新Client
。
请注意,这不要与WSDL文件位置混淆。WSDL文件可以包含任意数量的函数定义。所有这些函数使用相同的位置定义是非常常见的。然而,技术上每个函数都可以使用不同的位置。
$client = $client->withLocation('http://example.com/soap'); assert('http://example.com/soap' === $client->getLocation('echo'));
作为此方法的替代方案,您还可以在Client
构造函数中设置location
选项(例如,在非WSDL模式下)。
代理
Proxy
类将现有的Client
实例包装起来,以简化调用SOAP函数。
$proxy = new Proxy($client);
请注意,这个类被命名为"Proxy",因为它会将所有方法调用通过底层的
Client::soapCall()
方法转发(代理)到实际的SOAP服务。这不同于使用代理服务器。有关如何使用HTTP代理服务器的更多详细信息,请参阅Client
文档。
函数
对Proxy
类的每次方法调用都将通过SOAP发送。
$proxy->myMethod($myArg1, $myArg2)->then(function ($response) { // result received });
请参阅您的WSDL及其相关文档,以获取关于哪些函数和参数受支持的详细信息。
承诺
发布SOAP函数是异步(非阻塞)的,因此您可以实际并行发送多个RPC请求。Web服务将针对每个请求返回一个返回值。顺序没有保证。发送请求使用基于Promise的接口,这使得在请求完成(即成功解析或因错误而被拒绝)时作出反应变得容易。
$proxy->demo()->then( function ($response) { // response received for demo function }, function (Exception $e) { // an error occured while executing the request } });
取消
返回的Promise是这样实现的,可以在它仍然挂起时取消。取消挂起的Promise会使用异常拒绝其值,并清理任何底层资源。
$promise = $proxy->demo(); $loop->addTimer(2.0, function () use ($promise) { $promise->cancel(); });
超时
此库使用非常高效的HTTP实现,因此大多数SOAP请求通常只需几毫秒即可完成。但是,当通过不可靠的网络(互联网)发送SOAP请求时,可能会有许多可能导致请求在一段时间后失败的问题。因此,超时由底层HTTP库处理,并且此库尊重PHP的default_socket_timeout
设置(默认60秒)作为发送出站SOAP请求和等待成功响应的超时。否则,将取消挂起的请求,并使用异常拒绝其值。
请注意,此超时值包括创建底层传输连接、发送SOAP请求、等待远程服务处理请求以及接收完整的SOAP响应。要传递自定义超时值,您可以按如下方式分配底层的timeout
选项。
$browser = new Browser($loop); $browser = $browser->withOptions(array( 'timeout' => 10.0 )); $client = new Client($browser, $wsdl); $proxy = new Proxy($client); $proxy->demo()->then(function ($response) { // response received within 10 seconds maximum var_dump($response); });
类似地,您可以使用负的超时值来不应用超时,或者使用null
值来恢复默认处理。请注意,底层连接可能仍然强制执行不同的超时值。有关更多详细信息,请参阅底层的timeout
选项。
安装
安装此库的推荐方法是通过Composer。您是Composer的新手吗?新用户?
此项目遵循SemVer。这将安装最新的受支持版本。
$ composer require clue/soap-react:^1.0
有关版本升级的详细信息,请参阅CHANGELOG。
本项目旨在在任何平台上运行,因此仅需要ext-soap
,并支持在从旧版PHP 5.3到当前的PHP 7+和HHVM上运行。强烈建议为本项目使用PHP 7+。
测试
要运行测试套件,您首先需要克隆此仓库,然后通过Composer安装所有依赖项(Composer)
$ composer install
要运行测试套件,请进入项目根目录并运行
$ php vendor/bin/phpunit
测试套件还包含一些依赖稳定网络连接的功能集成测试。如果您不想运行这些测试,可以像这样简单地跳过
$ php vendor/bin/phpunit --exclude-group internet
许可
本项目采用宽松的MIT许可协议发布。
你知道吗?我提供定制开发服务,并为发布赞助和贡献发布发票。请联系我(@clue)了解详情。