]> granicus.if.org Git - php/commitdiff
WSDL: encoding rpc/document and encoded/literal
authorDmitry Stogov <dmitry@php.net>
Wed, 14 Jan 2004 12:49:02 +0000 (12:49 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 14 Jan 2004 12:49:02 +0000 (12:49 +0000)
ext/soap/TODO
ext/soap/php_encoding.c
ext/soap/php_encoding.h
ext/soap/php_http.c
ext/soap/php_sdl.c
ext/soap/soap.c

index 4c4c23de7f6f0a678187089fae7e10be9e181c40..f517b4408a7cd443a3aa4022892656462a5db3aa 100644 (file)
@@ -53,7 +53,7 @@ Encoding
   ? arrays of arrays
   - encoding of arrays with holes
 - full support for structures???  
-- references (id,href)
++ references (id,href)
 - references to external resources
 - default values
 - root attribute
@@ -65,8 +65,11 @@ WSDL
 ----
 + wsdl and schema import
 + support for <opperation> without <input>
-? support for style "rpc"/"document" encoding
-? support for "encoded"/"literal" encoding
++ support for style "rpc"/"document" encoding (client part)
+- support for style "rpc"/"document" encoding (server part)
+  How to get function name from request?
++ support for "encoded"/"literal" encoding
+? arrayType and "literal" encoding
 ? support for "nillable" and "nil"
 - support for user defined simple types
   - restiction
@@ -112,6 +115,10 @@ WSDL
 - wsdl caching
 - wsdl auto generation
 ? SOAP binding
+  ? <soap:body>
+    - "parts"
+  - <soap:fault>
+  - <soap:header> and <soap:headerfault>
 - HTTP GET/POST binding
 - MIME binding
 
index d76225c48300c3d9d186fc3e9dfbbcf3185f15c6..09c3700fde06693fe4595bcb65fe47ae7ce56968 100644 (file)
@@ -773,6 +773,7 @@ static xmlNodePtr to_xml_array(encodeType type, zval *data, int style)
        if (Z_TYPE_P(data) == IS_ARRAY) {
                i = zend_hash_num_elements(Z_ARRVAL_P(data));
 
+               /*FIXME: arrayType and "literal" encoding? */
                if (i > 0 && style == SOAP_ENCODED) {
                        get_array_type(data, &array_type TSRMLS_CC);
                        smart_str_append(&array_type_and_size, &array_type);
@@ -859,7 +860,9 @@ zval *to_zval_array(encodeType type, xmlNodePtr data)
        int* pos = NULL;
        xmlAttrPtr arrayTypeAttr;
        xmlAttrPtr offsetAttr;
+       xmlAttrPtr *tmp;
        sdlPtr sdl;
+       sdlAttributePtr *arrayType;
 
        TSRMLS_FETCH();
 
@@ -888,6 +891,30 @@ zval *to_zval_array(encodeType type, xmlNodePtr data)
                }
                efree(type);
                if (ns) {efree(ns);}
+       } else if (type.sdl_type != NULL &&
+                  type.sdl_type->attributes != NULL &&
+                  zend_hash_find(type.sdl_type->attributes, SOAP_ENC_NAMESPACE":arrayType",
+                                 sizeof(SOAP_ENC_NAMESPACE":arrayType"),
+                                 (void **)&arrayType) == SUCCESS &&
+                  zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&tmp) == SUCCESS) {
+               char *type, *end, *ns;
+               xmlNsPtr nsptr;
+
+               arrayTypeAttr = *tmp;
+               parse_namespace(arrayTypeAttr->children->content, &type, &ns);
+               nsptr = xmlSearchNs(arrayTypeAttr->doc, arrayTypeAttr->parent, ns);
+
+               end = strrchr(type,'[');
+               if (end) {
+                       *end = '\0';
+               }
+               if (nsptr != NULL) {
+                       enc = get_encoder(SOAP_GLOBAL(sdl), nsptr->href, type);
+               }
+               efree(type);
+               if (ns) {efree(ns);}
+               dims = emalloc(sizeof(int));
+               *dims = 0;
        }
        if (dims == NULL) {
                dims = emalloc(sizeof(int));
@@ -1177,7 +1204,7 @@ static xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format,
                }
 
                /* Time zone support */
-#if HAVE_TM_GMTOFF                             
+#if HAVE_TM_GMTOFF
                sprintf(tzbuf, "%c%02d%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( (ta->tm_gmtoff % 3600) / 60 ));
 #else
                sprintf(tzbuf, "%c%02d%02d", ((ta->tm_isdst ? tzone - 3600:tzone)>0)?'-':'+', abs((ta->tm_isdst ? tzone - 3600 : tzone) / 3600), abs(((ta->tm_isdst ? tzone - 3600 : tzone) % 3600) / 60));
index c71c2b2155e8f7ea2b66aec5b751d89bdcdc232b..4f63d74ca514c2ec7608220716d90dee16295cd5 100644 (file)
 #define WSDL_NAMESPACE "http://schemas.xmlsoap.org/wsdl/"
 #define WSDL_NS_PREFIX "wsdl"
 
-#define WSDL_SOAP_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap/"
+#define WSDL_SOAP11_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap/"
+#define WSDL_SOAP12_NAMESPACE "http://www.w3.org/2003/05/soap-rpc"
+#define WSDL_SOAP12OLD_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap12/"
 #define WSDL_SOAP_NS_PREFIX "wsdlSoap"
 
-#define WSDL_SOAP12_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap12/"
-
 #define WSDL_HTTP_NAMESPACE "http://schemas.xmlsoap.org/wsdl/http/"
 #define WSDL_HTTP_NS_PREFIX "http"
 
index 361585d477b4a5e13901838f50a99cb2b00baaf0..07165974956b6678e7b163da2ffaa7878fb9e045 100644 (file)
@@ -129,8 +129,8 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
 /*
                        "Connection: close\r\n"
                        "Accept: text/html; text/xml; text/plain\r\n"
-                       "User-Agent: PHP SOAP 0.1\r\n"
 */
+                       "User-Agent: PHP SOAP 0.1\r\n"
                        "Content-Type: text/xml; charset=\"utf-8\"\r\n"
                        "Content-Length: ");
                smart_str_append_long(&soap_headers, buf_size);
index bd91028231d4dcee4d048360f427301e98594c5c..bb28fd498037440c9accfab34694c6a4901f85e5 100644 (file)
@@ -107,7 +107,7 @@ encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const
        enc->details.sdl_type = cur_type;
        enc->to_xml = sdl_guess_convert_xml;
        enc->to_zval = sdl_guess_convert_zval;
-       
+
        if (enc_ptr == NULL) {
                zend_hash_update(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL);
        }
@@ -213,6 +213,7 @@ static xmlNodePtr sdl_to_xml_array(encodeType enc_type, zval *data, int style)
                sdlAttributePtr *arrayType;
                i = zend_hash_num_elements(Z_ARRVAL_P(data));
 
+/* FIXME: Is arrayType needed? What about enc? */
                if (style == SOAP_ENCODED) {
                        xmlAttrPtr *wsdl;
                        if (type->attributes &&
@@ -609,6 +610,7 @@ static sdlPtr load_wsdl(char *struri)
                                xmlNodePtr address, binding, trav2;
                                char *ns, *ctype;
                                sdlBindingPtr tmpbinding;
+                               char *wsdl_soap_namespace = NULL;
 
                                tmpbinding = malloc(sizeof(sdlBinding));
                                memset(tmpbinding, 0, sizeof(sdlBinding));
@@ -636,9 +638,14 @@ static sdlPtr load_wsdl(char *struri)
 
                                tmpbinding->location = strdup(location->children->content);
 
-                               if (address->ns && !strcmp(address->ns->href, WSDL_SOAP_NAMESPACE)) {
+                               if (address->ns && !strcmp(address->ns->href, WSDL_SOAP11_NAMESPACE)) {
+                                       wsdl_soap_namespace = WSDL_SOAP11_NAMESPACE;
+                                       tmpbinding->bindingType = BINDING_SOAP;
+                               } else if (address->ns && !strcmp(address->ns->href, WSDL_SOAP12OLD_NAMESPACE)) {
+                                       wsdl_soap_namespace = WSDL_SOAP12OLD_NAMESPACE;
                                        tmpbinding->bindingType = BINDING_SOAP;
                                } else if (address->ns && !strcmp(address->ns->href, WSDL_SOAP12_NAMESPACE)) {
+                                       wsdl_soap_namespace = WSDL_SOAP12_NAMESPACE;
                                        tmpbinding->bindingType = BINDING_SOAP;
                                } else if (address->ns && !strcmp(address->ns->href, WSDL_HTTP_NAMESPACE)) {
                                        tmpbinding->bindingType = BINDING_HTTP;
@@ -666,13 +673,13 @@ static sdlPtr load_wsdl(char *struri)
 
                                        soapBinding = malloc(sizeof(sdlSoapBinding));
                                        memset(soapBinding, 0, sizeof(sdlSoapBinding));
-                                       soapBinding->style = SOAP_RPC;
+                                       soapBinding->style = SOAP_DOCUMENT;
 
-                                       soapBindingNode = get_node_ex(binding->children, "binding", WSDL_SOAP_NAMESPACE);
+                                       soapBindingNode = get_node_ex(binding->children, "binding", wsdl_soap_namespace);
                                        if (soapBindingNode) {
                                                tmp = get_attribute(soapBindingNode->properties, "style");
-                                               if (tmp && !strcmp(tmp->children->content, "document")) {
-                                                       soapBinding->style = SOAP_DOCUMENT;
+                                               if (tmp && !strcmp(tmp->children->content, "rpc")) {
+                                                       soapBinding->style = SOAP_RPC;
                                                }
 
                                                tmp = get_attribute(soapBindingNode->properties, "transport");
@@ -709,7 +716,7 @@ static sdlPtr load_wsdl(char *struri)
                                trav2 = binding->children;
                                FOREACHNODE(trav2, "operation", operation) {
                                        sdlFunctionPtr function;
-                                       xmlNodePtr input, output, fault, portTypeOperation, portTypeInput, msgInput, msgOutput;
+                                       xmlNodePtr input, output, fault, portTypeOperation, portTypeInput, portTypeOutput, msgInput, msgOutput;
                                        xmlAttrPtr op_name, paramOrder;
 
                                        op_name = get_attribute(operation->properties, "name");
@@ -741,7 +748,7 @@ static sdlPtr load_wsdl(char *struri)
                                                soapBinding = (sdlSoapBindingPtr)tmpbinding->bindingAttributes;
                                                soapFunctionBinding->style = soapBinding->style;
 
-                                               soapOperation = get_node_ex(operation->children, "operation", WSDL_SOAP_NAMESPACE);
+                                               soapOperation = get_node_ex(operation->children, "operation", wsdl_soap_namespace);
                                                if (soapOperation) {
                                                        tmp = get_attribute(soapOperation->properties, "soapAction");
                                                        if (tmp) {
@@ -749,10 +756,14 @@ static sdlPtr load_wsdl(char *struri)
                                                        }
 
                                                        tmp = get_attribute(soapOperation->properties, "style");
-                                                       if (tmp && !strcmp(tmp->children->content, "rpc")) {
-                                                               soapFunctionBinding->style = SOAP_RPC;
-                                                       } else if (!soapBinding->style) {
-                                                               soapFunctionBinding->style = SOAP_DOCUMENT;
+                                                       if (tmp) {
+                                                               if (!strcmp(tmp->children->content, "rpc")) {
+                                                                       soapFunctionBinding->style = SOAP_RPC;
+                                                               } else {
+                                                                       soapFunctionBinding->style = SOAP_DOCUMENT;
+                                                               }
+                                                       } else {
+                                                               soapFunctionBinding->style = soapBinding->style;
                                                        }
                                                }
 
@@ -776,7 +787,7 @@ static sdlPtr load_wsdl(char *struri)
                                                        function->requestName = strdup(function->functionName);
                                                        function->requestParameters = malloc(sizeof(HashTable));
                                                        zend_hash_init(function->requestParameters, 0, NULL, delete_paramater, 1);
-               
+
                                                        parse_namespace(message->children->content, &ctype, &ns);
 
                                                        if (zend_hash_find(&ctx.messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
@@ -791,8 +802,8 @@ static sdlPtr load_wsdl(char *struri)
                                                                sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
                                                                xmlNodePtr body;
                                                                xmlAttrPtr tmp;
-                               
-                                                               body = get_node_ex(input->children, "body", WSDL_SOAP_NAMESPACE);
+
+                                                               body = get_node_ex(input->children, "body", wsdl_soap_namespace);
                                                                if (body) {
                                                                        tmp = get_attribute(body->properties, "use");
                                                                        if (tmp && !strcmp(tmp->children->content, "literal")) {
@@ -800,7 +811,7 @@ static sdlPtr load_wsdl(char *struri)
                                                                        } else {
                                                                                soapFunctionBinding->input.use = SOAP_ENCODED;
                                                                        }
-                                               
+
                                                                        tmp = get_attribute(body->properties, "namespace");
                                                                        if (tmp) {
                                                                                soapFunctionBinding->input.ns = strdup(tmp->children->content);
@@ -854,91 +865,94 @@ static sdlPtr load_wsdl(char *struri)
                                                }
                                        }
 
-                                       output = get_node(portTypeOperation->children, "output");
+                                       output = get_node(operation->children, "output");
                                        if (output != NULL) {
                                                xmlAttrPtr message;
                                                xmlNodePtr part, trav3;
                                                char *ns, *ctype;
 
-                                               /* FIXME: may be output message name */
-                                               function->responseName = malloc(strlen(function->functionName) + strlen("Response") + 1);
-                                               sprintf(function->responseName, "%sResponse", function->functionName);
-                                               function->responseParameters = malloc(sizeof(HashTable));
-                                               zend_hash_init(function->responseParameters, 0, NULL, delete_paramater, 1);
+                                               portTypeOutput = get_node(portTypeOperation->children, "output");
+                                               if (portTypeOutput) {
+                                                       /* FIXME: may be output message name */
+                                                       function->responseName = malloc(strlen(function->functionName) + strlen("Response") + 1);
+                                                       sprintf(function->responseName, "%sResponse", function->functionName);
+                                                       function->responseParameters = malloc(sizeof(HashTable));
+                                                       zend_hash_init(function->responseParameters, 0, NULL, delete_paramater, 1);
 
-                                               message = get_attribute(output->properties, "message");
-                                               if (message == NULL) {
-                                                       php_error(E_ERROR, "Error parsing wsdl (Missing name for \"output\" of \"%s\")", op_name->children->content);
-                                               }
+                                                       message = get_attribute(portTypeOutput->properties, "message");
+                                                       if (message == NULL) {
+                                                               php_error(E_ERROR, "Error parsing wsdl (Missing name for \"output\" of \"%s\")", op_name->children->content);
+                                                       }
 
-                                               parse_namespace(message->children->content, &ctype, &ns);
-                                               if (zend_hash_find(&ctx.messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
-                                                       php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content);
-                                               }
-                                               msgOutput = *tmp;
+                                                       parse_namespace(message->children->content, &ctype, &ns);
+                                                       if (zend_hash_find(&ctx.messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
+                                                               php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content);
+                                                       }
+                                                       msgOutput = *tmp;
 
-                                               if (ctype) {efree(ctype);}
-                                               if (ns) {efree(ns);}
+                                                       if (ctype) {efree(ctype);}
+                                                       if (ns) {efree(ns);}
 
-                                               if (tmpbinding->bindingType == BINDING_SOAP) {
-                                                       sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
-                                                       xmlNodePtr body;
-                                                       xmlAttrPtr tmp;
+                                                       if (tmpbinding->bindingType == BINDING_SOAP) {
+                                                               sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
+                                                               xmlNodePtr body;
+                                                               xmlAttrPtr tmp;
 
-                                                       body = get_node_ex(output->children, "body", WSDL_SOAP_NAMESPACE);
-                                                       if (body) {
-                                                               tmp = get_attribute(body->properties, "use");
-                                                               if (tmp && !strcmp(tmp->children->content, "literal")) {
-                                                                       soapFunctionBinding->output.use = SOAP_LITERAL;
-                                                               } else {
-                                                                       soapFunctionBinding->output.use = SOAP_ENCODED;
-                                                               }
+                                                               body = get_node_ex(output->children, "body", wsdl_soap_namespace);
+                                                               if (body) {
+                                                                       tmp = get_attribute(body->properties, "use");
+                                                                       if (tmp && !strcmp(tmp->children->content, "literal")) {
+                                                                               soapFunctionBinding->output.use = SOAP_LITERAL;
+                                                                       } else {
+                                                                               soapFunctionBinding->output.use = SOAP_ENCODED;
+                                                                       }
 
-                                                               tmp = get_attribute(body->properties, "namespace");
-                                                               if (tmp) {
-                                                                       soapFunctionBinding->output.ns = strdup(tmp->children->content);
-                                                               }
+                                                                       tmp = get_attribute(body->properties, "namespace");
+                                                                       if (tmp) {
+                                                                               soapFunctionBinding->output.ns = strdup(tmp->children->content);
+                                                                       }
 
-                                                               tmp = get_attribute(body->properties, "parts");
-                                                               if (tmp) {
-                                                                       soapFunctionBinding->output.parts = strdup(tmp->children->content);
-                                                               }
+                                                                       tmp = get_attribute(body->properties, "parts");
+                                                                       if (tmp) {
+                                                                               soapFunctionBinding->output.parts = strdup(tmp->children->content);
+                                                                       }
 
-                                                               tmp = get_attribute(body->properties, "encodingStyle");
-                                                               if (tmp) {
-                                                                       soapFunctionBinding->output.encodingStyle = strdup(tmp->children->content);
+                                                                       tmp = get_attribute(body->properties, "encodingStyle");
+                                                                       if (tmp) {
+                                                                               soapFunctionBinding->output.encodingStyle = strdup(tmp->children->content);
+                                                                       }
                                                                }
                                                        }
-                                               }
 
-                                               trav3 = msgOutput->children;
-                                               FOREACHNODE(trav3, "part", part) {
-                                                       sdlParamPtr param;
-                                                       xmlAttrPtr element, type, name;
+                                                       trav3 = msgOutput->children;
+                                                       FOREACHNODE(trav3, "part", part) {
+                                                               sdlParamPtr param;
+                                                               xmlAttrPtr element, type, name;
 
-                                                       param = malloc(sizeof(sdlParam));
-                                                       param->order = 0;
+                                                               param = malloc(sizeof(sdlParam));
+                                                               param->order = 0;
 
-                                                       name = get_attribute(part->properties, "name");
-                                                       if (name == NULL) {
-                                                               php_error(E_ERROR, "Error parsing wsdl (No name associated with part \"%s\")", msgOutput->name);
-                                                       }
+                                                               name = get_attribute(part->properties, "name");
+                                                               if (name == NULL) {
+                                                                       php_error(E_ERROR, "Error parsing wsdl (No name associated with part \"%s\")", msgOutput->name);
+                                                               }
 
-                                                       param->paramName = strdup(name->children->content);
+                                                               param->paramName = strdup(name->children->content);
 
-                                                       element = get_attribute(part->properties, "element");
-                                                       if (element) {
-                                                               param->encode = get_encoder_from_prefix(ctx.root, part, element->children->content);
-                                                       }
+                                                               element = get_attribute(part->properties, "element");
+                                                               if (element) {
+                                                                       param->encode = get_encoder_from_prefix(ctx.root, part, element->children->content);
+                                                               }
 
-                                                       type = get_attribute(part->properties, "type");
-                                                       if (type) {
-                                                               param->encode = get_encoder_from_prefix(ctx.root, part, type->children->content);
-                                                       }
+                                                               type = get_attribute(part->properties, "type");
+                                                               if (type) {
+                                                                       param->encode = get_encoder_from_prefix(ctx.root, part, type->children->content);
+                                                               }
 
-                                                       zend_hash_next_index_insert(function->responseParameters, &param, sizeof(sdlParamPtr), NULL);
+                                                               zend_hash_next_index_insert(function->responseParameters, &param, sizeof(sdlParamPtr), NULL);
+                                                       }
+                                                       ENDFOREACH(trav3);
                                                }
-                                               ENDFOREACH(trav3);
                                        }
 
                                        fault = get_node(operation->children, "fault");
@@ -1229,4 +1243,3 @@ static void delete_document(void *doc_ptr)
        xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
        xmlFreeDoc(doc);
 }
-
index 224b4e1c9891ef83a955deb48e55e3ba789974ad..789b5b068d42f7bddb9859807102519e0bf17644 100644 (file)
@@ -1042,7 +1042,7 @@ PHP_METHOD(soapserver, handle)
                && ((*raw_post)->type==IS_STRING)) {
                int old_error_reporting = EG(error_reporting);
                EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);
-               
+
                doc_request = xmlParseMemory(Z_STRVAL_PP(raw_post),Z_STRLEN_PP(raw_post));
                xmlCleanupParser();
 
@@ -1086,7 +1086,7 @@ PHP_METHOD(soapserver, handle)
 
                                MAKE_STD_ZVAL(tmp_soap);
                                object_init_ex(tmp_soap, service->soap_class.ce);
-                               
+
                                /* Call constructor */
                                class_name_len = strlen(service->soap_class.ce->name);
                                class_name = emalloc(class_name_len+1);
@@ -1460,13 +1460,16 @@ zend_try {
                zval** fault;
                if (zend_hash_find(Z_OBJPROP_P(thisObj), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
                        *return_value = **fault;
+                       zval_copy_ctor(return_value);
                } else {
                        *return_value = *add_soap_fault(thisObj, "SOAP-ENV:Client", "Unknown Error", NULL, NULL TSRMLS_CC);
+                       zval_copy_ctor(return_value);
                }
        } else {
                zval** fault;
                if (zend_hash_find(Z_OBJPROP_P(thisObj), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
                        *return_value = **fault;
+                       zval_copy_ctor(return_value);
                }
        }
        SOAP_GLOBAL(sdl) = NULL;
@@ -1847,6 +1850,7 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_
        sdlParamPtr parameter = NULL;
        smart_str *gen_ns = NULL;
        int param_count;
+       int style, use;
 
        encode_reset_ns();
 
@@ -1856,55 +1860,44 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_
        doc->children = xmlNewDocNode(doc, NULL, "SOAP-ENV:Envelope", NULL);
        envelope = doc->children;
 
-       /*TODO: if use="literal" SOAP-ENV:encodingStyle is not need */
-
        if (version == SOAP_1_1) {
-/*
-               if ($style == 'rpc' && $use == 'encoded') {
-*/
-                       xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC);
-/*
-               }
-*/
-               xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC);
                ns = xmlNewNs(envelope, SOAP_1_1_ENV,"SOAP-ENV");
        } else if (version == SOAP_1_2) {
-/*
-               if ($style == 'rpc' && $use == 'encoded') {
-*/
-                       xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC);
-/*
-               }
-*/
-               xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC);
                ns = xmlNewNs(envelope, SOAP_1_2_ENV,"SOAP-ENV");
        } else {
          php_error(E_ERROR, "Unknown SOAP version");
        }
-       xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
-       xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
-       xmlSetProp(envelope, "xmlns:" APACHE_NS_PREFIX , APACHE_NAMESPACE);
 
        body = xmlNewChild(envelope, ns, "Body", NULL);
 
        if (Z_TYPE_P(ret) == IS_OBJECT &&
                Z_OBJCE_P(ret) == soap_fault_class_entry) {
-               param = seralize_zval(ret, NULL, "SOAP-ENV:Fault", SOAP_ENCODED TSRMLS_CC);
+               use = SOAP_ENCODED;
+               param = seralize_zval(ret, NULL, "SOAP-ENV:Fault", use TSRMLS_CC);
                xmlAddChild(body, param);
        } else {
                gen_ns = encode_new_ns();
-               ns = xmlNewNs(envelope, uri, gen_ns->c);
 
-               if (function != NULL) {
-                       method = xmlNewChild(body, ns, function->responseName , NULL);
+               if (function != NULL && function->binding->bindingType == BINDING_SOAP) {
+                       sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
+
+                       style = fnb->style;
+                       use = fnb->output.use;
+                       if (style == SOAP_RPC) {
+                               ns = xmlNewNs(body, fnb->output.ns, gen_ns->c);
+                               if (function->responseName) {
+                                       method = xmlNewChild(body, ns, function->responseName, NULL);
+                               } else {
+                                       method = xmlNewChild(body, ns, function->functionName, NULL);
+                               }
+                       }
                } else {
+                       style = SOAP_RPC;
+                       use = SOAP_ENCODED;
+                       ns = xmlNewNs(body, uri, gen_ns->c);
                        method = xmlNewChild(body, ns, function_name, NULL);
                }
 
-               if (uri) {
-                       ns = xmlNewNs(method, uri, NULL);
-               }
-
                if (function != NULL) {
                        param_count = zend_hash_num_elements(function->responseParameters);
                } else {
@@ -1914,8 +1907,21 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_
                if (param_count == 1) {
                        parameter = get_param(function, NULL, 0, TRUE);
 
-                       param = seralize_parameter(parameter, ret, 0, "return", SOAP_ENCODED TSRMLS_CC);
-                       xmlAddChild(method,param);
+                       param = seralize_parameter(parameter, ret, 0, "return", use TSRMLS_CC);
+                       if (style == SOAP_RPC) {
+                               xmlAddChild(method,param);
+                       } else {
+                               if (function && function->binding->bindingType == BINDING_SOAP) {
+                                       sdlParamPtr *sparam;
+
+                                       if (zend_hash_index_find(function->responseParameters, 0, (void **)&sparam) == SUCCESS) {
+                                               ns = xmlNewNs(param, (*sparam)->encode->details.ns, gen_ns->c);
+                                               xmlNodeSetName(param, (*sparam)->encode->details.type_str);
+                                               xmlSetNs(param, ns);
+                                       }
+                               }
+                               xmlAddChild(body, param);
+                       }
                } else if (param_count > 1 && Z_TYPE_P(ret) == IS_ARRAY) {
                        HashPosition pos;
                        zval **data;
@@ -1930,8 +1936,21 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_
                                zend_hash_get_current_key_ex(Z_ARRVAL_P(ret), &param_name, &param_name_len, &param_index, 0, &pos);
                                parameter = get_param(function, param_name, param_index, TRUE);
 
-                               param = seralize_parameter(parameter, *data, i, param_name, SOAP_ENCODED TSRMLS_CC);
-                               xmlAddChild(method,param);
+                               param = seralize_parameter(parameter, *data, i, param_name, use TSRMLS_CC);
+                               if (style == SOAP_RPC) {
+                                       xmlAddChild(method,param);
+                               } else {
+                                       if (function && function->binding->bindingType == BINDING_SOAP) {
+                                               sdlParamPtr *sparam;
+
+                                               if (zend_hash_index_find(function->responseParameters, i, (void **)&sparam) == SUCCESS) {
+                                                       ns = xmlNewNs(param, (*sparam)->encode->details.ns, gen_ns->c);
+                                                       xmlNodeSetName(param, (*sparam)->encode->details.type_str);
+                                                       xmlSetNs(param, ns);
+                                               }
+                                       }
+                                       xmlAddChild(body, param);
+                               }
 
                                zend_hash_move_forward_ex(Z_ARRVAL_P(ret), &pos);
                                i++;
@@ -1939,6 +1958,22 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_
                }
        }
 
+/* FIXME: if use="literal" SOAP-ENV:encodingStyle is not need.
+          What about arrayType?
+*/
+       if (use == SOAP_ENCODED) {
+               xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+               xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
+               xmlSetProp(envelope, "xmlns:" APACHE_NS_PREFIX , APACHE_NAMESPACE);
+               if (version == SOAP_1_1) {
+                       xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC);
+                       xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC);
+               } else if (version == SOAP_1_2) {
+                       xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC);
+                       xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC);
+               }
+       }
+
        if (gen_ns) {
                smart_str_free(gen_ns);
                efree(gen_ns);
@@ -1965,35 +2000,29 @@ static xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function,
        xmlDocSetRootElement(doc, envelope);
        if (version == SOAP_1_1) {
                ns = xmlNewNs(envelope, SOAP_1_1_ENV, "SOAP-ENV");
-               xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC);
-               xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC);
        } else if (version == SOAP_1_2) {
                ns = xmlNewNs(envelope, SOAP_1_2_ENV, "SOAP-ENV");
-               xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC);
-               xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC);
        } else {
                php_error(E_ERROR, "Unknown SOAP version");
        }
-       xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
-       xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
 
        body = xmlNewChild(envelope, ns, "Body", NULL);
 
        gen_ns = encode_new_ns();
 
-       if (function) {
-               if (function->binding->bindingType == BINDING_SOAP) {
-                       sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
+       if (function && function->binding->bindingType == BINDING_SOAP) {
+               sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
 
-                       style = fnb->style;
-                       use = fnb->input.use;
-                       if (style == SOAP_RPC) {
-                               ns = xmlNewNs(body, fnb->input.ns, gen_ns->c);
-                               if (function->requestName) {
-                                       method = xmlNewChild(body, ns, function->requestName, NULL);
-                               } else {
-                                       method = xmlNewChild(body, ns, function->functionName, NULL);
-                               }
+               style = fnb->style;
+               /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
+               /*style = SOAP_RPC;*/
+               use = fnb->input.use;
+               if (style == SOAP_RPC) {
+                       ns = xmlNewNs(body, fnb->input.ns, gen_ns->c);
+                       if (function->requestName) {
+                               method = xmlNewChild(body, ns, function->requestName, NULL);
+                       } else {
+                               method = xmlNewChild(body, ns, function->functionName, NULL);
                        }
                }
        } else {
@@ -2002,22 +2031,37 @@ static xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function,
                } else {
                        style = SOAP_RPC;
                }
+               /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
+               /*style = SOAP_RPC;*/
                if (style == SOAP_RPC) {
                        ns = xmlNewNs(body, uri, gen_ns->c);
                        method = xmlNewChild(body, ns, function_name, NULL);
                }
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS) {
-                       if (Z_LVAL_PP(zuse) == SOAP_LITERAL) {
-                               use = SOAP_LITERAL;
-                       } else {
-                               use = SOAP_ENCODED;
-                       }
+               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS &&
+                         Z_LVAL_PP(zuse) == SOAP_LITERAL) {
+                       use = SOAP_LITERAL;
                } else {
                        use = SOAP_ENCODED;
                }
        }
-       
+
+/* FIXME: if use="literal" SOAP-ENV:encodingStyle is not need.
+          What about arrayType?
+*/
+       if (use == SOAP_ENCODED) {
+               xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
+               xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+               xmlSetProp(envelope, "xmlns:" APACHE_NS_PREFIX , APACHE_NAMESPACE);
+               if (version == SOAP_1_1) {
+                       xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC);
+                       xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC);
+               } else if (version == SOAP_1_2) {
+                       xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC);
+                       xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC);
+               }
+       }
+
        for (i = 0;i < arg_count;i++) {
                xmlNodePtr param;
                sdlParamPtr parameter = get_param(function, NULL, i, FALSE);
@@ -2030,7 +2074,7 @@ static xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function,
                        if (function && function->binding->bindingType == BINDING_SOAP) {
                                sdlParamPtr *sparam;
 
-                               if (zend_hash_index_find(function->requestParameters, 0, (void **)&sparam) == SUCCESS) {
+                               if (zend_hash_index_find(function->requestParameters, i, (void **)&sparam) == SUCCESS) {
                                        ns = xmlNewNs(param, (*sparam)->encode->details.ns, gen_ns->c);
                                        xmlNodeSetName(param, (*sparam)->encode->details.type_str);
                                        xmlSetNs(param, ns);