📄 nusoap.php
字号:
function setEncoding($enc='gzip, deflate'){
$this->encoding = $enc;
$this->protocol_version = '1.1';
}
/**
* set proxy info here
*
* @param string $proxyhost
* @param string $proxyport
* @access public
*/
function setProxy($proxyhost, $proxyport) {
$this->proxyhost = $proxyhost;
$this->proxyport = $proxyport;
}
/**
* decode a string that is encoded w/ "chunked' transfer encoding
* as defined in RFC2068 19.4.6
*
* @param string $buffer
* @returns string
* @access public
*/
function decodeChunked($buffer){
// length := 0
$length = 0;
$new = '';
// read chunk-size, chunk-extension (if any) and CRLF
// get the position of the linebreak
$chunkend = strpos($buffer,"\r\n") + 2;
$temp = substr($buffer,0,$chunkend);
$chunk_size = hexdec( trim($temp) );
$chunkstart = $chunkend;
// while (chunk-size > 0) {
while ($chunk_size > 0) {
$chunkend = strpos( $buffer, "\r\n", $chunkstart + $chunk_size);
// Just in case we got a broken connection
if ($chunkend == FALSE) {
$chunk = substr($buffer,$chunkstart);
// append chunk-data to entity-body
$new .= $chunk;
$length += strlen($chunk);
break;
}
// read chunk-data and CRLF
$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
// append chunk-data to entity-body
$new .= $chunk;
// length := length + chunk-size
$length += strlen($chunk);
// read chunk-size and CRLF
$chunkstart = $chunkend + 2;
$chunkend = strpos($buffer,"\r\n",$chunkstart)+2;
if ($chunkend == FALSE) {
break; //Just in case we got a broken connection
}
$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
$chunk_size = hexdec( trim($temp) );
$chunkstart = $chunkend;
}
// Update headers
//$this->Header['content-length'] = $length;
//unset($this->Header['transfer-encoding']);
return $new;
}
}
?><?php
/**
*
* soap_server allows the user to create a SOAP server
* that is capable of receiving messages and returning responses
*
* NOTE: WSDL functionality is experimental
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @version v 0.6.3
* @access public
*/
class soap_server extends nusoap_base {
var $service = ''; // service name
var $operations = array(); // assoc array of operations => opData
var $responseHeaders = false;
var $headers = '';
var $request = '';
var $charset_encoding = 'UTF-8';
var $fault = false;
var $result = 'successful';
var $wsdl = false;
var $externalWSDLURL = false;
var $debug_flag = true;
/**
* constructor
* the optional parameter is a path to a WSDL file that you'd like to bind the server instance to.
*
* @param string $wsdl path or URL to a WSDL file
* @access public
*/
function soap_server($wsdl=false){
// turn on debugging?
global $debug;
if(isset($debug)){
$this->debug_flag = 1;
}
// wsdl
if($wsdl){
$this->wsdl = new wsdl($wsdl);
$this->externalWSDLURL = $wsdl;
if($err = $this->wsdl->getError()){
die('WSDL ERROR: '.$err);
}
}
}
/**
* processes request and returns response
*
* @param string $data usually is the value of $HTTP_RAW_POST_DATA
* @access public
*/
function service($data){
// print wsdl
global $QUERY_STRING;
if(isset($_SERVER['QUERY_STRING'])){
$qs = $_SERVER['QUERY_STRING'];
} elseif(isset($GLOBALS['QUERY_STRING'])){
$qs = $GLOBALS['QUERY_STRING'];
} elseif(isset($QUERY_STRING) && $QUERY_STRING != ''){
$qs = $QUERY_STRING;
}
// gen wsdl
if(isset($qs) && ereg('wsdl', $qs) ){
if($this->externalWSDLURL){
header('Location: '.$this->externalWSDLURL);
exit();
} else {
header("Content-Type: text/xml\r\n");
print $this->wsdl->serialize();
exit();
}
}
// print web interface
if($data == '' && $this->wsdl){
print $this->webDescription();
} else {
// $response is the serialized response message
$response = $this->parse_request($data);
$this->debug('server sending...');
$payload = $response;
// add debug data if in debug mode
if(isset($this->debug_flag) && $this->debug_flag == 1){
$payload .= "<!--\n".str_replace('--','- -',$this->debug_str)."\n-->";
}
// print headers
if($this->fault){
$header[] = "HTTP/1.0 500 Internal Server Error\r\n";
$header[] = "Status: 500 Internal Server Error\r\n";
} else {
$header[] = "Status: 200 OK\r\n";
}
$header[] = "Server: $this->title Server v$this->version\r\n";
$header[] = "Connection: Close\r\n";
$header[] = "Content-Type: text/xml; charset=$this->charset_encoding\r\n";
$header[] = "Content-Length: ".strlen($payload)."\r\n\r\n";
reset($header);
foreach($header as $hdr){
header($hdr);
}
$this->response = join("\r\n",$header).$payload;
print $payload;
}
}
/**
* parses request and posts response
*
* @param string $data XML string
* @return string XML response msg
* @access private
*/
function parse_request($data='') {
$this->debug('entering parseRequest() on '.date('H:i Y-m-d'));
$dump = '';
// get headers
if(function_exists('getallheaders')){
$this->headers = getallheaders();
foreach($this->headers as $k=>$v){
$dump .= "$k: $v\r\n";
$this->debug("$k: $v");
}
// get SOAPAction header
if(isset($this->headers['SOAPAction'])){
$this->SOAPAction = str_replace('"','',$this->headers['SOAPAction']);
}
// get the character encoding of the incoming request
if(strpos($this->headers['Content-Type'],'=')){
$enc = str_replace('"','',substr(strstr($this->headers["Content-Type"],'='),1));
if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
$this->xml_encoding = $enc;
} else {
$this->xml_encoding = 'us-ascii';
}
}
$this->debug('got encoding: '.$this->charset_encoding);
} elseif(is_array($_SERVER)){
$this->headers['User-Agent'] = $_SERVER['HTTP_USER_AGENT'];
$this->SOAPAction = isset($_SERVER['SOAPAction']) ? $_SERVER['SOAPAction'] : '';
}
$this->request = $dump."\r\n\r\n".$data;
// parse response, get soap parser obj
$parser = new soap_parser($data,$this->charset_encoding);
// if fault occurred during message parsing
if($err = $parser->getError()){
// parser debug
$this->debug("parser debug: \n".$parser->debug_str);
$this->result = 'fault: error in msg parsing: '.$err;
$this->fault('Server',"error in msg parsing:\n".$err);
// return soapresp
return $this->fault->serialize();
// else successfully parsed request into soapval object
} else {
// get/set methodname
$this->methodname = $parser->root_struct_name;
$this->debug('method name: '.$this->methodname);
// does method exist?
if(!function_exists($this->methodname)){
// "method not found" fault here
$this->debug("method '$this->methodname' not found!");
$this->debug("parser debug: \n".$parser->debug_str);
$this->result = 'fault: method not found';
$this->fault('Server',"method '$this->methodname' not defined in service '$this->service'");
return $this->fault->serialize();
}
if($this->wsdl){
if(!$this->opData = $this->wsdl->getOperationData($this->methodname)){
//if(
$this->fault('Server',"Operation '$this->methodname' is not defined in the WSDL for this service");
return $this->fault->serialize();
}
}
$this->debug("method '$this->methodname' exists");
// evaluate message, getting back parameters
$this->debug('calling parser->get_response()');
$request_data = $parser->get_response();
// parser debug
$this->debug("parser debug: \n".$parser->debug_str);
// verify that request parameters match the method's signature
if($this->verify_method($this->methodname,$request_data)){
// if there are parameters to pass
$this->debug('params var dump '.$this->varDump($request_data));
if($request_data){
$this->debug("calling '$this->methodname' with params");
if (! function_exists('call_user_func_array')) {
$this->debug('calling method using eval()');
$funcCall = $this->methodname.'(';
foreach($request_data as $param) {
$funcCall .= "\"$param\",";
}
$funcCall = substr($funcCall, 0, -1).')';
$this->debug('function call:<br>'.$funcCall);
@eval("\$method_response = $funcCall;");
} else {
$this->debug('calling method using call_user_func_array()');
$method_response = call_user_func_array("$this->methodname",$request_data);
}
$this->debug('response var dump'.$this->varDump($method_response));
} else {
// call method w/ no parameters
$this->debug("calling $this->methodname w/ no params");
$m = $this->methodname;
$method_response = @$m();
}
$this->debug("done calling method: $this->methodname, received $method_response of type".gettype($method_response));
// if we got nothing back. this might be ok (echoVoid)
if(isset($method_response) && $method_response != '' || is_bool($method_response)) {
// if fault
if(get_class($method_response) == 'soap_fault'){
$this->debug('got a fault object from method');
$this->fault = $method_response;
return $method_response->serialize();
// if return val is soapval object
} elseif(get_class($method_response) == 'soapval'){
$this->debug('got a soapval object from method');
$return_val = $method_response->serialize();
// returned other
} else {
$this->debug('got a(n) '.gettype($method_response).' from method');
$this->debug('serializing return value');
if($this->wsdl){
// weak attempt at supporting multiple output params
if(sizeof($this->opData['output']['parts']) > 1){
$opParams = $method_response;
} else {
$opParams = array($method_response);
}
$return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
} else {
$return_val = $this->serialize_val($method_response);
}
}
$this->debug('return val:'.$this->varDump($return_val));
} else {
$return_val = '';
$this->debug('got no response from method');
}
$this->debug('serializing response');
$payload = '<'.$this->methodname."Response>".$return_val.'</'.$this->methodname."Response>";
$this->result = 'successful';
if($this->wsdl){
//if($this->debug_flag){
$this->debug("WSDL debug data:\n".$this->wsdl->debug_str);
// }
// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
return $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style']);
} else {
return $this->serializeEnvelope($payload,$this->responseHeaders);
}
} else {
// debug
$this->debug('ERROR: request not verified against method signature');
$this->result = 'fault: request failed validation against method signature';
// return fault
$this->fault('Server',"Operation '$this->methodname' not defined in service.");
return $this->fault->serialize();
}
}
}
/**
* takes the value that was created by parsing the request
* and compares to the method's signature, if available.
*
* @param mixed
* @return boolean
* @access private
*/
function verify_method($operation,$request){
if(isset($this->wsdl) && is_object($this->wsdl)){
if($this->wsdl->getOperationData($operation)){
return true;
}
} elseif(isset($this->operations[$operation])){
return true;
}
return false;
}
/**
* add a method to the dispatch map
*
* @param string $methodname
* @param string $in array of input values
* @param string $out array of output values
* @access public
*/
function add_to_map($methodname,$in,$out){
$this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
}
/**
* register a service with the server
*
* @param string $methodname
* @param string $in assoc array of input values: key = param name, value = param type
* @param string $out assoc array of output values: key = param name, value = param type
* @param string $namespace
* @param string $soapaction
* @param string $style (rpc|literal)
* @access public
*/
function register($name,$in=false,$out=false,$namespace=false,$soapaction=false,$style=false,$use=false){
if($this->externalWSDLURL){
die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
}
if(false == $in) {
}
if(false == $out) {
}
if(false == $namespace) {
}
if(false == $soapaction) {
global $SERVER_NAME, $SCRIPT_NAME;
$soapaction = "http://$SERVER_NAME$SCRIPT_NAME";
}
if(false == $style) {
$style = "rpc";
}
if(false == $use) {
$use = "encoded";
}
$this->operations[$name] = array(
'name' => $name,
'in' => $in,
'out' => $out,
'namespace' => $namespace,
'soapaction' => $soapaction,
'style' => $style);
if($this->wsdl){
$this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use);
}
return true;
}
/**
* create a fault. this also acts as a flag to the server that a fau
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -