postedin/fxmlrpc

快速且小巧的XML/RPC客户端,具有各种HTTP客户端的桥梁

0.16.0 2022-12-01 06:40 UTC

README

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

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

此分支中的更改

  • 向Client实例添加第四个可选参数以禁用修剪响应。

升级到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业务选择三个包

  • PSR-7兼容的HTTP消息(请求/响应)实现
  • 创建HTTP消息的兼容HTTP消息工厂实现
  • PSR-7兼容的HTTP客户端

两个广泛的消息实现是zend-diactorosguzzle/psr7。这两个实现的消息工厂都可在php-http/message中找到。对于HTTP客户端,您可以选择例如php-http/guzzle6-adapterphp-http/guzzle5-adapterphp-http/curl-clientphp-http/buzz-adapter

示例

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兼容性
  • [改进] 修改解析器抛出故障异常而不是客户端(参见 #53,由 Piotr Olaszewski 贡献)
  • [特性] 在客户端添加 XML 验证。可配置但默认启用
  • [特性] 包含最后请求、响应和异常的 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 了解详情)
  • [特性] 新的 artax 桥接器(由 Markus Staab 贡献)
  • [特性] 新的 Guzzle 4 桥接器(由 Robin van der Vleuten 贡献)
  • [特性] 允许控制 HTTP 传输头
  • [特性] 允许控制传输内容类型和字符集(参见 #9)
  • [BC] 移除过时的 PeclHttpBridge
  • [BC] 要求 PHP 5.4
  • [BUG] 修复 XmlWriterSerializer 中的巨大问题(参见 #4 了解详情)
  • [特性] 多调用特殊 API
  • [特性] 支持所有 Java XML/RPC 扩展
  • [BC] fXmlRpc\AbstractDecoratorfXmlRpc\ClientInterface 现在包括 prepend 和 append 参数的方法
  • [BC] fXmlRpc\Client 被标记为 final。属性被标记为 private。通过装饰器进行扩展。
  • [BC]fXmlRpc\Value\Base64 的已弃用构造函数标记为 private。此外,值对象现在是 final 的
  • [TESTING] 针对 Java XML/RPC 和 Python XML/RPC 的集成测试套件
  • [BUG] 修复隐式字符串类型处理问题(其中字符串不是值的孩子)
  • [改进] 改善异常处理
  • [BC] 改变命名方案为驼峰式
  • [BUG] 修复各种数组/结构边缘情况
  • [改进] 序列化和解析器的内存和性能的小幅改进
  • [BC] 弃用 fXmlRpc\Value\Base64 的构造函数,并引入 ::serialize()::deserialize()
  • [特性] 添加 fXmlRpc\Client::prependParams()fXmlRpc\Client::appendParams() 来设置默认参数。这有助于例如您需要为每次调用添加授权信息的情况
  • [特性] 时间日志记录器现在支持基于阈值的日志记录,以简化控制服务器响应的特定时间
  • [TESTING] Travis 现在运行针对支持的 HTTP 客户端和日志组件的各个版本的测试套件。

它真的有多快?

IO 性能从用户空间的角度来看是无法达到的,但解析和序列化速度才是关键。我们如何从 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));

Prepend 和 append 参数

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

使用便捷的 Proxy 对象

<?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'
    )
);