Suggestion on using php Class with NuSoap

Help
2010-06-17
2013-06-06
  • Timo Karvinen
    Timo Karvinen
    2010-06-17

    I use NuSoap server in WSDL mode and php Classes for data retrieval.
    NuSoap has ability to instantiate classes but this requires Class.method notation which in my case means there has to be Class.method notation also in WSDL which I would like to get rid of.
    I have modified my NuSoap source so that you can set Class on server without the need of Class.method notation.

    Here are the suggested changes:

    Add instance variable:
    var $userclass = null;

    Add method:
    public function setClass($class) {
    $this->userclass = $class;
    }

    Add function invoke_method():
    After the lines (3995-3996 in 0.9.5):
    $class = '';
    $method = '';
    These lines:
    if (!empty($this->userclass)) {
    $class = $this->userclass;
    $method = $this->methodname;
    }

    These changes shouldn't break existing functionality but would allow setting class on server instance without having to use Class.method notation on WSDL.

     
  • Scott Nichol
    Scott Nichol
    2010-06-19

    I will be adding a more general capability, specifically a dispatch map.  This will allow the specification of a function, class+method or class-instance+method for any soap-action or operation name.  The implicit mapping done today will be the default if no appropriate map element is present for a particular call.

     
  • Timo Karvinen
    Timo Karvinen
    2010-06-21

    That's nice, any estimate about timetable on this?

     
  • Scott Nichol
    Scott Nichol
    2010-06-21

    I've added the method below to my working copy and check the maps when invoking a method on the server, but have not created full tests so have not committed.  If there is something in this code that looks bad or that you would like to see added, let me know.

        /**
        * add an operation dispatch mapping
        *
        * (either $operation_element OR $soap_action should be specified)
        * (one or neither of $invoke_class or $invoke_class_instance should be specified)
        *
        * @param    string $operation_element   The XML element for the operation
        * @param    string $soap_action The SOAP Action for the operation
        * @param    string $invoke_class    The class on which to invoke as a class method
        * @param    string $invoke_class_instance   The class on which to invoke as an instance method
        * @param    string $invoke_function The function or method to invoke
        * @return   boolean true if added, false if not
        * @access   public
        */
        function addDispatchMap($operation_element, $soap_action, $invoke_function, $invoke_class, $invoke_class_instance) {
            // massage parameters
            if (!is_string($operation_element))
                $operation_element = '';
            if (!is_string($soap_action))
                $soap_action = '';
            if (!is_string($invoke_class))
                $invoke_class = '';
            if (!is_string($invoke_class_instance))
                $invoke_class_instance = '';
            if (!is_string($invoke_function))
                $invoke_function = '';
            // validate parameters
            if ($operation_element == '' && $soap_action == '') {
                $this->debug('addDispatchMap: Neither operation_element nor soap_action specified');
                return false;
            }
            if ($operation_element != '' && $soap_action != '') {
                $this->debug('addDispatchMap: Both operation_element and soap_action specified');
                return false;
            }
            if ($invoke_class != '' && $invoke_class_instance != '') {
                $this->debug('addDispatchMap: Both invoke_class and invoke_class_instance specified');
                return false;
            }
            if ($invoke_function == '') {
                $this->debug('addDispatchMap: No value provided for invoke_function');
                return false;
            }
            $map['operation_element'] = $operation_element;
            $map['soap_action'] = $soap_action;
            $map['invoke_class'] = $invoke_class;
            $map['invoke_class_instance'] = $invoke_class_instance;
            $map['invoke_function'] = $invoke_function;
            if ($operation_element != '') {
                $this->dispatchMapByOperationElement[$operation_element] = $map;
                $this->debug("addDispatchMap: Added map for operation_element $operation_element");
            } else {
                $this->dispatchMapBySOAPAction[$soap_action] = $map;
                $this->debug("addDispatchMap: Added map for soap_action $soap_action");
            }
    
            return true;
        }
    
     
  • Timo Karvinen
    Timo Karvinen
    2010-06-22

    I'm not so sure this would work with my case.
    Here's an example how I'm using it now with my setClass() -method.

    /*
    Require PHP Class with business logic $WS_CLASS_DIR is directory from general 
    configuration file and $WS_NAME comes from service specific configuration 
    file read by a parameter submitted in the URL request.
    */
    require_once ($WS_CLASS_DIR . $WS_NAME . '.php');
    /*
    WSDL file is generated on the fly, from the service specific configuration 
    file, and set here for the service.
    */
    $wsdlfile = $WS_WSDL_DIR . $WS_NAME . '.wsdl';
    /*
    Initialize NuSoap server in WSDL-mode
    */
    $server = new nusoap_server ( $wsdlfile );
    $server->soap_defencoding = "utf-8";
    /*
    Set the class to be used by server.
    */
    $server->setClass ( $WS_NAME );
    /*
    Get raw post data.
    */
    if (!isset($HTTP_RAW_POST_DATA)){
        $HTTP_RAW_POST_DATA = file_get_contents('php://input');
    }
    $HTTP_RAW_POST_DATA = isset ( $HTTP_RAW_POST_DATA ) ? $HTTP_RAW_POST_DATA : '';
    /*
    Serve.
    */
    $server->service ( $HTTP_RAW_POST_DATA );