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

Documentation generated on Mon, 11 Mar 2019 14:20:04 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.