PHP Conference Japan 2024

SoapClient::__construct

(PHP 5, PHP 7, PHP 8)

SoapClient::__constructSoapClient 构造函数

描述

public SoapClient::__construct(?string $wsdl, array $options = [])

创建一个 SoapClient 对象以连接到 SOAP 服务。

参数

wsdl

描述服务的 WSDL 文件的 URI,用于自动配置客户端。如果未提供,则客户端将以非 WSDL 模式运行。

注意:

默认情况下,WSDL 文件将被缓存以提高性能。要禁用或配置此缓存,请参阅 SOAP 配置选项 cache_wsdl 选项

options

一个关联数组,指定 SOAP 客户端的其他选项。如果提供了 wsdl,则此选项是可选的;否则,必须至少提供 locationurl

location string

要发送请求到的 SOAP 服务器的 URL。

如果未提供 wsdl 参数,则需要此参数。如果同时提供了 wsdl 参数和 location 选项,则 location 选项将覆盖 WSDL 文件中指定的任何位置。

uri string

SOAP 服务的目标命名空间。

如果未提供 wsdl 参数,则需要此参数;否则将被忽略。

style int

使用常量 SOAP_RPCSOAP_DOCUMENT 指定要为此客户端使用的绑定样式。SOAP_RPC 指示 RPC 样式绑定,其中 SOAP 请求主体包含函数调用的标准编码。SOAP_DOCUMENT 指示文档样式绑定,其中 SOAP 请求主体包含具有服务定义含义的 XML 文档。

如果提供了 wsdl 参数,则忽略此选项,并且样式将从 WSDL 文件中读取。

如果既未提供此选项也未提供 wsdl 参数,则使用 RPC 样式。

use int

使用常量 SOAP_ENCODEDSOAP_LITERAL 指定要为此客户端使用的编码样式。SOAP_ENCODED 指示使用 SOAP 规范中定义的类型进行编码。SOAP_LITERAL 指示使用服务定义的模式进行编码。

如果提供了 wsdl 参数,则忽略此选项,并且编码将从 WSDL 文件中读取。

如果既未提供此选项也未提供 wsdl 参数,则使用“编码”样式。

soap_version int

指定要使用的 SOAP 协议版本:SOAP_1_1 用于 SOAP 1.1,或 SOAP_1_2 用于 SOAP 1.2。

如果省略,则使用 SOAP 1.1。

authentication int

在请求中使用 HTTP 身份验证时指定身份验证方法。该值可以是 SOAP_AUTHENTICATION_BASICSOAP_AUTHENTICATION_DIGEST

如果省略,并且提供了 login 选项,则使用基本身份验证。

login string

与 HTTP 基本或摘要身份验证一起使用的用户名。

password string

与 HTTP 基本或摘要身份验证一起使用的密码。

不要与 passphrase 混淆,后者用于 HTTPS 客户端证书身份验证。

local_cert string

与 HTTPS 身份验证一起使用的客户端证书的路径。它必须是包含您的证书和私钥的 PEM 编码文件。

该文件还可以包含发行者链,该链必须位于客户端证书之后。

也可以通过 stream_context 设置,该选项还支持指定单独的私钥文件。

passphrase string

local_cert 选项中指定的客户端证书的密码。

不要与 password 混淆,后者用于基本或摘要身份验证。

也可以通过 stream_context 设置。

proxy_host string

用作 HTTP 请求代理服务器的主机名。

还必须指定 proxy_port 选项。

proxy_port int

连接到 proxy_host 中指定的代理服务器时使用的 TCP 端口。

proxy_login string

使用 HTTP 基本身份验证对 proxy_host 中指定的代理服务器进行身份验证的可选用户名。

proxy_password string

使用 HTTP 基本身份验证对 proxy_host 中指定的代理服务器进行身份验证的可选密码。

compression int

启用 HTTP SOAP 请求和响应的压缩。

该值应为三个部分的按位或:一个可选的 SOAP_COMPRESSION_ACCEPT,用于发送“Accept-Encoding”标头;SOAP_COMPRESSION_GZIPSOAP_COMPRESSION_DEFLATE 用于指示要使用的压缩算法;以及 1 到 9 之间的数字,用于指示要在请求中使用的压缩级别。例如,要启用具有最大压缩级别的双向 gzip 压缩,请使用 SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 9

encoding string

定义内部字符编码。请求始终以 UTF-8 发送,并转换为此编码和从此编码转换。

trace 布尔型

捕获请求和响应信息,然后可以使用 SoapClient::__getLastRequest()SoapClient::__getLastRequestHeaders()SoapClient::__getLastResponse()SoapClient::__getLastResponseHeaders() 方法访问这些信息。

如果省略,则默认为 false

classmap 数组

用于将 WSDL 中定义的类型映射到 PHP 类。它应该指定为一个关联 数组,其中 WSDL 中的类型名称作为键,PHP 类名作为值。请注意,元素的类型名称不一定与元素(标签)名称相同。

提供的类名应始终使用任何 命名空间进行完全限定,并且永远不要以 \ 开头。可以使用 ::class 生成正确的形式。

请注意,在创建类时,不会调用构造函数,但会调用各个属性的魔术 __set()__get() 方法。

typemap 数组

用于使用用户定义的回调函数定义类型映射。每个类型映射都应该是一个数组,其键为 type_name字符串,指定 XML 元素类型);type_ns字符串,包含命名空间 URI);from_xml可调用,接受一个字符串参数并返回一个对象)和 to_xml可调用,接受一个对象参数并返回一个字符串)。

exceptions 布尔型

定义错误是否抛出 SoapFault 类型的异常。

默认为 true

connection_timeout 整数

定义连接到 SOAP 服务的超时时间(以秒为单位)。此选项不定义对响应缓慢的服务的超时时间。要限制等待调用完成的时间,可以使用 default_socket_timeout 配置选项。

cache_wsdl 整数

如果提供了 wsdl 参数,并且 soap.wsdl_cache_enabled 配置选项已开启,则此选项确定缓存类型。可以是 WSDL_CACHE_NONEWSDL_CACHE_DISKWSDL_CACHE_MEMORYWSDL_CACHE_BOTH

可以使用两种类型的缓存:内存缓存,它在当前进程的内存中缓存 WSDL;磁盘缓存,它在磁盘上的文件中缓存 WSDL,并在所有进程之间共享。用于磁盘缓存的目录由 soap.wsdl_cache_dir 配置选项确定。两种缓存都使用相同的生存期,由 soap.wsdl_cache_ttl 配置选项确定。内存缓存还具有由 soap.wsdl_cache_limit 配置选项确定的最大条目数。

如果未指定,则将使用 soap.wsdl_cache 配置选项。

user_agent 字符串

在发出请求时,用于 User-Agent HTTP 标头的值。

也可以通过 stream_context 设置。

如果未指定,则用户代理将为 "PHP-SOAP/" 后跟 PHP_VERSION 的值。

stream_context 资源

stream_context_create() 创建的 流上下文,允许设置其他选项。

上下文可能包含 套接字上下文选项SSL 上下文选项,以及选定的 HTTP 上下文选项content_typeheadermax_redirectsprotocol_versionuser_agent

请注意,以下 HTTP 标头会自动生成或来自其他选项,如果在 'header' 上下文选项中指定,则将被忽略:hostconnectionuser-agentcontent-lengthcontent-typecookieauthorizationproxy-authorization

features 整数

一个位掩码,用于启用以下一个或多个功能

SOAP_SINGLE_ELEMENT_ARRAYS

在将响应解码为数组时,默认行为是检测某个元素名称在特定父元素中出现一次还是多次。对于仅出现一次的元素,对象属性允许直接访问内容;对于出现多次的元素,该属性包含每个匹配元素的内容的数组。

如果启用了 SOAP_SINGLE_ELEMENT_ARRAYS 功能,则仅出现一次的元素将放置在单元素数组中,以便所有元素的访问方式一致。这仅在使用包含响应架构的 WSDL 时有效。请参阅示例部分以了解说明。

SOAP_USE_XSI_ARRAY_TYPE

use 选项或 WSDL 属性设置为 encoded 时,强制数组使用 SOAP-ENC:Array 类型的类型,而不是特定于架构的类型。

SOAP_WAIT_ONE_WAY_CALLS

即使 WSDL 指示单向请求,也等待响应。

keep_alive 布尔型

一个布尔值,用于定义是否发送 Connection: Keep-Alive 标头或 Connection: close

默认为 true

ssl_method 字符串

指定要与安全 HTTP 连接一起使用的 SSL 或 TLS 协议版本,而不是默认协商。指定 SOAP_SSL_METHOD_SSLv2SOAP_SSL_METHOD_SSLv3 将分别强制使用 SSL 2 或 SSL 3。指定 SOAP_SSL_METHOD_SSLv23 没有任何效果;该常量仅为了向后兼容而存在。从 PHP 7.2 开始,指定 SOAP_SSL_METHOD_TLS 也没有任何效果;在早期版本中,它强制使用 TLS 1.0。

请注意,SSL 版本 2 和 3 被认为是不安全的,并且已安装的 OpenSSL 库可能不支持它们。

此选项从 PHP 8.1.0 开始已 弃用。一个更灵活的替代方案,它允许指定 TLS 的各个版本,是使用 stream_context 选项以及 'crypto_method' 上下文参数。

示例 #1 指定仅使用 TLS 1.3

<?php
$context
= stream_context_create([
'ssl' => [
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT
]
]);
$client = new SoapClient("some.wsdl", ['context' => $context]);

错误/异常

如果在非 WSDL 模式下未提供 locationuri 选项,则 SoapClient::__construct() 将生成 E_ERROR 错误。

如果无法加载 wsdl URI,则会抛出 SoapFault 异常。

示例

示例 #2 SoapClient::__construct() 示例

<?php

$client
= new SoapClient("some.wsdl");

$client = new SoapClient("some.wsdl", array('soap_version' => SOAP_1_2));

$client = new SoapClient("some.wsdl", array('login' => "some_name",
'password' => "some_password"));

$client = new SoapClient("some.wsdl", array('proxy_host' => "localhost",
'proxy_port' => 8080));

$client = new SoapClient("some.wsdl", array('proxy_host' => "localhost",
'proxy_port' => 8080,
'proxy_login' => "some_name",
'proxy_password' => "some_password"));

$client = new SoapClient("some.wsdl", array('local_cert' => "cert_key.pem"));

$client = new SoapClient(null, array('location' => "https://127.0.0.1/soap.php",
'uri' => "http://test-uri/"));

$client = new SoapClient(null, array('location' => "https://127.0.0.1/soap.php",
'uri' => "http://test-uri/",
'style' => SOAP_DOCUMENT,
'use' => SOAP_LITERAL));

$client = new SoapClient("some.wsdl",
array(
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 9));

$client = new SoapClient("some.wsdl", array('encoding'=>'ISO-8859-1'));

class
MyBook {
public
$title;
public
$author;
}

$client = new SoapClient("books.wsdl", array('classmap' => array('book' => "MyBook")));

$typemap = array(
array(
"type_ns" => "http://schemas.example.com",
"type_name" => "book",
"from_xml" => "unserialize_book",
"to_xml" => "serialize_book")
);
$client = new SoapClient("books.wsdl", array('typemap' => $typemap));

?>

示例 #3 使用SOAP_SINGLE_ELEMENT_ARRAYS 功能

/* 假设响应如下,以及相应的 WSDL */
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:example">
<SOAP-ENV:Body>
<response>
<collection>
<item>Single</item>
</collection>
<collection>
<item>First</item>
<item>Second</item>
</collection>
</response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/

echo "默认:\n";

$client = new TestSoapClient(__DIR__ . '/temp.wsdl');
$response = $client->exampleRequest();
var_dump( $response->collection[0]->item );
var_dump( $response->collection[1]->item );

echo "\n使用 SOAP_SINGLE_ELEMENT_ARRAYS:\n";

$client = new TestSoapClient(__DIR__ . '/temp.wsdl', ['features' => SOAP_SINGLE_ELEMENT_ARRAYS]);
$response = $client->exampleRequest();
var_dump( $response->collection[0]->item );
var_dump( $response->collection[1]->item );

以上示例将输出

Default:
string(6) "Single"
array(2) {
  [0] =>
  string(5) "First"
  [1] =>
  string(6) "Second"
}

With SOAP_SINGLE_ELEMENT_ARRAYS:
array(1) {
  [0] =>
  string(6) "Single"
}
array(2) {
  [0] =>
  string(5) "First"
  [1] =>
  string(6) "Second"
}

添加注释

用户贡献的注释 1 条注释

1
turabgarip at gmail dot com
5 个月前
关于 steam_context 选项的两点说明

1- 在文档的示例中,它说

<?php
$client
= new SoapClient("some.wsdl", ['context' => $context]);
?>

这是错误的。正如参数列表中所述,它必须是“stream_context”,而不是“context”。

2- 此处的 HTTP 上下文手册:https://php.net/manual/en/context.http.php

它说 header 可以是数组或字符串类型。这也是错误的。它不一定是可选的,因为它可能取决于您的 PHP 编译时配置。

如果您的实例编译了 --with-curlwrappers 选项,则应在 HTTP 上下文中使用数组类型作为 header,否则应使用换行符 (\n) 分隔的字符串作为 header。我不确定 SoapClient 是否尊重 curl_wrappers 选项,因为尽管它在我的实例中已启用,并且尽管我正在使用数组作为 header 来为非 Soap 操作创建 HTTP 上下文;SoapClient 要求我使用字符串。否则,它只会完全删除 stream_context。

因此,使用 SoapClient,最好对 HTTP 标头使用字符串,例如

<?php

$context
= stream_context_create(array(
'http' => array(
'user_agent' => 'My App',
'header' =>
"Custom-Header: Value\n" .
"Another Header: Surprise"
)
));

$client = new SoapClient('some.wsdl', ['stream_context' => $context]);
?>
To Top