morpholetto / soap
一个提供处理请求和响应的干净接口的SOAP客户端。
Requires
- php: ^7.3|^7.4|~8.0|~8.1|~8.2
- illuminate/support: ^8.16|^9.0|^10.0
Requires (Dev)
- ext-soap: *
- mockery/mockery: ^1.4
- orchestra/testbench: ^6.24|^7.0|^8.0
- pestphp/pest: ^1.11
- phpoption/phpoption: ^1.8.1
- phpunit/phpunit: ^9.5
- spatie/ray: ^1.17
This package is not auto-updated.
Last update: 2024-09-27 18:32:43 UTC
README
一个Laravel SOAP客户端,提供处理请求和响应的干净接口。
文档
需求
- PHP 7.4或更高版本
- Laravel 8.16或更高版本
安装
您可以通过composer安装此包
composer require ricorocks-digital-agency/soap
注意:从v1.5.0版本开始,Soap需要PHP ^7.4
使用Soap
可以通过提供的Facade访问Soap
use RicorocksDigitalAgency\Soap\Facades\Soap Soap::to()
特性/API
头部
您可以使用withHeaders
方法为每个将要传递给Soap客户端的SOAP请求设置头部。
Soap::to('...')->withHeaders(...$headers)->call('...');
每个头部都应该是一个Header
实例,它提供了一个流畅的接口来构建一个新的PHP Soap Header,可以按如下方式组合:
$header = Soap::header() ->name('Authentication') ->namespace('test.com') ->data([ 'user' => '...', 'password' => '...' ]) ->mustUnderstand() ->actor('foo.co.uk')
这也可以表示为:
$header = Soap::header('Authentication', 'test.com', [ 'user' => '...', 'password' => '...' ]) ->mustUnderstand() ->actor('foo.co.uk')
此外,还可以使用soap_header
辅助方法。
$header = soap_header('Authentication', 'test.com') ->data([ 'user' => '...', 'password' => '...' ])
头部的
data
可以是一个数组或一个SoapVar
,如SoapHeader
构造函数所示。
全局头部
Soap允许您设置应该包含在每个请求中的头部。
Soap::headers(...$headers)
同样,每个头部应该是一个Header
实例。
您可能还想在每次请求中都包含头部,但仅针对某些端点或操作。
// Only requests to this endpoint will include these headers Soap::headers(soap_header('Auth', 'test.com'))->for('https://api.example.com'); // Only requests to this endpoint and the method Customers will include these headers Soap::headers(soap_header('Brand', 'test.com'))->for('https://api.example.com', 'Customers');
这些调用通常放置在您的应用程序服务提供者的boot
方法中。
发送到
要访问的端点
Soap::to('github.com/api')
函数
检索端点提供的函数
Soap::to('github.com/api')->functions()
这是PHP SoapClient _getFunctions()
方法的包装器。
调用
调用端点的方法。
Soap::to('github.com/api')->call('merge')
该方法也可以作为魔术方法调用。
Soap::to('github.com/api')->merge()
参数
当然,调用方法接受参数。传递的参数可以是一个数组
Soap::to('github.com/api')->call('merge', ['branch' => 'staging', 'credentials' => ['password' => '...'])
节点
为了简化处理请求中的SOAP XML,Soap提供了一个方法来流畅地构建请求中的节点。
例如,假设以下节点需要在XML请求中。请注意,它没有主体。
<PullRequest branch="dev" target="main"> </PullRequest>
传递给底层php SoapClient
以构造此节点的数组如下:
'PullRequest' => [ '_' => '', 'branch' => 'dev', 'target' => 'main' ]
_
是必需的,用于将信息设置为不是主体,而是节点的属性。
但是,如果XML节点有主体,则不需要这样做。
<PullRequest branch="dev" target="main"> <Author>Ricorocks</Author> </PullRequest>
现在,数组如下:
'PullRequest' => [ 'Author' => 'Ricorocks', 'branch' => 'dev', 'target' => 'main' ]
因此,为了避免混淆,Soap::node()
将允许智能构建传递给SoapClient
的php array
。
想象一下我们正在访问information
方法来查看拉取请求的详细信息。
Soap::to('...') ->information('PullRequest' => soap_node(['branch' => 'dev', 'target' => 'main'])) 'PullRequest' => [ '_' => '', 'branch' => 'dev', 'target' => 'main' ] Soap::to('...') ->information('PullRequest' => soap_node(['branch' => 'dev', 'target' => 'main'])->body(['Author' => 'Ricorocks'])) 'PullRequest' => [ 'Author' => 'Ricorocks', 'branch' => 'dev', 'target' => 'main' ]
现在,只需通过向或从soap_node()
添加或删除主体,就可以智能地构建输出的数组。
可以使用Facade Soap::node()
或辅助方法soap_node()
来创建节点。
选项
您可以使用withOptions
方法为每个SOAP请求设置自定义选项,这些选项将被传递给Soap客户端。
Soap::to('...')->withOptions(['soap_version' => SOAP_1_2])->call('...');
有关更多详细信息,请参阅https://php.ac.cn/manual/en/soapclient.construct.php。
Soap还提供了一些方法,它们为最常用的选项添加了语法糖,如下所述。
追踪
SOAP 允许您轻松追踪与访问的 SOAP 终端的交互。
要追踪所有请求,请在您的 ServiceProvider
的注册方法中设置以下内容
Soap::trace()
现在,所有返回的 Response
对象都将附加一个 Trace
对象,可通过 $response->getTrace()
访问。这个对象有四个属性,是对 SoapClient
上相应方法的包装
xmlRequest
(__getLastRequest
)xmlResponse
(__getLastResponse
)requestHeaders
(__getLastRequestHeaders
)responseHeaders
(__getLastResponseHeaders
)
追踪也可以局部声明
Soap::to('...')->trace()->call('...')
现在,仅此 Response
将有一个有效的 Trace
。
追踪是空安全的。如果调用 $response->getTrace()
时没有设置 Trace
,将返回一个新的 Trace
。这个 Trace
的属性都将返回 null
。
认证
您可以使用 withBasicAuth
和 withDigestAuth
分别通过基本或摘要认证进行身份验证。
Soap::to('...')->withBasicAuth('username', 'password')->call('...'); Soap::to('...')->withDigestAuth('username', 'password')->call('...');
全局选项
有时,您可能希望在每个 SOAP 请求中都包含相同的选项集。您可以使用 Soap
外观的 options
方法来完成此操作
// Every request will include these options automatically Soap::options(['login' => 'foo', 'password' => 'bar']);
您可能还希望在每个请求中都包含选项,但仅针对特定的端点或操作
// Only requests to this endpoint will include these options Soap::options(['login' => 'foo', 'password' => 'bar'])->for('https://api.example.com'); // Only requests to this endpoint and the method Customers will include these options Soap::options(['login' => 'foo', 'password' => 'bar'])->for('https://api.example.com', 'Customers');
这些调用通常放置在您的应用程序服务提供者的boot
方法中。
钩子
钩子允许您在 Soap 发出请求之前和之后执行操作。这些钩子可以是局部的(针对每个请求),也可以是全局的(应用于每个请求)。
如果您希望在 beforeRequesting
钩子中更改 Request
对象,可以这样做。这些更改将反映在实际请求中。事实上,这就是 Soap 的 include
功能的工作方式。
局部
要创建一个局部钩子,将 beforeRequesting
或 afterRequesting
连接到一个 Request
对象
Soap::to('http://example.com') ->beforeRequesting(fn() => Log::info('Request going in!')) ->afterRequesting(fn() => Log::info('Request coming out!')) ->call('Action', []);
所有在请求之前的钩子将接收到请求作为参数,而在请求之后的钩子将接收到请求和响应作为参数。
全局
要创建一个全局钩子,使用 Soap::beforeRequesting
和 Soap::afterRequesting
方法。
Soap::beforeRequesting(fn() => Log::info('Request going in!')); Soap::afterRequesting(fn() => Log::info('Request coming out!'));
所有在请求之前的钩子将接收到请求作为参数,而在请求之后的钩子将接收到请求和响应作为参数。
模拟
Soap 包括对模拟端点和操作以及检查请求和响应的全面支持。
要模拟所有 SOAP 请求,请调用 Soap:fake()
。这将返回每个请求的空响应。您可能希望更具体一些,因此可以向 fake
方法传递一个键为数组端点,值为响应对象的数组
Soap::fake(['http://endpoint.com' => Response::new(['foo' => 'bar'])]);
在上面的示例中,任何发送到 http://endpoint.com
的 SOAP 请求都将被模拟,并将返回一个包含 ['foo' => 'bar']
体的 Response
对象。
如果您还想指定 SOAP 动作怎么办?很简单!只需在端点后添加 :{ActionName}
,如下所示
Soap::fake(['http://endpoint.com:Details' => Response::new(['foo' => 'bar'])]);
现在,只有针对 Details
操作的 SOAP 请求将被模拟。
您也可以使用 |
运算符指定多个操作
Soap::fake(['http://endpoint.com:Details|Information|Overview' => Response::new(['foo' => 'bar'])]);
现在,只有针对 Details
、Information
和 Overview
操作的 SOAP 请求将被模拟。
检查请求
如果您已调用 Soap::fake()
,Soap 将记录所有请求。然后您可以按需检查这些请求。
Soap::assertSentCount($count)
如果您只想断言发送了 n
个 SOAP 请求,您可以使用此方法,并将所需计数作为参数传递。
Soap::assertSent(callable $callback)
您可以更深入地测试是否确实发送了特定请求,并且它返回了预期的响应。您应将闭包传递到此方法中,该闭包接收 $request
和 $response
作为参数,并在它们符合您的期望时返回 true
。
Soap::assertNotSent(callable $callback)
这是 Soap::assertSent
的反义。您可以确保没有发出特定请求。同样,从闭包中返回 true
将导致它通过。
Soap::assertNothingSent()
如果您只想确保没有任何东西被发送出去,您可以调用这个方法。它做了它所说的。
配置
通过在您的服务提供者中的 boot()
方法调用 Soap
门面来配置 Soap。
包含
可以将参数设置为在所有请求中自动包含。这些可以是 数组
或 节点
Soap::include(['credentials' => soap_node(['user' => '...', 'password' => '...'])]);
您甚至可以在您的数组键上使用点语法来深入请求体。
Soap::include(['login.credentials' => soap_node(['user' => '...', 'password' => '...'])]);
通常,您可能想要针对特定的端点或操作。您可以通过链式调用 for
方法来实现。
// Only requests to https://api.example.com will include this data Soap::include(['credentials' => soap_node(['user' => '...', 'password' => '...'])])->for('https://api.example.com'); // Only requests to https://api.example.com calling the Customers method will include this data Soap::include(['credentials' => soap_node(['user' => '...', 'password' => '...'])])->for('https://api.example.com', 'Customers');
Ray支持
本包包含了对 Ray 的第一方支持,Ray 是 Spatie 的一款出色的调试工具!我们提供了一些方法,您可以立即开始调试。
显然,您需要在项目中安装 Ray 才能使此功能正常工作。
ray()->showSoapRequests()
这启用了 SOAP 包中的 Ray 支持。任何 SOAP 请求都将被记录在 Ray 应用中供您检查。
ray()->stopShowingSoapRequests()
这禁用了 SOAP 包中的 Ray 支持。如果之前已启用,请求将停止记录。
如果您想在测试中使用 Ray 集成,请记住与您的其他提供者一起注册
RayServiceProvider
。
变更日志
有关最近更改的更多信息,请参阅 变更日志。
贡献
有关详细信息,请参阅 贡献指南。
安全性
如果您发现任何与安全相关的问题,请通过电子邮件 hello@ricorocks.agency 而不是使用问题跟踪器来联系。
鸣谢
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件。