camcima/camcima-soap-client

该软件包最新版本(1.3.0)没有提供许可信息。

PHP SoapClient类的包装器

1.3.0 2019-02-04 17:17 UTC

This package is auto-updated.

Last update: 2024-09-07 05:08:38 UTC


README

概述

这是我对原生PHP SOAP客户端实现(\SoapClient)不足之处的改进尝试。

使用方法

实例化

<?php
$soapClient = new \Camcima\Soap\Client($wsdl, $options, $sslVerifyPeer);

默认情况下,sslVerifyPeer的值为true,这意味着将验证SSL证书。如果WSDL文件托管在拥有无效SSL证书或自签名证书的服务器上,请将sslVerifyPeer设置为false

cURL选项

此包装器使用cURL发出HTTP请求。可以使用cURL选项自定义SOAP请求。

<?php
$curlOptions = array(
    CURLOPT_CRLF => true,
    CURLOPT_SSL_VERIFYPEER => true
);
$soapClient = new \Camcima\Soap\Client($wsdl, $options);
$soapClient->setCurlOptions($curlOptions);

然而,有一些cURL选项不能被覆盖,因为它们对于包装器是必需的

<?php
// Mandatory cURL Options
CURLOPT_POST => true
CURLOPT_HEADER => true

要获取当前使用的cURL选项

<?php
$curlOptions = $soapClient->getCurlOptions();

使用代理

如果您需要代理请求(例如调试),可以使用此方法设置代理主机、端口和类型

<?php
$soapClient->useProxy('proxy.local', 8080, CURLPROXY_SOCKS5);

此方法的默认主机、端口和类型为localhost8888CURLPROXY_HTTP,这是Fiddler Web调试代理的默认绑定(http://fiddler2.com/)。

代理认证

如果您的代理需要认证,您可以使用此方法设置代理用户名和密码

<?php
$soapClient->setProxyAuth('proxy_user', 'proxy_password');

认证

为了使用HTTP认证,请使用SoapClient原始的loginpassword选项。cURL客户端将从中获取这些信息。

<?php
$soapClient = new Client($wsdlUrl, ['login' => 'joelogin', 'password' => 'joepassword']);

用户代理

可以自定义客户端使用的用户代理

<?php
$soapClient->setUserAgent('MyUserAgent/1.0');

小写首字符

在我开发与基于.NET的web服务的集成时,我注意到SOAP请求有效负载根元素的名称总是首字母小写。其他内部元素的首字母总是大写,这是类名常见的做法。我不知道这是否是.NET web服务的规范,但无论如何,我已经实现了一个处理此问题的选项。

<?php
$soapClient->setLowerCaseFirst(true);

此设置的默认值为false

保留空属性

当您将对象作为SOAP参数传递时,它的某些属性可能是null(或未设置)。默认情况下,此客户端在发送请求时会省略这些null属性。如果您需要发送所有属性,即使为null,请使用此选项

<?php
$soapClient->setKeepNullProperties(true);

此设置的默认值为true

调试

为了调试请求和响应,您需要将调试模式设置为true,并设置调试文件名和路径。

<?php
$soapClient->setDebug(true);
$soapClient->setDebugLogFilePath(__DIR__ . '/../../../../log/debug.log');

最后请求通信日志

您可以从最后请求中获取HTTP通信日志(请求和响应)。

<?php
$soapClient->getCommunicationLog();

结果类映射

PHP原生SOAP客户端实现具有将SOAP返回映射到本地类的能力。不幸的是,它并没有按预期工作。因此,我实现了我自己的结果类映射版本。

它有两种不同的风格

使用类映射

您必须构建一个关联数组,其中结果元素作为键,相应的本地类作为值。

<?php
$soapClient = new Client($wsdlUrl);
$soapResult = $soapClient->GetCityForecastByZIP($getForecastByZip);
$resultClassmap = array(
    'GetCityForecastByZIPResult' => '\Camcima\Soap\Test\Fixtures\GetCityForecastByZIPResult',
    'ForecastResult' => '\Camcima\Soap\Test\Fixtures\ForecastResult',
    'array|Forecast' => '\Camcima\Soap\Test\Fixtures\ForecastEntry',
    'Temperatures' => '\Camcima\Soap\Test\Fixtures\Temperatures',
    'ProbabilityOfPrecipiation' => '\Camcima\Soap\Test\Fixtures\ProbabilityOfPrecipiation'
);
$getCityForecastByZIPResult = $soapClient->mapSoapResult($soapResult, 'GetCityForecastByZIPResult', $resultClassmap, true);

原生SOAP客户端将所有对象返回为标准类(StdClass),而我的映射函数将它们“转换为”映射的本地类。此函数基于包含标准类对象的属性名称。这在大多数情况下表现良好,但当存在对象数组时,需要特殊的配置

<?php
$mapping = array(
    'array|Forecast' => '\Camcima\Soap\Test\Fixtures'
);

该属性名称是数组的标记,用于映射。您还需要在元素名称前加上array前缀,并使用竖线(|)分隔它们。

如果我们得到简单类型的数组,如

<xsd:element name="ForecastIcons" type="tns:ArrayOfString"/>

我们需要映射到数组,因此它将从item属性中提取数据(不需要在SoapClient中启用SOAP_SINGLE_ELEMENT_ARRAYS功能)

<?php
$mapping = array(
    'ForecastIcons' => 'array'
);

使用命名空间

如果所有结果类都位于同一个命名空间中,就没有必要单独映射它们。您可以告诉映射器类所在的命名空间,它将自动通过将SOAP结果名称与本地类名称匹配来确定映射。

<?php
$resultClassNamespace = '\MyProject\SOAP\Result\\';

跳过根对象

有时,web服务将返回一个只有一个属性的对象,因此为这个属性创建包装对象没有太大意义。在这种情况下,您可以在mapSoapResult方法中使用skipRootObject参数来跳过根对象,并返回内部属性。

<?php

public function mapSoapResult($soapResult, $rootClassName, array $resultClassMap = array(), $resultClassNamespace = '', $skipRootObject = false);

改进

我计划根据我的需求添加新功能。如果您需要特殊功能,您有两个选择

  • 自行开发并发送pull请求给我。我保证会尽快合并。

  • 创建一个issue并等待我开发。这可能会花费一些时间,因为我通常很忙。