WebService 採用 XML + HTTP 跨平台交換資料,核心標準包含 SOAP (傳輸協定)、WSDL (服務描述)、UDDI (註冊發現)。PHP 透過 SoapServer / SoapClient 類別原生支援。
[Client] --SOAP Request (HTTP POST)--> [Server (SoapServer)]
<-- SOAP Response (XML) --
<?php
// Service.php - 實際業務邏輯
class Service {
public function Hello() {
return 'hello good';
}
public function Add($a, $b) {
return $a + $b;
}
}
?>
需下載 SoapDiscovery.class.php (開源工具類),或使用 Zend Studio 等 IDE 圖形化生成。
<?php
// creat_wsdl.php
include_once('Service.php');
include_once('SoapDiscovery.class.php');
$wsdl = new SoapDiscovery('Service', 'soap'); // 類名、服務名
$wsdl->getWSDL(); // 輸出 Service.wsdl 並直接輸出至瀏覽器
?>
執行後將輸出內容另存為 Service.wsdl 放置於服務端同目錄。
<?php
// server.php
include_once('Service.php');
$server = new SoapServer('Service.wsdl', array(
'soap_version' => SOAP_1_2,
'cache_wsdl' => WSDL_CACHE_NONE, // 開發階段關閉快取
));
$server->setClass('Service'); // 註冊所有 public 方法
$server->handle(); // 處理請求
?>
<?php
// client.php
ini_set('soap.wsdl_cache_enabled', 0); // 關閉 WSDL 快取 (開發必備)
$client = new SoapClient('https://localhost/soap/Service.wsdl', array(
'trace' => 1, // 除錯用
'exceptions' => true, // 拋出 SoapFault 異常
));
try {
echo $client->Add(1, 2); // 輸出 3
// 或使用 __soapCall
// echo $client->__soapCall('Add', array(1, 2));
} catch (SoapFault $e) {
echo "SOAP Error: {$e->getMessage()}";
// 除錯:var_dump($client->__getLastRequest(), $client->__getLastResponse());
}
?>
WSDL 中定義 <complexType>,PHP 端對應 stdClass 或自定類別 + __set/__get,或使用 SoapVar 指定編碼。
$header = new SoapHeader('https://ns.example.com', 'AuthToken', array('user'=>'a','pass'=>'b'));
$client->__setSoapHeaders($header);
targetNamespace) 一致性long → PHP int)looks like we got no XML document,檢查是否為 REST/JSON 而非 SOAP| 錯誤 | 原因與解決 |
|---|---|
Class 'SoapClient' not found | 未安裝 php-soap:yum install php-soap / apt install php-soap |
WSDL_CACHE 導致修改不生效 | 關閉快取:ini_set('soap.wsdl_cache_enabled', 0) 或刪除 /tmp/wsdl-* |
SOAP-ERROR: Parsing WSDL | WSDL XML 格式錯誤、無法訪問、或 HTTPS 證書問題 |
| 中文亂碼 | 確保檔案 UTF-8 無 BOM,WSDL 宣告 encoding="UTF-8" |