WebService 是異構系統集成的經典方案,基於 SOAP 協議、WSDL 描述語言,通過 HTTP 傳輸 XML 數據。PHP 內置 SoapServer 和 SoapClient 類,配合 SoapDiscovery 工具類,可快速構建標準化的 WebService 服務端與客戶端。本文通過完整實例演示從零構建一個可用的 PHP WebService。
<?php
// Service.php
class Service
{
public function Hello(): string
{
return 'Hello, SOAP WebService!';
}
public function Add(float $a, float $b): float
{
return $a + $b;
}
public function GetUserInfo(int $uid): array
{
// 模擬數據庫查詢
return [
'id' => $uid,
'name' => "User_{$uid}",
'email' => "user{$uid}@example.com",
'created_at' => date('Y-m-d H:i:s'),
];
}
}
使用 SoapDiscovery.class.php(需從網上下載或使用 Zend Studio 生成):
<?php
// create_wsdl.php
require_once 'Service.php';
require_once 'SoapDiscovery.class.php';
$wsdl = new SoapDiscovery('Service', 'MySoapService'); // 類名、服務名
$wsdl->getWSDL(); // 直接輸出 WSDL XML,可重定向保存為 Service.wsdl
運行後將輸出保存為 Service.wsdl,部署時與 Service.php 放同級目錄。
<?php
// server.php
require_once 'Service.php';
$options = [
'soap_version' => SOAP_1_2,
'encoding' => 'UTF-8',
'actor' => 'https://example.com/soap/server',
];
$server = new SoapServer('Service.wsdl', $options);
$server->setClass('Service');
$server->handle();
<?php
// client.php
ini_set('soap.wsdl_cache_enabled', 0); // 開發期關閉 WSDL 緩存
ini_set('default_socket_timeout', 10); // 設置超時
try {
$client = new SoapClient('https://127.0.0.1/soap/server.php?wsdl', [
'trace' => 1, // 開啟調試追蹤
'exceptions' => true, // 拋出異常而非 PHP 錯誤
'cache_wsdl' => WSDL_CACHE_NONE,
]);
// 方式 1:直接調用方法(推薦)
echo "Add(10, 20) = {$client->Add(10, 20)}\n"; // 30
// 方式 2:使用 __soapCall(動態方法名)
$result = $client->__soapCall('GetUserInfo', [['uid' => 1001]]);
print_r($result);
// 調試:查看最後請求/響應 XML
echo "REQUEST:\n{$client->__getLastRequest()}\n";
echo "RESPONSE:\n{$client->__getLastResponse()}\n";
} catch (SoapFault $e) {
echo "SOAP Fault: {$e->getMessage()}\n";
echo "Code: {$e->faultcode}\n";
}
PHP 默認緩存 WSDL 文件(php.ini 中 soap.wsdl_cache_ttl=86400),開發期必須關閉:
ini_set('soap.wsdl_cache_enabled', '0'); // 或 php.ini 設置
WSDL 中定義 complexType 映射 PHP 關聯數組,客戶端直接傳遞數組即可:
$params = [
'user' => [
'name' => '張三',
'age' => 25,
'tags' => ['vip', 'developer'],
],
];
$client->CreateUser($params);
try {
$result = $client->SomeMethod($params);
} catch (SoapFault $e) {
// 記錄詳細錯誤信息
error_log("SOAP Error: {$e->faultstring} | Code: {$e->faultcode}");
// 可選:嘗試重試或降級處理
}
$client = new SoapClient('https://api.example.com/service?wsdl', [
'stream_context' => stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/path/to/ca-bundle.crt',
],
]),
]);
雖然 REST/JSON 成為主流,但 WebService (SOAP) 在以下場景仍具優勢:
PHP 內置 SOAP 擴展功能完善,配合 SoapDiscovery 可實現「代碼優先」快速生成 WSDL。掌握服務端 SoapServer、客戶端 SoapClient、WSDL 緩存控制、異常處理等核心點,即可構建生產級 WebService 接口。