WebService 是異構系統集成的經典方案,基於 HTTP 傳輸、XML(SOAP)封裝。本文系統講解 SOAP 报文結構、WSDL 定義、PHP SoapClient 調用、自建 WSDL 服務端全流程。
POST /WebServices/MobileCodeWS.asmx HTTP/1.1
Host: webservice.webxml.com.cn
Content-Type: text/xml; charset=utf-8
Content-Length: 354
SOAPAction: "https://WebXml.com.cn/getMobileCodeInfo"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="https://www.w3.org/2001/XMLSchema"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getMobileCodeInfo xmlns="https://WebXml.com.cn/">
<mobileCode>13426060134</mobileCode>
<userID></userID>
</getMobileCodeInfo>
</soap:Body>
</soap:Envelope>
<?php
// 1. 啟用擴展:php.ini 取消註釋 extension=soap,重啟 Apache
// 2. 實例化客戶端
$wsdl = 'https://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL';
$soap = new SoapClient($wsdl);
// 3. 查看可用方法
print_r($soap->__getFunctions());
/* 輸出示例:
Array(
[0] => getMobileCodeInfoResponse getMobileCodeInfo(getMobileCodeInfo $parameters)
[1] => getDatabaseInfoResponse getDatabaseInfo(getDatabaseInfo $parameters)
)
*/
// 4. 查看類型定義
print_r($soap->__getTypes());
// 5. 調用方法
$result = $soap->getMobileCodeInfo(array('mobileCode' => '13426060134'));
var_dump($result);
/* 輸出:
object(stdClass)#2 (1) {
["getMobileCodeInfoResult"]=>
string(42) "13426060134:北京 北京 聯通"
}
*/
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="DemoService"
targetNamespace="https://localhost/ws/"
xmlns:tns="https://localhost/ws/"
xmlns:soap="https://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="https://www.w3.org/2001/XMLSchema"
xmlns="https://schemas.xmlsoap.org/wsdl/">
<types>
<xsd:schema targetNamespace="https://localhost/ws/"></xsd:schema>
</types>
<message name="testRequest">
<part name="term" type="xsd:string"/>
</message>
<message name="testResponse">
<part name="value" type="xsd:string"/>
</message>
<portType name="DemoPortType">
<operation name="test">
<input message="tns:testRequest"/>
<output message="tns:testResponse"/>
</operation>
</portType>
<binding name="DemoBinding" type="tns:DemoPortType">
<soap:binding style="rpc" transport="https://schemas.xmlsoap.org/soap/http"/>
<operation name="test">
<soap:operation soapAction="https://localhost/ws/test"/>
<input><soap:body use="encoded" namespace="https://localhost/ws/" encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"/></input>
<output><soap:body use="encoded" namespace="https://localhost/ws/" encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"/></output>
</operation>
</binding>
<service name="DemoService">
<port name="DemoPort" binding="tns:DemoBinding">
<soap:address location="https://localhost/ws/server.php"/>
</port>
</service>
</definitions>
<?php
// server.php
function test($x) {
return "Server received: $x";
}
$server = new SoapServer('wsdl.xml');
$server->addFunction('test');
$server->handle();
?>
<?php
$client = new SoapClient('https://localhost/ws/wsdl.xml', array('trace' => 1));
var_dump($client->test('Hello WebService'));
// 輸出:string(28) "Server received: Hello WebService"
?>
在 WSDL <message> 中使用自定義複雜類型:
<types>
<xsd:schema targetNamespace="https://localhost/ws/">
<xsd:complexType name="ArrayOfString">
<xsd:sequence>
<xsd:element name="string" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</types>
<message name="testRequest">
<part name="terms" type="tns:ArrayOfString"/>
</message>
XML-RPC 可視為 SOAP 簡化版,數據封裝更輕量。PHP 需啟用 extension=xmlrpc。適合內部輕量 RPC,現代項目多改用 JSON-RPC/gRPC。
| 維度 | WebService (SOAP) | JSON API |
|---|---|---|
| 數據封裝 | XML | JSON |
| 復雜度 | 高(WSDL、XSD、命名空間) | 低 |
| 傳輸協議 | HTTP/HTTPS(也可 SMTP 等) | HTTP/HTTPS |
| 類型系統 | 強類型(XSD) | 弱類型(需額外文檔/Schema) |
| 自描述性 | 強(WSDL 即文檔) | 需 Swagger/OpenAPI 文檔 |
| 適用場景 | 企業級集成、跨語言強契約、金融/電信 | 前後端分離、移動端、微服務、快速迭代 |