camcima / camcima-soap-client
PHP SoapClient类的包装器
Requires
- php: >=5.3.0
- ext-libxml: *
- ext-soap: *
- lib-curl: *
Requires (Dev)
- phpunit/phpunit: ^5.2
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);
此方法的默认主机、端口和类型为localhost
、8888
和CURLPROXY_HTTP
,这是Fiddler Web调试代理的默认绑定(http://fiddler2.com/)。
代理认证
如果您的代理需要认证,您可以使用此方法设置代理用户名和密码
<?php $soapClient->setProxyAuth('proxy_user', 'proxy_password');
认证
为了使用HTTP认证,请使用SoapClient原始的login
和password
选项。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并等待我开发。这可能会花费一些时间,因为我通常很忙。