SOAP--Client
[ class tree: SOAP--Client ] [ index: SOAP--Client ] [ all elements ]

Source for file Server.php

Documentation is available at Server.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Shane Caraveo <Shane@Caraveo.com>   Port to PEAR and more   |
  17. // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author         |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Server.php,v 1.44.2.3 2004/08/22 19:59:50 arnaud Exp $
  21. //
  22.  
  23. require_once 'SOAP/Base.php';
  24. require_once 'SOAP/Fault.php';
  25. require_once 'SOAP/Parser.php';
  26. require_once 'SOAP/Value.php';
  27. require_once 'SOAP/WSDL.php';
  28.  
  29. $soap_server_fault = null;
  30. function SOAP_ServerErrorHandler($errno$errmsg$filename$linenum$vars{
  31.     // the error handler should ignore '0' errors, eg. hidden by @ - see the
  32.     // set_error_handler manual page.. (thanks to Alan Knowles)
  33.  
  34.     if (!$errno || $errno == E_NOTICE{
  35.         return;
  36.     }
  37.  
  38.     global $soap_server_fault;
  39.     $detail = "Errno: $errno\nFilename: $filename\nLineno: $linenum\n";
  40.     // XXX very strange behaviour with error handling if we =& here.
  41.     $soap_server_fault = new SOAP_Fault($errmsg'Server''PHP'$detail);
  42. }
  43.  
  44. /**
  45.  *  SOAP::Server
  46.  * SOAP Server Class
  47.  *
  48.  * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4
  49.  *
  50.  * @access   public
  51.  * @version  $Id: Server.php,v 1.44.2.3 2004/08/22 19:59:50 arnaud Exp $
  52.  * @package  SOAP::Client
  53.  * @author   Shane Caraveo <shane@php.net> Conversion to PEAR and updates
  54.  * @author   Dietrich Ayala <dietrich@ganx4.com> Original Author
  55.  */
  56. class SOAP_Server extends SOAP_Base
  57. {
  58.     /**
  59.      *
  60.      * @var  array 
  61.      */
  62.     var $dispatch_map = array()// create empty dispatch map
  63.     var $dispatch_objects = array();
  64.     var $soapobject = NULL;
  65.     var $call_methodname = NULL;
  66.     var $callHandler = NULL;
  67.     var $callValidation = true;
  68.  
  69.     /**
  70.      *
  71.      * @var  string 
  72.      */
  73.     var $headers = '';
  74.  
  75.     /**
  76.      *
  77.      * @var  string 
  78.      */
  79.     var $request = '';
  80.  
  81.     /**
  82.      *
  83.      * @var  string  XML-Encoding
  84.      */
  85.     var $xml_encoding = SOAP_DEFAULT_ENCODING;
  86.     var $response_encoding = 'UTF-8';
  87.  
  88.     var $result = 'successful'// for logging interop results to db
  89.  
  90.     var $endpoint = ''// the uri to ME!
  91.  
  92.     var $service = ''//soapaction header
  93.     var $method_namespace = NULL;
  94.     var $__options = array('use'=>'encoded','style'=>'rpc','parameters'=>0);
  95.  
  96.     function SOAP_Server($options=NULL{
  97.         ini_set('track_errors',1);
  98.         parent::SOAP_Base('Server');
  99.         if (is_array($options)) {
  100.             if (isset($options['use']))
  101.                 $this->__options['use'$options['use'];
  102.             if (isset($options['style']))
  103.                 $this->__options['style'$options['style'];
  104.             if (isset($options['parameters']))
  105.                 $this->__options['parameters'$options['parameters'];
  106.         }
  107.         $this->_section5 = TRUE; // assume we encode with section 5
  108.         if ($this->__options['use']=='literal'$this->_section5 = FALSE;
  109.     }
  110.  
  111.     function _getContentEncoding($content_type)
  112.     {
  113.         // get the character encoding of the incoming request
  114.         // treat incoming data as UTF-8 if no encoding set
  115.         $this->xml_encoding = 'UTF-8';
  116.         if (strpos($content_type,'=')) {
  117.             $enc strtoupper(str_replace('"',"",substr(strstr($content_type,'='),1)));
  118.             if (!in_array($enc$this->_encodings)) {
  119.                 return FALSE;
  120.             }
  121.             $this->xml_encoding = $enc;
  122.         }
  123.         return TRUE;
  124.     }
  125.  
  126.  
  127.     // parses request and posts response
  128.     function service($data$endpoint ''$test = FALSE)
  129.     {
  130.         $response = NULL;
  131.         $attachments = array();
  132.         $headers = array();
  133.         $useEncoding 'DIME';
  134.         // figure out our endpoint
  135.         $this->endpoint = $endpoint;
  136.         if (!$test && !$this->endpoint{
  137.             // we'll try to build our endpoint
  138.             $this->endpoint = 'http://'.$_SERVER['SERVER_NAME'];
  139.             if ($_SERVER['SERVER_PORT']$this->endpoint .= ':'.$_SERVER['SERVER_PORT'];
  140.             $this->endpoint .= $_SERVER['SCRIPT_NAME'];
  141.         }
  142.  
  143.         // get the character encoding of the incoming request
  144.         // treat incoming data as UTF-8 if no encoding set
  145.         if (isset($_SERVER['CONTENT_TYPE'])) {
  146.             if (strcasecmp($_SERVER['CONTENT_TYPE'],'application/dime')==0{
  147.                 $this->_decodeDIMEMessage($data,$headers,$attachments);
  148.                 $useEncoding 'DIME';
  149.             else if (stristr($_SERVER['CONTENT_TYPE'],'multipart/related')) {
  150.                 // this is a mime message, lets decode it.
  151.                 $data 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data;
  152.                 $this->_decodeMimeMessage($data,$headers,$attachments);
  153.                 $useEncoding 'Mime';
  154.             }
  155.             if (!isset($headers['content-type'])) {
  156.                 $headers['content-type'stripslashes($_SERVER['CONTENT_TYPE']);
  157.             }
  158.             if (!$this->fault &&
  159.                 !$this->_getContentEncoding($headers['content-type'])) {
  160.                 $this->xml_encoding = SOAP_DEFAULT_ENCODING;
  161.                 // an encoding we don't understand, return a fault
  162.                 $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server');
  163.             }
  164.         }
  165.  
  166.         // if this is not a POST with Content-Type text/xml, try to return a WSDL file
  167.         if (!$this->fault  && !$test && ($_SERVER['REQUEST_METHOD'!= 'POST' ||
  168.             strncmp($headers['content-type'],'text/xml',8!= 0)) {
  169.                 // this is not possibly a valid soap request, try to return a WSDL file
  170.                 $this->_raiseSoapFault("Invalid SOAP request, must be POST with content-type: text/xml, got: ".(isset($headers['content-type'])?$headers['content-type']:'Nothing!'),'','','Server');
  171.         }
  172.  
  173.         if (!$this->fault{
  174.             // $response is a soap_msg object
  175.             $soap_msg $this->parseRequest($data$attachments);
  176.  
  177.             // handle Mime or DIME encoding
  178.             // XXX DIME Encoding should move to the transport, do it here for now
  179.             // and for ease of getting it done
  180.             if (count($this->__attachments)) {
  181.                 if ($useEncoding == 'Mime'{
  182.                     $soap_msg $this->_makeMimeMessage($soap_msg);
  183.                 else {
  184.                     // default is dime
  185.                     $soap_msg $this->_makeDIMEMessage($soap_msg);
  186.                     $header['Content-Type''application/dime';
  187.                 }
  188.                 if (PEAR::isError($soap_msg)) {
  189.                     return $this->raiseSoapFault($soap_msg);
  190.                 }
  191.             }
  192.  
  193.             if (is_array($soap_msg)) {
  194.                 $response $soap_msg['body'];
  195.                 if (count($soap_msg['headers'])) {
  196.                     $header $soap_msg['headers'];
  197.                 }
  198.             else {
  199.                 $response $soap_msg;
  200.             }
  201.         }
  202.  
  203.         // make distinction between the different choice of installation,
  204.         // running php as cgi or as a module
  205.         if(stristr(php_sapi_name(),'cgi'=== 0)
  206.             $hdrs_type 'Status:';
  207.         else
  208.             $hdrs_type 'HTTP/1.1';
  209.  
  210.         if ($this->fault{
  211.             $hdrs = "$hdrs_type 500 Soap Fault\r\n";
  212.             $response $this->fault->message();
  213.         else {
  214.            $hdrs = "$hdrs_type 200 OK\r\n";
  215.         }
  216.         header($hdrs);
  217.  
  218.         $header['Server'SOAP_LIBRARY_NAME;
  219.         if (!isset($header['Content-Type']))
  220.             $header['Content-Type'= "text/xml; charset=$this->response_encoding";
  221.         $header['Content-Length'strlen($response);
  222.  
  223.         reset($header);
  224.         foreach ($header as $k => $v{
  225.             header("$k$v");
  226.             $hdrs .= "$k$v\r\n";
  227.         }
  228.  
  229.         $this->response $hdrs "\r\n" $response;
  230.         print $response;
  231.     }
  232.  
  233.     function &callMethod($methodname&$args{
  234.         global $soap_server_fault;
  235.         $soap_server_fault = null;
  236.  
  237.         if ($this->callHandler{
  238.             return @call_user_func_array($this->callHandler,array($methodname,$args));
  239.         }
  240.  
  241.         set_error_handler('SOAP_ServerErrorHandler');
  242.  
  243.         if ($args{
  244.             // call method with parameters
  245.             if (isset($this->soapobject&& is_object($this->soapobject)) {
  246.                 $ret @call_user_func_array(array(&$this->soapobject$methodname),$args);
  247.             else {
  248.                 $ret @call_user_func_array($methodname,$args);
  249.             }
  250.         else {
  251.             // call method w/ no parameters
  252.             if (is_object($this->soapobject)) {
  253.                 $ret @call_user_func(array(&$this->soapobject$methodname));
  254.             else {
  255.                 $ret @call_user_func($methodname);
  256.             }
  257.         }
  258.  
  259.         restore_error_handler();
  260.  
  261.         return is_null($soap_server_fault$ret $soap_server_fault;
  262.     }
  263.  
  264.     // create soap_val object w/ return values from method, use method signature to determine type
  265.     function buildResult(&$method_response&$return_type$return_name='return'$namespace '')
  266.     {
  267.         if (gettype($method_response== 'object' && is_a($method_response,'soap_value')) {
  268.             $return_val = array($method_response);
  269.         else {
  270.             if (is_array($return_type&& is_array($method_response)) {
  271.                 $i = 0;
  272.  
  273.                 foreach ($return_type as $key => $type{
  274.                     if (is_numeric($key)) $key 'item';
  275.                     if (is_a($method_response[$i],'soap_value')) {
  276.                         $return_val[$method_response[$i++];
  277.                     else {
  278.                         $qn =new QName($key$namespace);
  279.                         $return_val[=new SOAP_Value($qn->fqn(),$type,$method_response[$i++]);
  280.                     }
  281.                 }
  282.             else {
  283.                 if (is_array($return_type)) {
  284.                     $keys array_keys($return_type);
  285.                     if (!is_numeric($keys[0])) $return_name $keys[0];
  286.                     $values array_values($return_type);
  287.                     $return_type $values[0];
  288.                 }
  289.                 $qn =new QName($return_name$namespace);
  290.                 $return_val = array();
  291.                 $return_val[=new SOAP_Value($qn->fqn(),$return_type,$method_response);
  292.             }
  293.         }
  294.         return $return_val;
  295.     }
  296.  
  297.     function parseRequest($data ''$attachments = null)
  298.     {
  299.         // parse response, get soap parser obj
  300.         $parser =new SOAP_Parser($data,$this->xml_encoding,$attachments);
  301.         // if fault occurred during message parsing
  302.         if ($parser->fault{
  303.             $this->fault = $parser->fault;
  304.             return null;
  305.         }
  306.  
  307.         //*******************************************************
  308.         // handle message headers
  309.  
  310.         $request_headers $parser->getHeaders();
  311.         $header_results = array();
  312.  
  313.         if ($request_headers{
  314.             if (!is_a($request_headers,'soap_value')) {
  315.                 $this->_raiseSoapFault("parser did not return SOAP_Value object: $request_headers",'','','Server');
  316.                 return null;
  317.             }
  318.             if ($request_headers->value{
  319.             // handle headers now
  320.             foreach ($request_headers->value as $header_val{
  321.                 $f_exists $this->validateMethod($header_val->name$header_val->namespace);
  322.  
  323.                 # XXX this does not take into account message routing yet
  324.                 $myactor (
  325.                     !$header_val->actor ||
  326.                     $header_val->actor == 'http://schemas.xmlsoap.org/soap/actor/next' ||
  327.                     $header_val->actor == $this->endpoint);
  328.  
  329.                 if (!$f_exists && $header_val->mustunderstand && $myactor{
  330.                     $this->_raiseSoapFault("I don't understand header $header_val->name.",'','','MustUnderstand');
  331.                     return null;
  332.                 }
  333.  
  334.                 // we only handle the header if it's for us
  335.                 $isok $f_exists && $myactor;
  336.  
  337.                 if ($isok{
  338.                     # call our header now!
  339.                     $header_method $header_val->name;
  340.                     $header_data = array($this->_decode($header_val));
  341.                     // if there are parameters to pass
  342.                     $hr =$this->callMethod($header_method$header_data);
  343.                     # if they return a fault, then it's all over!
  344.                     if (PEAR::isError($hr)) {
  345.                         $this->_raiseSoapFault($hr);
  346.                         return null;
  347.                     }
  348.                     $header_results[array_shift($this->buildResult($hr$this->return_type$header_method$header_val->namespace));
  349.                 }
  350.             }
  351.             }
  352.         }
  353.  
  354.         //*******************************************************
  355.         // handle the method call
  356.  
  357.         // evaluate message, getting back a SOAP_Value object
  358.         $this->call_methodname = $this->methodname $parser->root_struct_name[0];
  359.  
  360.         // figure out the method_namespace
  361.         $this->method_namespace = $parser->message[$parser->root_struct[0]]['namespace'];
  362.  
  363.         if ($this->_wsdl{
  364.             $this->_setSchemaVersion($this->_wsdl->xsd);
  365.             $dataHandler $this->_wsdl->getDataHandler($this->methodname,$this->method_namespace);
  366.             if ($dataHandler)
  367.                 $this->call_methodname = $this->methodname $dataHandler;
  368.  
  369.             $this->_portName $this->_wsdl->getPortName($this->methodname);
  370.             if (PEAR::isError($this->_portName)) {
  371.                 return $this->_raiseSoapFault($this->_portName);
  372.             }
  373.             $opData $this->_wsdl->getOperationData($this->_portName$this->methodname);
  374.             if (PEAR::isError($opData)) {
  375.                 return $this->_raiseSoapFault($opData);
  376.             }
  377.             $this->__options['style'$opData['style'];
  378.             $this->__options['use'$opData['output']['use'];
  379.             $this->__options['parameters'$opData['parameters'];
  380.         }
  381.  
  382.         // does method exist?
  383.         if (!$this->methodname || !$this->validateMethod($this->methodname,$this->method_namespace)) {
  384.             $this->_raiseSoapFault("method '{{$this->method_namespace}}$this->methodname' not defined in service",'','','Server');
  385.             return NULL;
  386.         }
  387.  
  388.         if (!$request_val = $parser->getResponse()) {
  389.             return NULL;
  390.         }
  391.         if (!is_a($request_val,'soap_value')) {
  392.             $this->_raiseSoapFault("parser did not return SOAP_Value object: $request_val",'','','Server');
  393.             return NULL;
  394.         }
  395.  
  396.         // verify that SOAP_Value objects in request match the methods signature
  397.         if (!$this->verifyMethod($request_val)) {
  398.             // verifyMethod creates the fault
  399.             return NULL;
  400.         }
  401.  
  402.         // need to set special error detection inside the value class
  403.         // so as to differentiate between no params passed, and an error decoding
  404.         $request_data = $this->__decodeRequest($request_val);
  405.         if (PEAR::isError($request_data)) {
  406.             return $this->_raiseSoapFault($request_data);
  407.         }
  408.         $method_response =& $this->callMethod($this->call_methodname$request_data);
  409.  
  410.         if (PEAR::isError($method_response)) {
  411.             $this->_raiseSoapFault($method_response);
  412.             return null;
  413.         }
  414.  
  415.         if ($this->__options['parameters'|| !$method_response || $this->__options['style']=='rpc'{
  416.             // get the method result
  417.             if (is_null($method_response))
  418.                 $return_val = NULL;
  419.             else
  420.                 $return_val = $this->buildResult($method_response$this->return_type);
  421.  
  422.             $qn =new QName($this->methodname.'Response',$this->method_namespace);
  423.             $methodValue =new SOAP_Value($qn->fqn()'Struct'$return_val);
  424.         } else {
  425.             $methodValue =& $method_response;
  426.         }
  427.         return $this->_makeEnvelope($methodValue$header_results$this->response_encoding);
  428.     }
  429.  
  430.     function &__decodeRequest($request,$shift=false)
  431.     {
  432.         if (!$request) return NULL;
  433.         // check for valid response
  434.         if (PEAR::isError($request)) {
  435.             return $this->_raiseSoapFault($request);
  436.         } else if (!is_a($request,'soap_value')) {
  437.             return $this->_raiseSoapFault("Invalid data in server::__decodeRequest");
  438.         }
  439.  
  440.         // decode to native php datatype
  441.         $requestArray = $this->_decode($request);
  442.         // fault?
  443.         if (PEAR::isError($requestArray)) {
  444.             return $this->_raiseSoapFault($requestArray);
  445.         }
  446.         if (is_object($requestArray)&& get_class($requestArray) == 'stdClass') {
  447.                 $requestArray = get_object_vars($requestArray);
  448.         } else
  449.         if ($this->__options['style']=='document'{
  450.             $requestArray = array($requestArray);
  451.         }
  452.         if (is_array($requestArray)) {
  453.             if (isset($requestArray['faultcode']) || isset($requestArray['SOAP-ENV:faultcode'])) {
  454.                 $faultcode = $faultstring = $faultdetail = $faultactor = '';
  455.                 foreach ($requestArray as $k => $v) {
  456.                     if (stristr($k,'faultcode')) $faultcode = $v;
  457.                     if (stristr($k,'faultstring')) $faultstring = $v;
  458.                     if (stristr($k,'detail')) $faultdetail = $v;
  459.                     if (stristr($k,'faultactor')) $faultactor = $v;
  460.                 }
  461.                 return $this->_raiseSoapFault($faultstring$faultdetail$faultactor$faultcode);
  462.             }
  463.             // return array of return values
  464.             if ($shift && count($requestArray) == 1) {
  465.                 return array_shift($requestArray);
  466.             }
  467.             return $requestArray;
  468.         }
  469.         return $requestArray;
  470.     }
  471.  
  472.     function verifyMethod($request)
  473.     {
  474.         if (!$this->callValidationreturn TRUE;
  475.         //return true;
  476.         $params $request->value;
  477.  
  478.         // get the dispatch map if one exists
  479.         $map = NULL;
  480.         if (array_key_exists($this->methodname$this->dispatch_map)) {
  481.             $map = $this->dispatch_map[$this->methodname];
  482.         } else if (isset($this->soapobject)) {
  483.             if (method_exists($this->soapobject'__dispatch')) {
  484.                 $map = $this->soapobject->__dispatch($this->methodname);
  485.             } else if (method_exists($this->soapobject$this->methodname)) {
  486.                 // no map, all public functions are soap functions
  487.                 return TRUE;
  488.             }
  489.         }
  490.         if (!$map) {
  491.             $this->_raiseSoapFault("soap request specified an unhandled method '$this->methodname'",'','','Client');
  492.             return FALSE;
  493.         }
  494.  
  495.         // if we aliased the soap method name to a php function,
  496.         // change the call_method so we do the right thing.
  497.         if (array_key_exists('alias',$map) && !empty($map['alias'])) {
  498.             $this->call_methodname = $map['alias'];
  499.         }
  500.  
  501.         // if there are input parameters required...
  502.         if ($sig = $map['in']) {
  503.             $this->input_value = count($sig);
  504.             $this->return_type $this->getReturnType($map['out']);
  505.             if (is_array($params)) {
  506.                 // validate the number of parameters
  507.                 if (count($params) == count($sig)) {
  508.                     // make array of param types
  509.                     foreach ($params as $param) {
  510.                         $p[] = strtolower($param->type);
  511.                     }
  512.                     $sig_t = array_values($sig);
  513.                     // validate each param's type
  514.                     for($i=0; $i < count($p)$i++) {
  515.                         // type not match
  516.                         // if soap types do not match, we ok it if the mapped php types match
  517.                         // this allows using plain php variables to work (ie. stuff like Decimal would fail otherwise)
  518.                         // we only error if the types exist in our type maps, and they differ
  519.                         if (strcasecmp($sig_t[$i],$p[$i])!=0 &&
  520.                             (isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]]&&
  521.                             strcasecmp($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]],$this->_typemap[SOAP_XML_SCHEMA_VERSION][$p[$i]])!=0)) {
  522.  
  523.                             $param = $params[$i];
  524.                             $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');
  525.                             return false;
  526.                         }
  527.                     }
  528.                     return true;
  529.                 // oops, wrong number of paramss
  530.                 } else {
  531.                     $this->_raiseSoapFault("soap request contained incorrect number of parameters. method '$this->methodname' required ".count($sig).' and request provided '.count($params),'','','Client');
  532.                     return false;
  533.                 }
  534.             // oops, no params...
  535.             } else {
  536.                 $this->_raiseSoapFault("soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig).' parameters, and request provided none','','','Client');
  537.                 return false;
  538.             }
  539.         // no params
  540.         }
  541.         // we'll try it anyway
  542.         return true;
  543.     }
  544.  
  545.     // get string return type from dispatch map
  546.     function getReturnType($returndata)
  547.     {
  548.         if (is_array($returndata)) {
  549.             if (count($returndata) > 1) {
  550.                 return $returndata;
  551.             }
  552.             $type = array_shift($returndata);
  553.             return $type;
  554.         }
  555.         return false;
  556.     }
  557.  
  558.     function validateMethod($methodname, $namespace = NULL)
  559.     {
  560.         unset($this->soapobject);
  561.         if (!$this->callValidationreturn TRUE;
  562.         # no soap access to private functions
  563.         if ($methodname[0== '_'return FALSE;
  564.  
  565.         /* if it's in our function list, ok */
  566.         if (array_key_exists($methodname$this->dispatch_map&&
  567.             (!$namespace || !array_key_exists('namespace'$this->dispatch_map[$methodname]||
  568.              $namespace == $this->dispatch_map[$methodname]['namespace'])) {
  569.                 if (array_key_exists('namespace', $this->dispatch_map[$methodname]))
  570.                     $this->method_namespace = $this->dispatch_map[$methodname]['namespace'];
  571.             return TRUE;
  572.         }
  573.  
  574.         /* if it's in an object, it's ok */
  575.         if (isset($this->dispatch_objects[$namespace])) {
  576.             $c = count($this->dispatch_objects[$namespace]);
  577.             for ($i=0; $i $c$i++{
  578.                 $obj =& $this->dispatch_objects[$namespace][$i];
  579.                 // if we have a dispatch map, and the function is not
  580.                 // in the dispatch map, then it is not callable!
  581.                 if (method_exists($obj'__dispatch')) {
  582.                     if ($obj->__dispatch($methodname)) {
  583.                         $this->method_namespace = $namespace;
  584.                         $this->soapobject =$obj;
  585.                         return TRUE;
  586.                     }
  587.                 } else
  588.                 if (method_exists($obj, $methodname)) {
  589.                     $this->method_namespace = $namespace;
  590.                     $this->soapobject =$obj;
  591.                     return TRUE;
  592.                 }
  593.             }
  594.         }
  595.         return FALSE;
  596.     }
  597.  
  598.     function addObjectMap(&$obj, $namespace = null, $service_name = 'Default', $service_desc = '')
  599.     {
  600.         if (!$namespace) {
  601.             if (isset($obj->namespace)) {
  602.                 // XXX a bit of backwards compatibility
  603.                 $namespace = $obj->namespace;
  604.             } else {
  605.                 $this->_raiseSoapFault('No namespace provided for class!','','','Server');
  606.                 return false;
  607.             }
  608.         }
  609.         if (!isset($this->dispatch_objects[$namespace])) {
  610.             $this->dispatch_objects[$namespace= array();
  611.         }
  612.         $this->dispatch_objects[$namespace][=$obj;
  613.  
  614.         // Create internal WSDL structures for object
  615.         // XXX Because some internal workings of PEAR::SOAP decide whether to
  616.         // do certain things by the presence or absence of _wsdl, we should
  617.         // only create a _wsdl structure if we know we can fill it; if
  618.         // __dispatch_map or __typedef for the object is missing, we should
  619.         // avoid creating it. Later, when we are using PHP 5 introspection,
  620.         // we will be able to make the data for all objects without any extra
  621.         // information from the developers, and this condition should be
  622.         // dropped.
  623.  
  624.         // XXX Known issue: if imported WSDL (bindWSDL) or another WSDL source
  625.         // is used to add _wsdl structure information, then addObjectWSDL is
  626.         // used, there is a high possibility of _wsdl data corruption;
  627.         // therefore you should avoid using __dispatch_map/__typedef definitions
  628.         // AND other WSDL data sources in the same service. We exclude classes
  629.         // that don't have __typedefs to allow external WSDL files to be used
  630.         // with classes with no internal type definitions (the types are defined
  631.         // in the WSDL file). When addObjectWSDL is refactored to not cause
  632.         // corruption, this restriction can be relaxed.
  633.  
  634.         // In summry, if you add an object with both a dispatch map and type
  635.         // definitions, then previous WSDL file operation and type definitions
  636.         // will be overwritten.
  637.         if (isset($obj->__dispatch_map&& isset($obj->__typedef)) {
  638.             $this->addObjectWSDL($obj$namespace$service_name$service_desc);
  639.         }
  640.         return true;
  641.     }
  642.  
  643.     // add a method to the dispatch map
  644.     function addToMap($methodname, $in, $out, $namespace = NULL, $alias=NULL)
  645.     {
  646.         if (!function_exists($methodname)) {
  647.             $this->_raiseSoapFault("error mapping function\n",'','','Server');
  648.             return false;
  649.         }
  650.         $this->dispatch_map[$methodname]['in'$in;
  651.         $this->dispatch_map[$methodname]['out'$out;
  652.         $this->dispatch_map[$methodname]['alias'$alias;
  653.         if ($namespace$this->dispatch_map[$methodname]['namespace'$namespace;
  654.         return true;
  655.     }
  656.  
  657.     function setCallHandler($callHandler, $validation=true) {
  658.         $this->callHandler = $callHandler;
  659.         $this->callValidation = $validation;
  660.     }
  661.  
  662.     /**
  663.      * @deprecated use bindWSDL from now on
  664.      */
  665.     function bind($wsdl_url) {
  666.         $this->bindWSDL($wsdl_url);
  667.     }
  668.  
  669.     /**
  670.      * @param  string a url to a WSDL resource
  671.      * @return void
  672.      */
  673.     function bindWSDL($wsdl_url) {
  674.         // instantiate wsdl class
  675.         $this->_wsdl =new SOAP_WSDL($wsdl_url);
  676.         if ($this->_wsdl->fault{
  677.             $this->_raiseSoapFault($this->_wsdl->fault);
  678.         }
  679.     }
  680.  
  681.     /**
  682.      * @return void
  683.      */
  684.     function addObjectWSDL(&$wsdl_obj, $targetNamespace, $service_name, $service_desc = '') {
  685.         if (!isset($this->_wsdl)) {
  686.             $this->_wsdl =new SOAP_WSDL;
  687.         }
  688.  
  689.         $this->_wsdl->parseObject($wsdl_obj$targetNamespace$service_name$service_desc);
  690.  
  691.         if ($this->_wsdl->fault{
  692.             $this->_raiseSoapFault($this->_wsdl->fault);
  693.         }
  694.     }
  695. }

Documentation generated on Mon, 11 Mar 2019 13:59:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.