webit/soap-api

Web-IT SOAP API 工具

3.0.2 2023-04-13 05:51 UTC

This package is auto-updated.

Last update: 2024-09-13 08:46:58 UTC


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 使用 ResolveIPHydratorResolveIPNornaliser 来处理给定的 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