webit / soap-api
Web-IT SOAP API 工具
3.0.2
2023-04-13 05:51 UTC
Requires
- php: >=7.4
- ext-soap: *
- doctrine/collections: ^1.2|^2.0
Requires (Dev)
- behat/behat: ^3.0
- jms/serializer: ^2.0|^3.0
- mockery/mockery: ^1.5.1
- phpunit/phpunit: ^9.6.5
Suggests
- jms/serializer: To support normalization / hydration based on JMS Serializer. Minimum version: 1.0
README
此库提供了一套工具,以简化基于 SOAP 的 Web 服务的客户端/SDK 的构建。
安装
Composer:在 composer.json 中添加 webit/soap-api
{ "require": { "php": ">=5.4", "webit/soap-api": "~2.0" } }
测试
./vendor/bin/phpunit
示例
运行 Behat 测试
./vendor/bin/behat
然后在 features/ 下探索它们的实现
用法
构建您的第一个 SDK
库的核心是 SoapApiExecutor,它只有一个方法 executeSoapFunction($soapFunction, $input)。它将委托给底层的 \SoapClient。
让我们为 IP2Geo Web 服务(WSDL 可以在这里找到这里)提供 SDK
<?php namespace Webit\SoapApi\Features\Ip2Geo; use Webit\SoapApi\Executor\SoapApiExecutor; class Ip2GeoSimpleClient { /** @var SoapApiExecutor */ private $executor; /** * @param SoapApiExecutor $executor */ public function __construct(SoapApiExecutor $executor) { $this->executor = $executor; } /** * @param Ip $ip * @return GeoLocation */ public function getGeoLocation(Ip $ip) { $result = $this->executor->executeSoapFunction( 'ResolveIP', array( 'ipAddress' => $ip, 'licenseKey' => '' ) ); return $this->hydrateToGeoLocation($result); } /** * @param $result * @return null|GeoLocation */ private function hydrateToGeoLocation($result) { $result = isset($result->ResolveIPResult) ? $result->ResolveIPResult : null; if (! $result) { return null; } return new GeoLocation( $result->City, $result->StateProvince, $result->Country, $result->Organization, $result->Latitude, $result->Longitude, $result->AreaCode, $result->TimeZone, $result->HasDaylightSavings, $result->Certainty, $result->RegionName, $result->CountryCode ); } } // IP address wrapper class Ip { /** @var string */ private $ip; public function __construct($ip) { $this->ip = $ip; } public function __toString() { return (string) $this->ip; } }
要使用我们的客户端,我们需要配置 SoapApiExecutor,然后将其传递给 Ip2GeoSimpleClient 构造函数。
<?php use Webit\SoapApi\Executor\SoapApiExecutorBuilder; use Webit\SoapApi\SoapClient\SoapClientSimpleFactory; $builder = SoapApiExecutorBuilder::create(); $builder->setWsdl('http://ws.cdyne.com/ip2geo/ip2geo.asmx?WSDL'); $client = new \Webit\SoapApi\Features\Ip2Geo\Ip2GeoSimpleClient( $builder->build() ); $result = $client->getGeoLocation(new Ip('8.8.8.8')); // returns GeoLocation instance
输入规范化
让我们将我们的 Ip 转换为 SOAP 函数参数的过程进行抽象。
<?php namespace Webit\SoapApi\Features\Ip2Geo\Normaliser; use Webit\SoapApi\Features\Ip2Geo\Ip; use Webit\SoapApi\Input\Exception\NormalisationException; use Webit\SoapApi\Input\InputNormaliser; class ResolveIPNormaliser implements InputNormaliser { /** * @param string $soapFunction * @param mixed $arguments * @throws NormalisationException * @return array */ public function normaliseInput($soapFunction, $arguments) { if (! ($arguments instanceof Ip)) { throw new NormalisationException(__CLASS__ . ' requires arguments to be an instance of IP class.'); } return array( 'ipAddress' => (string) $arguments, 'licenseKey' => '' ); } }
然后 Ip2GeoInputNormalisingClient 将看起来像这样
<?php namespace Webit\SoapApi\Features\Ip2Geo; use Webit\SoapApi\Executor\SoapApiExecutor; class Ip2GeoInputNormalisingClient { /** @var SoapApiExecutor */ private $executor; public function __construct(SoapApiExecutor $executor) { $this->executor = $executor; } /** * @param Ip $ip * @return GeoLocation */ public function getGeoLocation(Ip $ip) { $result = $this->executor->executeSoapFunction('ResolveIP', $ip); return $this->hydrateToGeoLocation($result); } public function hydrateToGeoLocation($result) { // same as Ip2GeoSimpleClient } }
现在我们配置 SoapApiExecutor 使用 ResolveIPNornaliser 来处理给定的 SOAP 函数
<?php use Webit\SoapApi\Executor\SoapApiExecutorBuilder; use Webit\SoapApi\SoapClient\SoapClientSimpleFactory; $builder = SoapApiExecutorBuilder::create(); $builder->setWsdl('http://ws.cdyne.com/ip2geo/ip2geo.asmx?WSDL'); $builder->setInputNormaliser( new \Webit\SoapApi\Input\FrontInputNormaliser( array( 'ResolveIP' => new ResolveIPNormaliser() ) ) ); $client = new \Webit\SoapApi\Features\Ip2Geo\Ip2GeoInputNormalisingClient( $builder->build() ); $result = $client->getGeoLocation(new Ip('8.8.8.8')); // returns GeoLocation instance
结果注水
我们的客户端看起来不错,但仍然有一些不美观的 "注水" 部分。让我们也将其抽象化。
<?php namespace Webit\SoapApi\Features\Ip2Geo\Hydrator; use Webit\SoapApi\Features\Ip2Geo\GeoLocation; use Webit\SoapApi\Hydrator\Hydrator; class ResolveIPHydrator implements Hydrator { /** * @param \stdClass|array $result * @param string $soapFunction * @return mixed */ public function hydrateResult($result, $soapFunction) { $result = isset($result->ResolveIPResult) ? $result->ResolveIPResult : null; if (! $result) { return null; } return new GeoLocation( $result->City, $result->StateProvince, $result->Country, $result->Organization, $result->Latitude, $result->Longitude, $result->AreaCode, $result->TimeZone, $result->HasDaylightSavings, $result->Certainty, $result->RegionName, $result->CountryCode ); } }
然后 Ip2GeoResultHydratingClient 将看起来像这样
<?php namespace Webit\SoapApi\Features\Ip2Geo; use Webit\SoapApi\Executor\SoapApiExecutor; class Ip2GeoResultHydratingClient { /** @var SoapApiExecutor */ private $executor; public function __construct(SoapApiExecutor $executor) { $this->executor = $executor; } /** * @param Ip $ip * @return GeoLocation */ public function getGeoLocation(Ip $ip) { return $this->executor->executeSoapFunction('ResolveIP', $ip); } }
现在我们配置 SoapApiExecutor 使用 ResolveIPHydrator 和 ResolveIPNornaliser 来处理给定的 SOAP 函数
<?php use Webit\SoapApi\Executor\SoapApiExecutorBuilder; use Webit\SoapApi\SoapClient\SoapClientSimpleFactory; $builder = SoapApiExecutorBuilder::create(); $builder->setWsdl('http://ws.cdyne.com/ip2geo/ip2geo.asmx?WSDL'); $builder->setInputNormaliser( new \Webit\SoapApi\Input\FrontInputNormaliser( array( 'ResolveIP' => new ResolveIPNormaliser() ) ) ); $builder->setHydrator( new \Webit\SoapApi\Hydrator\FrontHydrator( array( 'ResolveIP' => new ResolveIPHydrator() ) ) ); $client = new \Webit\SoapApi\Features\Ip2Geo\Ip2GeoResultHydratingClient( $builder->build() ); $result = $client->getGeoLocation(new Ip('8.8.8.8')); // returns GeoLocation instance