lstrojny/fxmlrpc

快速且小巧的XML/RPC客户端,支持各种HTTP客户端的桥接

0.22.0 2021-06-21 09:30 UTC

README

Gitter Build Status Average time to resolve an issue Percentage of issues still open

  • 方便、面向对象的API(类似于Zend Framework中的XML/RPC客户端)
  • 非常快速的序列化和解析涉及到的XML负载
  • 坚持使用你已使用的HTTP客户端,由HTTPlug提供
  • 在MIT许可的条款下发布
  • 支持现代标准:通过composer轻松安装,完全兼容PSR-0、PSR-1和PSR-2
  • 不懈地进行单元和集成测试
  • 实现了所有已知的XML/RPC扩展

升级到0.23.x

现在我们使用PSR-7兼容的RequestFactoryInterface代替了php-http/message-factory。您需要更改自定义HTTP客户端实现,并将Psr\Http\Message\RequestFactoryInterface实现、Psr\Http\Message\StreamFactoryInterfaceHttp\Client\HttpClient传递给HttpAdapterTransport。下面有详细说明。

安装

要安装fxmlrpc,请运行此命令

composer require lstrojny/fxmlrpc

安装依赖项

您必须为HTTP业务选择三个包

示例

composer require php-http/message php-http/guzzle7-adapter

实例化HttpAdapterTransport

使用Guzzle6的实例化示例

$httpClient = new GuzzleHttp\Client();
$httpClient->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(
        new \Http\Message\MessageFactory\DiactorosMessageFactory(),
        new \Http\Message\StreamFactory\DiactorosStreamFactory(),
        new \Http\Adapter\Guzzle7\Client($httpClient)
    )
);

升级到0.12.x

我们现在使用PSR-7兼容的php-http/httplug代替了egeloen/http-adapter。您需要更改自定义HTTP客户端实现,并将Http\Message\MessageFactory实现和Http\Client\HttpClient传递给HttpAdapterTransport。下面有详细说明。

安装

要安装fxmlrpc,请运行此命令

composer require lstrojny/fxmlrpc

安装依赖项

您必须为HTTP业务选择三个包

示例

composer require zendframework/zend-diactoros php-http/message php-http/guzzle6-adapter

实例化HttpAdapterTransport

使用Guzzle6的实例化示例

$httpClient = new GuzzleHttp\Client();
$httpClient->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(
        new \Http\Message\MessageFactory\DiactorosMessageFactory(),
        new \Http\Adapter\Guzzle6\Client($httpClient)
    )
);

升级到0.11.x

我们更改了ParserInterface::parse()方法接口,现在不需要传递第二个参数($isFault),解析器在服务器响应中遇到故障消息时应该抛出FaultException异常。

升级到0.10.x

0.10.x 版本带来了几个重大更改:我们曾自行提供与各种 HTTP 客户端互操作性的桥梁,但已将此责任移交给名为 Ivory HTTP Adapter 的第三方库。重要提示:该库默认不安装,因为您可以选择仅使用带有您自己的 fXmlRpc\Transport\TransportInterface 实现的 fxmlrpc。要安装库 – 这可能是您最想要做的 – 请将以下行添加到您的 composer.json

"egeloen/http-adapter": "~0.6"

… 然后,运行 composer update

实例化 HTTP 传输

为了使用新的适配器,您需要更改实例化 fXmlRpc 及其传输的方式。这是之前实例化自定义传输的方式

$httpClient = new GuzzleHttp\Client();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\Guzzle4Bridge($httpClient)
);

这是您现在要这样做的方式

$httpClient = new GuzzleHttp\Client();
$httpClient->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(new Ivory\HttpAdapter\GuzzleHttpHttpAdapter($httpClient))
);

最新改进

  • [BC] 支持 PSR-7
  • [IMPROVEMENT] PHP7 兼容性
  • [IMPROVEMENT] 重构解析器,抛出异常而不是客户端(见 #53,由 Piotr Olaszewski 贡献)
  • [FEATURE] 在客户端添加 XML 验证。可配置但默认启用
  • [FEATURE] 传输装饰器,包含最后请求、响应和异常的 XML(见 #47,由 Piotr Olaszewski 贡献)
  • [BC] PSR-4 自动加载(见 #29)
  • [BC]fXmlRpc\Multicall 重命名为 fXmlRpc\MulticallBuilder
  • [BC] 显著缩小 ClientInterface 的接口(见 #24 了解详细信息)
  • [BC] 将内置传输替换为 Ivory HTTP Adapter。不再支持 PECL HTTP。由 Márk Sági-Kazár 贡献
  • [BUG] 修复与 XmlWriterSerializer 的序列化问题(见 #19 了解详细信息)
  • [FEATURE] 新的 artax 桥(由 Markus Staab 贡献)
  • [FEATURE] 新的 Guzzle 4 桥(由 Robin van der Vleuten 贡献)
  • [FEATURE] 允许控制 HTTP 传输头
  • [FEATURE] 允许控制传输的内容类型和字符集(见 #9)
  • [BC] 删除过时的 PeclHttpBridge
  • [BC] 需要 PHP 5.4
  • [BUG] 修复 XmlWriterSerializer 的重大问题(见 #4 了解详细信息)
  • [FEATURE] 多调用特殊 API
  • [FEATURE] 支持 Java XML/RPC 的所有扩展
  • [BC] fXmlRpc\AbstractDecoratorfXmlRpc\ClientInterface 现在包含用于前缀和后缀参数的方法
  • [BC] fXmlRpc\Client 被标记为最终。属性被标记为私有。通过装饰器扩展。
  • [BC]fXmlRpc\Value\Base64 的构造函数标记为私有。此外,值对象现在是最终的
  • [TESTING] 针对 Java XML/RPC 和 Python XML/RPC 的集成测试套件
  • [BUG] 修复隐式字符串类型处理问题(其中字符串不是值的子节点)
  • [IMPROVEMENT] 改进异常处理
  • [BC] 更改命名方案为 StudlyCaps
  • [BUG] 修复各种数组/结构边缘情况
  • [IMPROVEMENT] 序列化和解析器的内存和性能改进
  • [BC] 废弃 fXmlRpc\Value\Base64 的构造函数,并引入了 ::serialize()::deserialize()
  • [FEATURE] 添加 fXmlRpc\Client::prependParams()fXmlRpc\Client::appendParams() 来设置默认参数。这有助于例如您需要为每个调用添加授权信息的情况
  • [特性] 时间记录器现在支持基于阈值的记录,以简化对服务器响应特定时间的控制
  • [测试] Travis现在运行测试套件,针对支持的HTTP客户端和记录组件的各个版本。

它实际上有多快?

从用户空间的角度来看,I/O性能难以达到,但解析和序列化速度才是关键。我们能够多快地将PHP数据结构生成XML有效载荷?我们能够多快地解析服务器的响应?fXmlRpc使用基于流的XML写入器/读取器来实现其性能,并对其进行了大量优化(读取丑化)。因此,用户空间版本仅比原生的C实现(ext/xmlrpc)慢约2倍。

解析器

Zend\XmlRpc\Value (ZF2): 249.02972793579 sec
Zend_XmlRpc_Value (ZF1): 253.88145494461 sec
fXmlRpc\Parser\XmlReaderParser: 36.274516105652 sec
fXmlRpc\Parser\NativeParser: 18.652323007584 sec

序列化器

Zend\XmlRpc\Request (ZF2): 52.004573106766 sec
Zend_XmlRpc_Request (ZF1): 65.042532920837 sec
fXmlRpc\Serializer\XmlWriterSerializer: 23.652673006058 sec
fXmlRpc\Serializer\NativeSerializer: 9.0790779590607 sec

用法

基本用法

<?php
$client = new fXmlRpc\Client('http://endpoint.com');
$client->call('remoteMethod', array('arg1', true));

使用原生(基于ext/xmlrpc的序列化器/解析器)(以获得更好的性能)

<?php
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    null,
    new fXmlRpc\Parser\NativeParser(),
    new fXmlRpc\Serializer\NativeSerializer()
);
$client->call('remoteMethod', array('arg1', true));

添加和附加参数

<?php
$client = new fXmlRpc\Client('http://endpoint.com');
$client->prependParams(array('username', 'password'));
$client->appendParams(array('appended'));
...

使用方便的代理对象

<?php
$proxy = new fXmlRpc\Proxy(new fXmlRpc\Client('http://endpoint.com'));
// Call system.echo
$proxy->system->echo('Hello World!');

跟踪请求和响应的XML

<?php
$transport = new fXmlRpc\Transport\HttpAdapterTransport(...);
$recorder = new Recorder($transport);
$client = new Client('http://foo.com', $recorder);
$client->call('TestMethod', ['param1', 2, ['param3' => true]]);

$lastRequest = $recorder->getLastRequest();
$lastResponse = $recorder->getLastResponse();

如果在传输层发生异常,您可以使用getLastException()获取它。

多调用请求的有用抽象

<?php
$result = $client->multicall()
    ->addCall('system.add', array(1, 2))
    ->addCall(
        'system.add',
        array(2, 3),
        function ($result) {
            echo "Result was: " . $result;
        },
        function($result) {
            echo "An error occured: " . var_export($result, true);
        }
    )
    ->onSuccess(function ($result) {echo "Success";}) // Success handler for each call
    ->onError(function ($result) {echo "Error";}) // Error handler for each call
    ->execute();

使用Ivory集成各种HTTP客户端

<?php
/** Buzz (https://github.com/kriswallsmith/Buzz) */
$browser = new Buzz\Browser();
$browser->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(new \Ivory\HttpAdapter\BuzzHttpAdapter($browser))
);

/** Zend Framework 1 (http://framework.zend.com/) */
$httpClient = new Zend_Http_Client();
$httpClient->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(new \Ivory\HttpAdapter\Zend1HttpAdapter($httpClient))
);

/** Zend Framework 2 (http://framework.zend.com/zf2) */
$httpClient = new Zend\Http\Client();
$httpClient->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(new \Ivory\HttpAdapter\Zend2HttpAdapter($httpClient))
);

/** Guzzle (http://guzzlephp.org/) */
$httpClient = new Guzzle\Http\Client();
$httpClient->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(new \Ivory\HttpAdapter\GuzzleAdapter($httpClient))
);

/** Guzzle 4+ (http://guzzlephp.org/) */
$httpClient = new GuzzleHttp\Client();
$httpClient->...();
$client = new fXmlRpc\Client(
    'http://endpoint.com',
    new fXmlRpc\Transport\HttpAdapterTransport(new \Ivory\HttpAdapter\GuzzleHttpHttpAdapter($httpClient))
);

定时XML/RPC请求以查找问题调用

fXmlRpc允许您定时XML/RPC请求,以找出哪些调用耗时。它提供了一个fXmlRpc\Timing\TimingDecorator,可以与实现fXmlRpc\Timing\TimerInterface的各种计时器一起使用。目前实现了Monolog、Zend Framework 1 Zend_Log和Zend Framework 2 Zend\Log的桥梁。

用法

<?php
$client = new fXmlRpc\Timing\TimingDecorator(
    new fXmlRpc\Client(...),
    new fXmlRpc\Timing\MonologTimerBridge(
        $monolog,
        Monolog\Logger::ALERT,
        'My custom log message template %F'
    )
);