NuSOAP教程

這個文檔描述瞭如何取得和安裝 NuSOAP,然後提供一些實例來說明 NuSOAP 的功能,這並不是一個全面的 NuSOAP 的介紹,但是希望能夠然一些 PHP 開發者可以有一個很好的入門。


NuSOAP 是一組 PHP 類,它讓開發者可以創建和使用 SOAP web services。它不需要安裝任何的 PHP 擴展。它是在2004年12月3日被開發,當前的版本是 NuSOAP(0.6.7) 。支持 SOAP 1.1 規范,它能夠生產 WSDL 1.1 ,當然也可以使用它,同時也支持 rpc/encoded and document/literal service。但是,必須註意 NuSOAP 沒有像 .NET 和 Apache Axis 那樣提供完全的實現。


Hello, World
我會以 “Hello, World” 為實例做開始,編寫基本的 NuSOAP 客戶端和服務器端的代碼。


我們先從服務器端開始,應為沒有服務器端,有客戶端也是沒有意義的。我們將編寫一個帶有單個參數並返回一個字符串,名叫 Hello 的 SOAP 方法,希望代碼中的註釋能夠提供有效的說明。


<?php
// Pull in the NuSOAP code
require_once(nusoap.php);
// Create the server instance
$server = new soap_server;
// Register the method to expose
$server->register(hello);
// Define the method as a PHP function
function hello($name) {
    return Hello, . $name;
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ;
$server->service($HTTP_RAW_POST_DATA);
?>


以下是客戶端的代碼,有一些重要的事情需要註意:首先,當創建實例 soapclient 時,需要指定一個 service 的 URL 為參數,在這個實例中,helloworld.php 從 http://localhost/phphack 訪問的。當然,你要使用的 services 放在不同的 URL;第二,當調用service 時,第一個參數是 service 的名字,必須要匹配有效的方法名(有的服務器是大小寫敏感的)。在這個實例,他必須匹配在 helloworld.php 中已經註冊瞭的方法。最後,第二個參數是一個數組,它將是傳遞給 SOAP service 方法作為參數。既然 helloworld.php 中的方法 hello 隻有一個參數,那麼數組就隻有一個元素。


<?php
// Pull in the NuSOAP code
require_once(nusoap.php);
// Create the client instance
$client = new soapclient(http://localhost/phphack/helloworld.php);
// Call the SOAP method
$result = $client->call(hello, array(name => Scott));
// Display the result
print_r($result);
?>


Debugging
編程時,當有問題出現的時候你都需要調試。NuSOAP 提供瞭一組工具來幫助你做這個工作。NuSOAP 調試的時候需要查看的信息是發送的請求信息和返回的相應信息。NuSOAP 的客戶端類允許你通過它的兩個成員來查看這些信息。例如,這裡是顯示請求和響應的 helloworldclient.php 的修改版。在下一部分我會回顧顯示在客戶端代碼的請求和響應信息。


<?php
// Pull in the NuSOAP code
require_once(nusoap.php);
// Create the client instance
$client = new soapclient(http://localhost/phphack/helloworld.php);
// Call the SOAP method
$result = $client->call(hello, array(name => Scott));
// Display the result
print_r($result);
// Display the request and response
echo <h2>Request</h2>;
echo <pre> . htmlspecialchars($client->request, ENT_QUOTES) . </pre>;
echo <h2>Response</h2>;
echo <pre> . htmlspecialchars($client->response, ENT_QUOTES) . </pre>;
?>


NuSOAP 也提供瞭一個方法使用它的類就可以通過日志來查看調試信息。加入以下的代碼將會顯示冗長的調試信息。不幸的是輸出的說明必須留給讀者。


// Display the debug messages
echo <h2>Debug</h2>;
echo <pre> . htmlspecialchars($client->debug_str, ENT_QUOTES) . </pre>;


服務器端能夠提供相似的調試信息,有趣的是,這些調試信息是在SOAP 的相應的末尾以 xml 格式顯示,因此它可以在客戶端中查看到。服務器端的調試看起來像這樣:


<?php
// Pull in the NuSOAP code
require_once(nusoap.php);
// Enable debugging *before* creating server instance
$debug = 1;
// Create the server instance
$server = new soap_server;
// Register the method to expose
$server->register(hello);
// Define the method as a PHP function
function hello($name) {
    return Hello, . $name;
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ;
$server->service($HTTP_RAW_POST_DATA);
?>


調試的第三個方法不算是真正的調試,它是很好的編程實踐。上面的實例在調用 SOAP 的時候沒有做錯誤的檢查,更健壯的客戶端會像這樣:


<?php
// Pull in the NuSOAP code
require_once(nusoap.php);
// Create the client instance
$client = new soapclient(http://localhost/phphack/helloworld.php);
// Check for an error
$err = $client->getError();
if ($err) {
    // Display the error
    echo <p><b>Constructor error: . $err . </b></p>;
    // At this point, you know the call that follows will fail
}
// Call the SOAP method
$result = $client->call(hello, array(name => Scott));
// Check for a fault
if ($client->fault) {
    echo <p><b>Fault: ;
    print_r($result);
    echo </b></p>;
} else {
    // Check for errors
    $err = $client->getError();
    if ($err) {
        // Display the error
        echo <p><b>Error: . $err . </b></p>;
    } else {
        // Display the result
        print_r($result);
    }
}
?>


為瞭測試代碼,需要引起錯誤發生,例如,改變調用的方法名稱 hello 為 goodbye。


Request and Response
我在上面的例子中已經展示瞭顯示 SOAP 的請求和響應信息是如此的容易,在這裡 hello2client.php 的請求信息:


POST /phphack/helloworld2.php HTTP/1.0
Host: localhost
User-Agent: NuSOAP/0.6.8 (1.81)
Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: “”
Content-Length: 538


<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<SOAP-ENV:Envelope
  SOAP-ENV:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”
  xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
  xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
  xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  xmlns:SOAP-ENC=”http://schemas.xmlsoap.org/soap/encoding/”
  xmlns:si=”http://soapinterop.org/xsd”>
<SOAP-ENV:Body>
  <ns1:hello xmlns:ns1=”http://testuri.org”>
   <name xsi:type=”xsd:string”>Scott</name>
  </ns1:hello>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
在 HTTP headers 裡,你會看到 SOAPAction 是一個空的字符串,這是它的默認值。你的 service 方法可以設置 SOAPAction 的值,你的客戶端代碼可以指定 SOAPAction 作為參數來調用方法。


在 XML payload,你可以看到 NuSOAP 使用和Latin-1一樣著名的 ISO-8859-1 做為編碼,為瞭指定不同的編碼,你可以在客戶端 soapclient 的實例設置 soap_defencoding 屬性。使用指定的編碼來編碼參數的數據當然就是程序員的責任。幸運地,在 SOAP 裡PHP提供瞭很多函數來編碼和解碼最通用的編碼數據,如 UTF-8。



另一件事情要註意的是,元素指定要調用的方法,名稱為 hello 的元素被放在 http://tempuri.org的域名下,指定真實的域名是最佳的實踐,對於很多 services 也是很有必要的。這裡展示瞭一個未來的文檔:


SOAP 服務的響應像以下:


HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 03 Nov 2004 21:32:34 GMT
X-Powere

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *