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_DOCUMENTSOAP_RPC 表示 RPC 樣式綁定,其中 SOAP 請求主體包含函式呼叫的標準編碼。SOAP_DOCUMENT 表示文件樣式綁定,其中 SOAP 請求主體包含具有服務定義含義的 XML 文件。

如果提供 wsdl 參數,則此選項將被忽略,且樣式將從 WSDL 檔案讀取。

如果未提供此選項且未提供 wsdl 參數,則使用 RPC 樣式。

use int

指定要用於此用戶端的編碼樣式,使用常數 SOAP_ENCODEDSOAP_LITERALSOAP_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 混淆,passphrase 用於 HTTPS 用戶端憑證驗證。

local_cert string

用於 HTTPS 驗證的用戶端憑證路徑。它必須是包含您的憑證和私鑰的 PEM 編碼檔案。

該檔案也可以包含一連串發行者,這些發行者必須位於用戶端憑證之後。

也可以透過 stream_context 設定,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 請求和回應的壓縮。

該值應為三個部分的位元 OR 運算:一個可選的 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 bool

擷取請求和回應資訊,這些資訊隨後可透過方法 SoapClient::__getLastRequest()SoapClient::__getLastRequestHeaders()SoapClient::__getLastResponse()SoapClient::__getLastResponseHeaders() 存取。

如果省略,預設為 false

classmap array

用於將 WSDL 中定義的類型對應到 PHP 類別。它應指定為一個關聯 陣列,其中 WSDL 中的類型名稱作為鍵,PHP 類別的名稱作為值。請注意,元素的類型名稱不一定與元素(標籤)名稱相同。

提供的類別名稱應始終使用完整的 命名空間 限定,且絕不應以開頭的 \ 開始。正確的格式可以使用 ::class 產生。

請注意,當建立一個類別時,不會呼叫建構子,但會呼叫個別屬性的魔術方法 __set()__get()

typemap array

用於使用使用者定義的回呼函式定義類型對應。每個類型對應都應是一個陣列,其中包含鍵 type_name字串,指定 XML 元素類型);type_ns字串,包含命名空間 URI);from_xml可呼叫,接受一個字串參數並傳回一個物件)和 to_xml可呼叫,接受一個物件參數並傳回一個字串)。

exceptions bool

定義錯誤是否拋出 SoapFault 類型的例外。

預設為 true

connection_timeout int

定義連線到 SOAP 服務的逾時時間(以秒為單位)。此選項不定義回應緩慢的服務逾時。若要限制等待呼叫完成的時間,可以使用 default_socket_timeout 設定選項。

cache_wsdl int

如果提供了 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 string

在發出請求時,要在 User-Agent HTTP 標頭中使用的值。

也可以透過 stream_context 設定。

如果未指定,使用者代理程式將為 "PHP-SOAP/",後接 PHP_VERSION 的值。

stream_context resource

stream_context_create() 建立的 串流內容,允許設定其他選項。

內容可能包括 socket 內容選項SSL 內容選項,以及選定的 HTTP 內容選項content_typeheadermax_redirectsprotocol_versionuser_agent

請注意,下列 HTTP 標頭會自動產生或從其他選項產生,如果它們在 'header' 內容選項中指定,則會被忽略:hostconnectionuser-agentcontent-lengthcontent-typecookieauthorizationproxy-authorization

features int

用於啟用一個或多個下列功能的位元遮罩

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 bool

一個布林值,定義是否要傳送 Connection: Keep-Alive 標頭或 Connection: close

預設為 true

ssl_method string

指定用於安全 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 起已過時。更靈活的替代方案是使用具有 'crypto_method' 內容參數的 stream_context 選項,允許指定個別的 TLS 版本。

範例 #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 則註解

turabgarip at gmail dot com
5 個月前
關於 steam_context 選項的兩個注意事項

1- 在文件的範例中,它說

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

這是錯誤的。如同參數列表中所述,它必須是 "stream_context" 而不是 "context"。

2- 此處的 HTTP Context 手冊:https://php.dev.org.tw/manual/en/context.http.php

它說標頭可以是陣列或字串類型。這也是錯誤的。它可能不一定是可選的,因為它可能取決於您的 PHP 編譯時組態。

如果您的實例是使用 --with-curlwrappers 選項編譯的,則應該在 HTTP context 中對標頭使用陣列類型,如果沒有,則應該對標頭使用以換行符號 (\n) 分隔的字串。我不確定 SoapClient 是否尊重 curl_wrappers 選項,因為儘管它在我的實例中已啟用,並且儘管我使用陣列作為標頭來建立非 Soap 操作的 HTTP context,但 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