Soap Web Service using PHP
http://www.datanom.net/foredrag/php/soap/server/Servers-lecture.pdf
TOC
● Necessary steps when constructing a simple server
● Example server
● Error handling
● Returning the WSDL to clients
● Necessary steps when constructing a complex server
● Mapping complex types
● Example server
● Concluding remarks
3. Add this class to the server: $server->setClass(“class”);
4. Activate the server: $server->handle()
WSDL
xmlns:tns='urn:SayHello' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/' xmlns='http://schemas.xmlsoap.org/wsdl/'>
TOC
● Necessary steps when constructing a simple server
● Example server
● Error handling
● Returning the WSDL to clients
● Necessary steps when constructing a complex server
● Mapping complex types
● Example server
● Concluding remarks
Necessary steps when constructing a simple server
1. Write the WSDL
2. Write the service class
1. Write the WSDL
2. Write the service class
4. Activate the server: $server->handle()
WSDL
xmlns:tns='urn:SayHello' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/' xmlns='http://schemas.xmlsoap.org/wsdl/'>
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
Service Class
class SayHello {
public function getHello($inmessage) {
return "Hello $inmessage!"; }
} //end class
ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer("SayHello.wsdl");
$server->setClass("SayHello"); $server->handle();
?>
public function getHello($inmessage) {
return "Hello $inmessage!"; }
} //end class
ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer("SayHello.wsdl");
$server->setClass("SayHello"); $server->handle();
?>
Error handling
$faultcode = 'The actor coursing the fault [client | server | intermediary]';
$faultstring = 'Some human readable text';
$faultactor = 'The namespace';
$detail = 'Some machine readable text.';
throw new SoapFault( $faultstring, $faultcode, $faultactor, $detail);
} else {Some other non-related SOAP error}
}
$faultcode = 'The actor coursing the fault [client | server | intermediary]';
$faultstring = 'Some human readable text';
$faultactor = 'The namespace';
$detail = 'Some machine readable text.';
throw new SoapFault( $faultstring, $faultcode, $faultactor, $detail);
Returning the WSDL
if (isset($_SERVER['REQUEST_METHOD']) &&
$_SERVER['REQUEST_METHOD']=='POST') {
$soapserver->handle();
} else {
$soapserver->handle();
} else {
if (isset($_SERVER['QUERY_STRING']) &&
strcasecmp($_SERVER['QUERY_STRING'],'wsdl') == 0) { // Return the WSDL
$wsdl = @implode ('', @file ('some.wsdl'));
if (strlen($wsdl) > 1) {
header("Content-type: text/xml");
echo $wsdl;
} else {
header("Status: 500 Internal Server Error"); header("Content-type: text/plain");
echo "HTTP/1.0 500 Internal Server Error";
}
strcasecmp($_SERVER['QUERY_STRING'],'wsdl') == 0) { // Return the WSDL
$wsdl = @implode ('', @file ('some.wsdl'));
if (strlen($wsdl) > 1) {
header("Content-type: text/xml");
echo $wsdl;
} else {
header("Status: 500 Internal Server Error"); header("Content-type: text/plain");
echo "HTTP/1.0 500 Internal Server Error";
}
}
Necessary steps when constructing a complex server
1. Write the WSDL for the service
2. Map complex types from WSDL
3. Write the service class
4. Add this class to the server: $server->setClass(“class”);
5. Activate the server: $server->handle()
1. Write the WSDL for the service
2. Map complex types from WSDL
3. Write the service class
4. Add this class to the server: $server->setClass(“class”);
5. Activate the server: $server->handle()
The WSDL
targetNamespace="urn:HostInfo">
Map complex types
● Create an associative array for each complex type
● Use the class SoapParam to convert the array to the soap type specified in the WSDL: //SoapParam(mixed data, 'type name from WSDL')
$HostInfo = array(
'hostname' => “”,
'ip' => “”, 'port' => “”,
'datetime' => “”,
'PHP_version' => “”
);
return new SoapParam ( $HostInfo, 'hostInfo');
● Create an associative array for each complex type
● Use the class SoapParam to convert the array to the soap type specified in the WSDL: //SoapParam(mixed data, 'type name from WSDL')
$HostInfo = array(
'hostname' => “”,
'ip' => “”, 'port' => “”,
'datetime' => “”,
'PHP_version' => “”
);
return new SoapParam ( $HostInfo, 'hostInfo');
Service class
class HostInfo {
public function getHostInfo() {
$response = array(
'hostname' => $_SERVER['SERVER_NAME'],
'ip' => $_SERVER['SERVER_ADDR'],
'port' => $_SERVER['SERVER_PORT'],
'datetime' => date("l dS of F Y H:i:s T"),
'PHP_version' => PHP_VERSION
);
return new SoapParam ( $response, 'hostInfo');
}
}
class HostInfo {
public function getHostInfo() {
$response = array(
'hostname' => $_SERVER['SERVER_NAME'],
'ip' => $_SERVER['SERVER_ADDR'],
'port' => $_SERVER['SERVER_PORT'],
'datetime' => date("l dS of F Y H:i:s T"),
'PHP_version' => PHP_VERSION
);
return new SoapParam ( $response, 'hostInfo');
}
}
Add class to server and activate server
ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer("HostInfo.wsdl");
$server->setClass("HostInfo");
if (isset($_SERVER['REQUEST_METHOD']) &&
$_SERVER['REQUEST_METHOD']=='POST') {
$server->handle();
} else { $wsdl = @implode ('', @file ('HostInfo.wsdl'));
if (strlen($wsdl) > 1) {
header("Content-type: text/xml");
echo $wsdl;
}
}
@: suppresses error and warnings
ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer("HostInfo.wsdl");
$server->setClass("HostInfo");
if (isset($_SERVER['REQUEST_METHOD']) &&
$_SERVER['REQUEST_METHOD']=='POST') {
$server->handle();
} else { $wsdl = @implode ('', @file ('HostInfo.wsdl'));
if (strlen($wsdl) > 1) {
header("Content-type: text/xml");
echo $wsdl;
}
}
@: suppresses error and warnings
Concluding remarks
● All input parameters will be of type stdObject
● Output of any kind is not permitted
● Always provide WSDL for clients
● Input and output are passed in clear text – XML
● If security is an issue use HTTPS – requires the curl module in PHP
● Encryption is not a part of the standard yet, but work is in progress
● Always use SoapParam to return complex types
● Provide a class for each usecase – simplifies debugging and gives higher maintainability
● All input parameters will be of type stdObject
● Output of any kind is not permitted
● Always provide WSDL for clients
● Input and output are passed in clear text – XML
● If security is an issue use HTTPS – requires the curl module in PHP
● Encryption is not a part of the standard yet, but work is in progress
● Always use SoapParam to return complex types
● Provide a class for each usecase – simplifies debugging and gives higher maintainability
评论