goetas-webservices / soap-client
Requires
- php: ^7.1|^8.0
- doctrine/inflector: ^2.0
- doctrine/instantiator: ^1.0.3
- goetas-webservices/soap-common: ^0.2.2
- goetas-webservices/soap-reader: ^0.3.3
- goetas-webservices/xsd2php: ^0.4.7
- goetas-webservices/xsd2php-runtime: ^0.2.11
- jms/serializer: ^1.6|^2.0|^3.0
- laminas/laminas-code: ^4.8
- laminas/laminas-zendframework-bridge: ^1.7
- php-http/discovery: ^1.13
- psr/http-client: ^1.0
- psr/http-client-implementation: ^1.0
- psr/http-factory: ^1.0
- psr/http-factory-implementation: ^1.0
- psr/http-message: ^1.0
- psr/http-message-implementation: ^1.0
- symfony/dependency-injection: ^3.3|^4.0|^5.0
Requires (Dev)
- doctrine/coding-standard: ^8.1
- goetas-webservices/wsdl2php: ^0.5.3
- guzzlehttp/guzzle: ^7.2
- laminas/laminas-diactoros: ^2.4
- phpunit/phpunit: ^7.0|^8.0
This package is auto-updated.
Last update: 2024-09-12 20:01:27 UTC
README
PHP 实现SOAP 1.1和1.2客户端规范。
优点
- 纯PHP,不依赖
ext-soap
- 可扩展的(支持JMS事件监听器)
- PSR-7 HTTP消息
- PSR-17 HTTP消息工厂
- PSR-18 HTTP客户端
- 生产环境不解析WSDL/XSD
- IDE类型提示支持
仅支持document/literal样式,且webservice应遵循WS-I指南。
没有计划支持废弃的rpc和encoded样式。不遵循WS-I规范的webservice可能工作,但官方不支持。
演示
goetas-webservices/soap-client-demo是一个演示项目,展示了如何在通用的PHP web应用程序中消费SOAP API。
安装
安装goetas-webservices / soap-client的推荐方法是使用Composer
将此包添加到您的composer.json
文件中。
{
"require": {
"goetas-webservices/soap-client": "^0.3",
},
"require-dev": {
"goetas-webservices/wsdl2php": "^0.5.1",
},
}
如何使用
为了提高性能,此库基于所有SOAP/WSDL元数据必须编译成PHP兼容元数据(实际上是一个大型的普通PHP数组,因此速度非常快)的概念。
为此,我们必须定义一个配置文件(在本例中称为config.yml
),其中包含一些重要信息。
以下是一个示例
# config.yml soap_client: alternative_endpoints: MyServiceName: MySoapPortName: http://localhost:8080/service namespaces: 'http://www.example.org/test/': 'TestNs/MyApp' destinations_php: 'TestNs/MyApp': soap/src destinations_jms: 'TestNs/MyApp': soap/metadata aliases: 'http://www.example.org/test/': MyCustomXSDType: 'MyCustomMappedPHPType' metadata: 'test.wsdl': ~ 'http://www.webservicex.net/weather.asmx?WSDL': ~
此文件包含一些重要部分
SOAP特定
-
alternative_endpoints
(可选)允许您指定在开发集成时可以使用的替代URL。如果此参数不存在,将使用WSDL文件中定义的URL,但如果设置了,将使用为名为MyServiceName的服务和MySoapPortName端口指定的URL。 -
unwrap_returns
(可选,默认:false)允许定义“包装”SOAP服务的模式。指示客户端“解包”所有返回值。
WSDL特定
metadata
指定放置用于生成所有所需PHP元数据的WSDL文件的位置。
XML/XSD特定
-
namespaces
(必需)定义XML命名空间和PHP命名空间之间的映射。(在示例中,我们具有将http://www.example.org/test/
XML命名空间映射到TestNs\MyApp
) -
destinations_php
(必需)指定保存属于TestNs\MyApp
PHP命名空间的PHP类的目录。(在本例中,TestNs\MyApp
类将保存在soap/src
目录中。) -
destinations_jms
(必需)指定保存属于TestNs\MyApp
PHP命名空间的JMS序列化器元数据文件的目录。(在本例中,TestNs\MyApp
元数据将保存在soap/metadata
目录中。) -
aliases
(可选)指定由自定义JMS序列化器处理程序处理的映射。允许指定不生成某些XML类型的元数据,并直接分配给PHP类。为此PHP类需要创建一个自定义JMS序列化/反序列化处理程序。
元数据生成
为了能够使用SOAP客户端,我们必须生成一些元数据和PHP类。
要这样做,我们可以运行
bin/soap-client generate \ tests/config.yml \ --dest-class=GlobalWeather/Container/SoapClientContainer \ soap/src-gw/Container
bin/soap-client generate
是我们正在运行的命令tests/config.yml
是我们配置文件的路径--dest-class=GlobalWeather/Container/SoapClientContainer
允许指定包含所有 Web 服务元数据的容器的完全限定类名。soap/src/Container
是保存包含所有 Web 服务元数据的容器类的路径(您需要配置自动加载器来加载它)
使用客户端
一旦所有元数据都生成,我们就可以使用我们的 SOAP 客户端。
让我们看看一个最小示例
// composer auto loader require __DIR__ . '/vendor/autoload.php'; // instantiate the main container class // the name was defined by --dest-class=GlobalWeather/Container/SoapClientContainer // parameter during the generation process $container = new SoapClientContainer(); // create a JMS serializer instance $serializer = SoapContainerBuilder::createSerializerBuilderFromContainer($container)->build(); // get the metadata from the container $metadata = $container->get('goetas_webservices.soap.metadata_reader'); $factory = new ClientFactory($metadata, $serializer); /** * @var $client \GlobalWeather\SoapStubs\WeatherSoap */ // get the soap client $client = $factory->getClient('http://www.webservicex.net/weather.asmx?WSDL'); // call the webservice $result = $client->getWeather(2010, "May", "USA"); // call the webservice with custom headers $result = $client->getWeather(2010, "May", "USA", Header::asMustUnderstand(new SomeAuth('me', 'pwd')));
请注意 @var $client \GlobalWeather\SoapStubs\WeatherSoap
。生成的元数据还有一个“存根”类,它允许现代 IDE 为参数和返回数据提供类型提示。
这使得您能够更快地开发客户端。
使用具有动态端点的客户端
假设您有具有不同端点(例如,针对每个客户)的相同 Web 服务,因此您想动态更改端点,而无需在配置中为每个客户编写新的端点并运行生成器。
借助 Symfony 的 EnvVarProcessorInterface
,您可以使用 alternative_endpoints
动态设置 Web 服务端点。
以下是一个示例
# config.yml soap_client: alternative_endpoints: MyServiceName: MySoapPortName: 'env(custom_vars:ENDPOINT_SERVICE1_PORT1)'
因此,SoapClientContainer
将在运行时解析特定服务和端点的端点,并将值从 ENDPOINT_SERVICE1_PORT1
变量中获取。
以下是一个简单的类,该类实现 EnvVarProcessorInterface
,负责为我们自定义端点位置提供值(如 custom_vars:ENDPOINT_SERVICE1_PORT1
)。
// SimpleEnvVarProcessor.php used for the `env(custom_vars:*)` variables resolution use Symfony\Component\DependencyInjection\EnvVarProcessorInterface; class SimpleEnvVarProcessor implements EnvVarProcessorInterface { private $map = []; public function __construct(array $map) { $this->map = $map; } public function getEnv($prefix, $name, \Closure $getEnv) { return $this->map[$name]; } public static function getProvidedTypes() { return []; } }
最后,使用 SoapClientContainer
// instantiate our variable processor and set the values for our custom variables $varProcessor = new SimpleEnvVarProcessor([ 'ENDPOINT_SERVICE1_PORT1' => 'http://localhost:8080/service' ]); // create an empty symfony container and set into it the $varProcessor namined as 'custom_vars' $varContainer = new \Symfony\Component\DependencyInjection\Container(); $varContainer->set('custom_vars', $varProcessor); // create the soap container and use $varContainer "env()" style variables resolution $container = new SoapClientContainer(); $container->set('container.env_var_processors_locator', $varContainer); // now $container can be used as explained in the section "Using the client"
这样,即使 WSDL 表示的是其他内容,MyServiceName.MySoapPortName
的端点也将动态解析为 http://localhost:8080/service
。
注意
本项目的代码遵循 MIT 许可。如需专业支持,请联系 goetas@gmail.com 或访问 https://www.goetas.com