雖然現代 PHP 推薦使用原生 SoapClient 或 REST API,但歷史專案常遇到 NuSOAP。本文記錄其核心用法與常見坑點。
# 方式 1:Composer(推薦,自動載入) composer require nusoap/nusoap # 方式 2:手動下載 # https://sourceforge.net/projects/nusoap/files/nusoap/0.9.5/nusoap-0.9.5.zip require_once 'lib/nusoap.php';
getError()) {
die('客戶端構造失敗: ' . $client->getError());
}
// 調用遠程方法
$params = [
'device_number' => '9910948357',
'latitude' => '40.727757',
'longitude' => '-73.984366',
'battery_status' => '30',
];
$result = $client->call('update_location', $params);
// 檢查 SOAP Fault
if ($client->fault) {
echo 'SOAP Fault: ';
print_r($result);
} elseif ($client->getError()) {
echo '調用錯誤: ' . $client->getError();
} else {
echo '結果: ';
print_r($result);
}
// 調試:查看請求/響應原始 XML
echo 'Request
' . htmlspecialchars($client->request) . '
';
echo 'Response
' . htmlspecialchars($client->response) . '
';
echo 'Debug
' . htmlspecialchars($client->debug_str) . '
';
// 對應 WSDL 中定義的複雜類型
$params = [
'user' => [
'id' => 123,
'profile' => [
'name' => 'John',
'email' => 'john@example.com',
'addresses' => [
['type' => 'home', 'city' => 'New York'],
['type' => 'work', 'city' => 'Boston'],
],
],
],
'options' => [
'notify' => true,
'priority' => 'high',
],
];
$result = $client->call('complexMethod', $params);
$client = new nusoap_client('https://example.com/api/endpoint'); // 無 WSDL
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
// 手動指定命名空間與方法
$namespace = 'https://example.com/ns';
$method = 'MyMethod';
$params = ['arg1' => 'value1'];
$result = $client->call($method, $params, $namespace);
| 問題 | 原因 | 解決 |
|---|---|---|
| 中文亂碼 | 編碼不匹配 | $client->soap_defencoding = 'UTF-8'; $client->decode_utf8 = false; |
| Class 'nusoap_client' not found | 引入路徑錯誤 | 檢查 require_once 路徑,或用 Composer 自動載入 |
| 調用超時 | 網絡/服務端慢 | $client->setTimeout(30); 設置 30 秒超時 |
| SSL 證書驗證失敗 | 自簽名/過期證書 | $client->setSSLVerifyPeer(false); $client->setSSLVerifyHost(false);(僅測試環境) |
| 命名空間不匹配 | WSDL 定義與調用不一致 | 檢查 WSDL targetNamespace,調用時傳正確 namespace |
| 返回 null/空 | 服務端異常或參數錯誤 | 開啟 $client->debug_str 分析請求/響應 XML |
NuSOAP 純 PHP 實現,效能較差,且長期未維護。新專案強烈建議使用 PHP 內建 SoapClient:
// 原生 SoapClient 等價代碼
$client = new SoapClient('https://example.com/api/service?wsdl', [
'trace' => 1, // 啟用調試
'exceptions' => true, // 拋出異常而非返回 false
'cache_wsdl' => WSDL_CACHE_MEMORY,
'encoding' => 'UTF-8',
'stream_context' => stream_context_create([
'ssl' => [
'verify_peer' => false, // 僅測試
'verify_peer_name' => false,
],
'http' => [
'timeout' => 30,
],
]),
]);
try {
$result = $client->updateLocation([
'device_number' => '9910948357',
'latitude' => '40.727757',
// ...
]);
print_r($result);
} catch (SoapFault $e) {
echo "SOAP Fault: {$e->getMessage()}";
if (isset($client->__getLastRequest())) {
echo "Request: " . $client->__getLastRequest();
}
}
| 特性 | NuSOAP | 原生 SoapClient |
|---|---|---|
| 效能 | 純 PHP,慢 | C 擴展,快 10-50x |
| WSDL 支援 | 部分 | 完整 |
| WS-Security | 不支援 | 需手動實現或擴展 |
| 維護狀態 | 停止更新 | PHP 核心持續維護 |
| 依賴 | 需引入庫 | 零依賴(需 soap 擴展) |