2008年9月27日星期六

使用NuSOAP编程---array

这篇文章是接着上两篇 Introduction to NuSOAP 和 Programming with NuSOAP ,增加了一些实例来说明如何使用 SOAP 数组(Arrays)和结构(Structs)类型来创建和使用 SOAP web service。

SOAP Arrays
SOAP Structs
Resources
SOAP Arrays

我在 Introduction to NuSOAP 和 Programming with NuSOAP 两篇文章中使用了普遍的 ’Hello, World\' 实例,显然是没有什么想象力,然而这里,我将会展示如何改进原有的代码,不是对单个人打招呼而使用数组来对多个人打招呼。

SOAP 数组是数字做索引的(不相关的),这与其它编程语言如 C 和 FORTRAN 很相似。因此,我们的 service 可以使用数组索引来访问数组的元素而不是关联的key值。

// Pull in the NuSOAP code
require_once(\'nusoap.php\');
// Create the server instance
$server = new soap_server;
// Register the method to expose
// Note: with NuSOAP 0.6.3, only method name is used w/o WSDL
$server->register(
\'hello\' // method name
);
// Define the method as a PHP function
function hello($names) {
for ($i = 0; $i < count($names); $i++) {
$retval[$i] = \'Hello, \' . $names[$i];
}

return $retval;
}
// 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);
?>

客户端要改变的只是传递的参数是一个数组的名字,而不是单个标量的值。

// Pull in the NuSOAP code
require_once(\'nusoap.php\');
// Create the client instance
$client = new soapclient(\'http://localhost/phphack/helloworld5.php\');
// Check for an error
$err = $client->getError();
if ($err) {
// Display the error
echo \'

Constructor error: \' . $err . \'

\';
// At this point, you know the call that follows will fail
}
// Call the SOAP method
$names = array(\'Scott\', \'Albert\', \'Robert\', \'Phyllis\');
$result = $client->call(
\'hello\', // method name
array(\'names\' => $names) // input parameters
);
// Check for a fault
if ($client->fault) {
echo \'

Fault: \';
print_r($result);
echo \'

\';
} else {
// Check for errors
$err = $client->getError();
if ($err) {
// Display the error
echo \'

Error: \' . $err . \'

\';
} else {
// Display the result
print_r($result);
}
}
?>

请求和响应的信息如下:

POST /phphack/helloworld5.php HTTP/1.0
User-Agent: NuSOAP/0.6.3
Host: localhost:80
Content-Type: text/xml; charset=\"ISO-8859-1\"
Content-Length: 736
SOAPAction: \"\"


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\">



Scott
Albert
Robert
Phyllis





HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Thu, 29 May 2003 18:46:12 GMT
X-Powered-By: PHP/4.0.6
Server: NuSOAP Server v0.6.3
Connection: Close
Content-Type: text/xml; charset=UTF-8
Content-Length: 743


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\">



Hello, Scott
Hello, Albert
Hello, Robert
Hello, Phyllis





SOAP Structs

我们已经使用标量类型和数组标量作为参数和返回值开发过实例,在这一部分,我将会使用SOAP 结构,在 XML 结构中它或多或少地符合复杂类型。这个例子是另一个不同的 Hello, World ,这次使用结构为参数来提供更多的问候信息。

NuSOAP 利用 PHP 的功能,使用关联数组来表现 SOAP 结构,这个例子,我们会使用一个包含了名字,年龄和性别的数组,在 PHP 中会像这样:

$person = array(
\'firstname\' => \'Betty\',
\'age\' => 32,
\'gender\' => \'female\'
);

这个 service 接受一个上面显示的关联数组为参数,它返回另一个数组:

$return = array(
\'greeting\' => \'Hello...\',
\'winner\' => false
);

service 的代码:

// 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\' // method name
);
// Define the method as a PHP function
function hello($person) {
$greeting = \'Hello, \' . $person[\'firstname\'] .
\'. It is nice to meet a \' . $person[\'age\'] .
\' year old \' . $person[\'gender\'] . \'.\';

$winner = $person[\'firstname\'] == \'Scott\';

$retval = array(
\'greeting\' => $greeting,
\'winner\' => $winner
);

return new soapval(\'return\', \'ContestInfo\', $retval, false, \'urn:MyURN\');
}
// 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);
?>

要注意的一件事情是 service 方法返回的是一个 soapval,所以这里的 xml 数据类型 urn:MyURN:ContestInfo 已可以被指定为返回值。

这里是客户端代码:

// Pull in the NuSOAP code
require_once(\'nusoap.php\');
// Create the client instance
$client = new soapclient(\'http://localhost/phphack/helloworld6.php\');
// Check for an error
$err = $client->getError();
if ($err) {
// Display the error
echo \'

Constructor error: \' . $err . \'

\';
// At this point, you know the call that follows will fail
}
// Call the SOAP method
$person = array(\'firstname\' => \'Willi\', \'age\' => 22, \'gender\' => \'male\');
$result = $client->call(
\'hello\', // method name
array(\'person\' => new soapval(\'person\', \'Person\',
$person, false, \'urn:MyURN\')) // input parameters
);
// Check for a fault
if ($client->fault) {
echo \'

Fault: \';
print_r($result);
echo \'

\';
} else {
// Check for errors
$err = $client->getError();
if ($err) {
// Display the error
echo \'

Error: \' . $err . \'

\';
} else {
// Display the result
print_r($result);
}
}
?>

像服务器端,这里使用一个 soapval 为参数,以便 XML 数据类型 urn:MyURN:Person 可以被指定。

请求和响应的信息如下:

POST /phphack/helloworld6.php HTTP/1.0
User-Agent: NuSOAP/0.6.3
Host: localhost:80
Content-Type: text/xml; charset=\"ISO-8859-1\"
Content-Length: 688
SOAPAction: \"\"


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\">



Willi
22
male





HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Thu, 29 May 2003 19:50:30 GMT
X-Powered-By: PHP/4.0.6
Server: NuSOAP Server v0.6.3
Connection: Close
Content-Type: text/xml; charset=UTF-8
Content-Length: 679


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\">


xsi:type=\"ns7437:ContestInfo\">

Hello, Willi. It is nice to meet a 22 year old male.

0





这个实例已经展示了如何发送一个 SOAP 结构参数和返回结果,它也展示了如何指定每个结构的 XML 类型。没有附加的工具,使用这些类型服务器端和客户端的交互遵守了这些结构的约定就可以进行高级的请求和交互。这是原生的 SOAP 1.1 规范的极大的自由之一,但是他也引起了交互的问题。这个系列的下一篇文章将会展示如何使用 WSDL 来为 web service 提供metadata ,也包括我们在使用的数据结构。

没有评论: