📄 server.php.svn-base
字号:
/* Call our header now! */ $header_method = $header_val->name; $header_data = array($this->_decode($header_val)); /* If there are parameters to pass. */ $hr =& $this->callMethod($header_method, $header_data); if (PEAR::isError($hr)) { $this->_raiseSoapDefault($hr); return null; } $results = $this->buildResult($hr, $this->return_type, $header_method, $header_val->namespace); $header_results[] = $results[0]; } } } } /* Handle the method call. */ /* Evaluate message, getting back a SOAP_Value object. */ $this->call_methodname = $this->methodname = $parser->root_struct_name[0]; /* Figure out the method namespace. */ $this->method_namespace = $parser->message[$parser->root_struct[0]]['namespace']; if ($this->_wsdl) { $this->_setSchemaVersion($this->_wsdl->xsd); $dataHandler = $this->_wsdl->getDataHandler($this->methodname, $this->method_namespace); if ($dataHandler) $this->call_methodname = $this->methodname = $dataHandler; $this->_portName = $this->_wsdl->getPortName($this->methodname); if (PEAR::isError($this->_portName)) { $this->_raiseSoapFault($this->_portName); return null; } $opData = $this->_wsdl->getOperationData($this->_portName, $this->methodname); if (PEAR::isError($opData)) { $this->_raiseSoapFault($opData); return null; } $this->__options['style'] = $opData['style']; $this->__options['use'] = $opData['output']['use']; $this->__options['parameters'] = $opData['parameters']; } /* Does method exist? */ if (!$this->methodname || !$this->validateMethod($this->methodname, $this->method_namespace)) { $this->_raiseSoapFault('method "' . $this->method_namespace . $this->methodname . '" not defined in service', '', '', 'Server'); return null; } if (!$request_val = $parser->getResponse()) { return null; } if (!is_a($request_val, 'SOAP_Value')) { $this->_raiseSoapFault('Parser did not return SOAP_Value object: ' . $request_val, '', '', 'Server'); return null; } /* Verify that SOAP_Value objects in request match the methods * signature. */ if (!$this->verifyMethod($request_val)) { /* verifyMethod() creates the fault. */ return null; } /* Need to set special error detection inside the value class to * differentiate between no params passed, and an error decoding. */ $request_data = $this->__decodeRequest($request_val); if (PEAR::isError($request_data)) { $this->_raiseSoapFault($request_data); return null; } $method_response =& $this->callMethod($this->call_methodname, $request_data); if (PEAR::isError($method_response)) { $this->_raiseSoapFault($method_response); return null; } if ($this->__options['parameters'] || !$method_response || $this->__options['style']=='rpc') { /* Get the method result. */ if (is_null($method_response)) { $return_val = null; } else { $return_val = $this->buildResult($method_response, $this->return_type); } $qn =& new QName($this->methodname . 'Response', $this->method_namespace); $methodValue =& new SOAP_Value($qn->fqn(), 'Struct', $return_val); } else { $methodValue =& $method_response; } return $this->_makeEnvelope($methodValue, $header_results, $this->response_encoding); } function &__decodeRequest($request, $shift = false) { if (!$request) { $decoded = null; return $decoded; } /* Check for valid response. */ if (PEAR::isError($request)) { $fault = &$this->_raiseSoapFault($request); return $fault; } else if (!is_a($request, 'SOAP_Value')) { $fault = &$this->_raiseSoapFault('Invalid data in server::__decodeRequest'); return $fault; } /* Decode to native php datatype. */ $requestArray = $this->_decode($request); /* Fault? */ if (PEAR::isError($requestArray)) { $fault = &$this->_raiseSoapFault($requestArray); return $fault; } if (is_object($requestArray) && get_class($requestArray) == 'stdClass') { $requestArray = get_object_vars($requestArray); } elseif ($this->__options['style'] == 'document') { $requestArray = array($requestArray); } if (is_array($requestArray)) { if (isset($requestArray['faultcode']) || isset($requestArray['SOAP-ENV:faultcode'])) { $faultcode = $faultstring = $faultdetail = $faultactor = ''; foreach ($requestArray as $k => $v) { if (stristr($k, 'faultcode')) { $faultcode = $v; } if (stristr($k, 'faultstring')) { $faultstring = $v; } if (stristr($k, 'detail')) { $faultdetail = $v; } if (stristr($k, 'faultactor')) { $faultactor = $v; } } $fault = &$this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); return $fault; } /* Return array of return values. */ if ($shift && count($requestArray) == 1) { $decoded = array_shift($requestArray); return $decoded; } return $requestArray; } return $requestArray; } function verifyMethod($request) { if (!$this->callValidation) { return true; } $params = $request->value; /* Get the dispatch map if one exists. */ $map = null; if (array_key_exists($this->methodname, $this->dispatch_map)) { $map = $this->dispatch_map[$this->methodname]; } elseif (isset($this->soapobject)) { if (method_exists($this->soapobject, '__dispatch')) { $map = $this->soapobject->__dispatch($this->methodname); } elseif (method_exists($this->soapobject, $this->methodname)) { /* No map, all public functions are SOAP functions. */ return true; } } if (!$map) { $this->_raiseSoapFault('SOAP request specified an unhandled method "' . $this->methodname . '"', '', '', 'Client'); return false; } /* If we aliased the SOAP method name to a PHP function, change * call_methodname so we do the right thing. */ if (array_key_exists('alias', $map) && !empty($map['alias'])) { $this->call_methodname = $map['alias']; } /* If there are input parameters required. */ if ($sig = $map['in']) { $this->input_value = count($sig); $this->return_type = false; if (is_array($map['out'])) { $this->return_type = count($map['out']) > 1 ? $map['out'] : array_shift($map['out']); } if (is_array($params)) { /* Validate the number of parameters. */ if (count($params) == count($sig)) { /* Make array of param types. */ foreach ($params as $param) { $p[] = strtolower($param->type); } $sig_t = array_values($sig); /* Validate each param's type. */ for ($i = 0; $i < count($p); $i++) { /* If SOAP types do not match, it's still fine if the * mapped php types match this allows using plain PHP * variables to work (i.e. stuff like Decimal would * fail otherwise). We consider this only error if the * types exist in our type maps, and they differ. */ if (strcasecmp($sig_t[$i], $p[$i]) != 0 && isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]]) && strcasecmp($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]], $this->_typemap[SOAP_XML_SCHEMA_VERSION][$p[$i]]) != 0) { $param = $params[$i]; $this->_raiseSoapFault("SOAP request contained mismatching parameters of name $param->name had type [{$p[$i]}], which did not match signature's type: [{$sig_t[$i]}], matched? " . (strcasecmp($sig_t[$i], $p[$i])), '', '', 'Client'); return false; } } return true; } else { /* Wrong number of params. */ $this->_raiseSoapFault('SOAP request contained incorrect number of parameters. method "' . $this->methodname . '" required ' . count($sig) . ' and request provided ' . count($params), '', '', 'Client'); return false; } } else { /* No params. */ $this->_raiseSoapFault('SOAP request contained incorrect number of parameters. method "' . $this->methodname . '" requires ' . count($sig) . ' parameters, and request provided none.', '', '', 'Client'); return false; } } /* We'll try it anyway. */ return true; } function validateMethod($methodname, $namespace = null) { unset($this->soapobject); if (!$this->callValidation) { return true; } /* No SOAP access to private functions. */ if ($methodname[0] == '_') { return false; } /* if it's in our function list, ok */ if (array_key_exists($methodname, $this->dispatch_map) && (!$namespace || !array_key_exists('namespace', $this->dispatch_map[$methodname]) || $namespace == $this->dispatch_map[$methodname]['namespace'])) { if (array_key_exists('namespace', $this->dispatch_map[$methodname])) $this->method_namespace = $this->dispatch_map[$methodname]['namespace']; return true; } /* if it's in an object, it's ok */ if (isset($this->dispatch_objects[$namespace])) { $c = count($this->dispatch_objects[$namespace]); for ($i = 0; $i < $c; $i++) { $obj =& $this->dispatch_objects[$namespace][$i]; /* If we have a dispatch map, and the function is not in the * dispatch map, then it is not callable! */ if (method_exists($obj, '__dispatch')) { if ($obj->__dispatch($methodname)) { $this->method_namespace = $namespace; $this->soapobject =& $obj; return true; } } elseif (method_exists($obj, $methodname)) { $this->method_namespace = $namespace; $this->soapobject =& $obj; return true; } } } return false; } function addObjectMap(&$obj, $namespace = null, $service_name = 'Default', $service_desc = '') { if (!$namespace) { if (isset($obj->namespace)) { // XXX a bit of backwards compatibility $namespace = $obj->namespace; } else { $this->_raiseSoapFault('No namespace provided for class!', '', '', 'Server'); return false; } } if (!isset($this->dispatch_objects[$namespace])) { $this->dispatch_objects[$namespace] = array(); } $this->dispatch_objects[$namespace][] =& $obj; // Create internal WSDL structures for object // XXX Because some internal workings of PEAR::SOAP decide whether to // do certain things by the presence or absence of _wsdl, we should // only create a _wsdl structure if we know we can fill it; if // __dispatch_map or __typedef for the object is missing, we should // avoid creating it. Later, when we are using PHP 5 introspection, we // will be able to make the data for all objects without any extra // information from the developers, and this condition should be // dropped. // XXX Known issue: if imported WSDL (bindWSDL) or another WSDL source // is used to add _wsdl structure information, then addObjectWSDL is // used, there is a high possibility of _wsdl data corruption; // therefore you should avoid using __dispatch_map/__typedef // definitions AND other WSDL data sources in the same service. We // exclude classes that don't have __typedefs to allow external WSDL // files to be used with classes with no internal type definitions // (the types are defined in the WSDL file). When addObjectWSDL is // refactored to not cause corruption, this restriction can be // relaxed. // In summary, if you add an object with both a dispatch map and type // definitions, then previous WSDL file operation and type definitions // will be overwritten. if (isset($obj->__dispatch_map) && isset($obj->__typedef)) { $this->addObjectWSDL($obj, $namespace, $service_name, $service_desc); } return true; } /** * Adds a method to the dispatch map. */ function addToMap($methodname, $in, $out, $namespace = null, $alias = null) { if (!function_exists($methodname)) { $this->_raiseSoapFault('Error mapping function', '', '', 'Server'); return false; } $this->dispatch_map[$methodname]['in'] = $in; $this->dispatch_map[$methodname]['out'] = $out; $this->dispatch_map[$methodname]['alias'] = $alias; if ($namespace) { $this->dispatch_map[$methodname]['namespace'] = $namespace; } return true; } function setCallHandler($callHandler, $validation = true) { $this->callHandler = $callHandler; $this->callValidation = $validation; } /** * @deprecated use bindWSDL from now on */ function bind($wsdl_url) { $this->bindWSDL($wsdl_url); } /** * @param string a url to a WSDL resource * @return void */ function bindWSDL($wsdl_url) { /* Instantiate WSDL class. */ $this->_wsdl =& new SOAP_WSDL($wsdl_url); if ($this->_wsdl->fault) { $this->_raiseSoapFault($this->_wsdl->fault); } } /** * @return void */ function addObjectWSDL(&$wsdl_obj, $targetNamespace, $service_name, $service_desc = '') { if (!isset($this->_wsdl)) { $this->_wsdl =& new SOAP_WSDL; } $this->_wsdl->parseObject($wsdl_obj, $targetNamespace, $service_name, $service_desc); if ($this->_wsdl->fault) { $this->_raiseSoapFault($this->_wsdl->fault); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -