SOAP (Simple Object Access Protocol) 是企業級系統整合常用協定,PHP 內建 SoapClient 類別支援 WSDL (Web Services Description Language) 自動解析服務定義。本文說明基本呼叫、除錯技巧與常見問題處理。
; php.ini 啟用 SOAP 擴充套件
extension=soap
; 確認安裝
php -m | grep soap
<?php
// WSDL 服務端點
$wsdl = 'https://www.example.com/Service.asmx?WSDL';
try {
// 建立客戶端,啟用追蹤模式除錯
$client = new SoapClient($wsdl, [
'trace' => 1, // 記錄請求/回應
'exceptions' => true, // 拋出例外而非錯誤
'cache_wsdl' => WSDL_CACHE_NONE, // 開發階段停用快取
]);
// 呼叫遠端方法
$params = ['zipcode' => '23590'];
$result = $client->getTemp($params);
echo "溫度查詢結果: ";
var_dump($result);
// 除錯:查看送出的 XML 請求
echo "<h3>送出請求 (Request)</h3>";
echo '<pre>' . htmlspecialchars($client->__getLastRequest()) . '</pre>';
// 除錯:查看收到的 XML 回應
echo "<h3>收到回應 (Response)</h3>";
echo '<pre>' . htmlspecialchars($client->__getLastResponse()) . '</pre>';
} catch (SoapFault $e) {
echo "SOAP 錯誤: " . $e->getMessage();
if (isset($client)) {
echo "<pre>請求: " . htmlspecialchars($client->__getLastRequest()) . "</pre>";
echo "<pre>回應: " . htmlspecialchars($client->__getLastResponse()) . "</pre>";
}
}
?>
<?php
$client = new SoapClient('https://example.com/Service.asmx?WSDL');
$functions = $client->__getFunctions();
echo "<h3>可用方法列表</h3><pre>";
print_r($functions);
echo "</pre>";
// 輸出範例:
// Array
// (
// [0] => string getTemp(string $zipcode)
// [1] => string getWeather(string $city)
// [2] => ArrayOfString getForecast(string $zipcode)
// )
?>
<?php
// 假設 WSDL 定義複雜型別:UserInfo { string name; int age; string[] tags; }
$params = [
'userInfo' => [
'name' => '張三',
'age' => 28,
'tags' => ['VIP', '會員', '活躍用戶']
],
'options' => [
'includeDetails' => true,
'format' => 'json'
]
];
$result = $client->updateUserProfile($params);
?>
<?php
// 建立 SOAP Header 認證資訊
$authHeader = new SoapHeader(
'https://example.com/auth', // 命名空間
'AuthHeader', // Header 元素名稱
[
'username' => 'api_user',
'password' => 'api_secret',
'token' => 'optional_token'
]
);
$client = new SoapClient($wsdl);
$client->__setSoapHeaders($authHeader);
// 後續呼叫會自動帶入 Header
$result = $client->protectedMethod(['data' => 'test']);
?>
<?php
// 生產環境建議啟用快取
$client = new SoapClient($wsdl, [
'cache_wsdl' => WSDL_CACHE_MEMORY, // 或 WSDL_CACHE_DISK
'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // 避免單元素陣列問題
]);
// 手動清除快取 (部署新版 WSDL 時)
ini_set('soap.wsdl_cache_enabled', 0);
// 或刪除 /tmp/wsdl-* 檔案
?>
| 問題 | 原因 | 解決方法 |
|---|---|---|
| Class 'SoapClient' not found | 未安裝/啟用 soap 擴充套件 | 安裝 php-soap 並重啟 PHP-FPM/Apache |
| SOAP-ERROR: Parsing WSDL | WSDL 網址錯誤、需認證、SSL 憑證問題 | 檢查網址、設定 stream_context、驗證憑證 |
| 看起來像陣列但無法用索引存取 | SOAP 單元素回傳非陣列 | 啟用 SOAP_SINGLE_ELEMENT_ARRAYS 選項 |
| 編碼錯誤/亂碼 | WSDL 定義 encoding 與實際不符 | 指定 encoding 參數、使用 utf8_encode/decode |
| Function not found | 方法名稱大小寫、命名空間不符 | 用 __getFunctions() 確認確切名稱 |
<?php
// 當無 WSDL 時,手動指定端點與 URI
$client = new SoapClient(null, [
'location' => 'https://example.com/soap/server.php',
'uri' => 'https://example.com/soap/',
'trace' => 1,
]);
// 呼叫需完整參數結構
$result = $client->__soapCall('methodName', [
'parameters' => ['arg1' => 'value1', 'arg2' => 'value2']
]);
?>
掌握 PHP SOAP Client 操作,能輕鬆串接企業級 ERP、CRM、金流等 SOAP 介面系統。