]> granicus.if.org Git - php/commitdiff
Reimplemented SoapServer and SoapClient classes using ZE2 object API.
authorDmitry Stogov <dmitry@php.net>
Mon, 31 Jul 2006 16:02:04 +0000 (16:02 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 31 Jul 2006 16:02:04 +0000 (16:02 +0000)
All internal properties are hidden now.

ext/soap/php_http.c
ext/soap/php_sdl.c
ext/soap/php_soap.h
ext/soap/soap.c
ext/soap/tests/server019.phpt
ext/soap/tests/server020.phpt
ext/soap/tests/setheaders.phpt [new file with mode: 0755]

index 4fa014e6cde5d913a38269f3a3fb3f8412bb5ea7..7e7e19c3ab41a0c45f8014a1363f990eb73d45fb 100644 (file)
@@ -57,17 +57,18 @@ static int stream_alive(php_stream *stream  TSRMLS_DC)
 /* Proxy HTTP Authentication */
 void proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
 {
-       zval **login, **password;
+       soap_client_object *client;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login"), (void **)&login) == SUCCESS) {
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       if (client->proxy_login) {
                unsigned char* buf;
                int len;
                smart_str auth = {0};
 
-               smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+               smart_str_appends(&auth, client->proxy_login);
                smart_str_appendc(&auth, ':');
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_password", sizeof("_proxy_password"), (void **)&password) == SUCCESS) {
-                       smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
+               if (client->proxy_password) {
+                       smart_str_appends(&auth, client->proxy_login);
                }
                smart_str_0(&auth);
                buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
@@ -82,18 +83,18 @@ void proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
 /* HTTP Authentication */
 void basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
 {
-       zval **login, **password;
+       soap_client_object *client;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
-                       !zend_hash_exists(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"))) {
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       if (client->login && !client->digest) {
                unsigned char* buf;
                int len;
                smart_str auth = {0};
 
-               smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+               smart_str_appends(&auth, client->login);
                smart_str_appendc(&auth, ':');
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS) {
-                       smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
+               if (client->password) {
+                       smart_str_appends(&auth, client->password);
                }
                smart_str_0(&auth);
                buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
@@ -108,7 +109,6 @@ void basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
 static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, int *use_proxy TSRMLS_DC)
 {
        php_stream *stream;
-       zval **proxy_host, **proxy_port, **tmp;
        char *host;
        php_stream_context *context = NULL;
        char *name;
@@ -117,32 +117,27 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, in
        int old_error_reporting;
        struct timeval tv;
        struct timeval *timeout = NULL;
+       soap_client_object *client;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
-           Z_TYPE_PP(proxy_host) == IS_STRING &&
-           zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
-           Z_TYPE_PP(proxy_port) == IS_LONG) {
-               host = Z_STRVAL_PP(proxy_host);
-               port = Z_LVAL_PP(proxy_port);
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       if (client->proxy_host) {
+               host = client->proxy_host;
+               port = client->proxy_port;
                *use_proxy = 1;
        } else {
                host = phpurl->host;
                port = phpurl->port;
        }
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_connection_timeout", sizeof("_connection_timeout"), (void **) &tmp) == SUCCESS &&
-           Z_TYPE_PP(tmp) == IS_LONG && Z_LVAL_PP(tmp) > 0) {
-         tv.tv_sec = Z_LVAL_PP(tmp);
-         tv.tv_usec = 0;
+       if (client->connection_timeout) {
+               tv.tv_sec = client->connection_timeout;
+               tv.tv_usec = 0;
                timeout = &tv;
        }
 
        old_error_reporting = EG(error_reporting);
        EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);
 
-       if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
-                       "_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
-               context = php_stream_context_from_zval(*tmp, 0);
-       }
+       context = client->stream_context;
 
        namelen = spprintf(&name, 0, "%s://%s:%d", (use_ssl && !*use_proxy)? "ssl" : "tcp", host, port);
 
@@ -227,7 +222,6 @@ int make_http_soap_request(zval  *this_ptr,
        int request_size, err;
        php_url *phpurl = NULL;
        php_stream *stream;
-       zval **trace, **tmp;
        int use_proxy = 0;
        int use_ssl;
        char *http_headers, *http_body, *content_type, *http_version, *cookie_itt;
@@ -239,21 +233,23 @@ int make_http_soap_request(zval  *this_ptr,
        char *content_encoding;
        char *http_msg = NULL;
        zend_bool old_allow_url_fopen;
+       soap_client_object *client;
 
        if (this_ptr == NULL || Z_TYPE_P(this_ptr) != IS_OBJECT) {
                return FALSE;
        }
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
 
-  request = buf;
-  request_size = buf_size;
+       request = buf;
+       request_size = buf_size;
        /* Compress request */
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "compression", sizeof("compression"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
-               int level = Z_LVAL_PP(tmp) & 0x0f;
-               int kind  = Z_LVAL_PP(tmp) & SOAP_COMPRESSION_DEFLATE;
+       if (client->compression) {
+               int level = client->compression & 0x0f;
+               int kind  = client->compression & SOAP_COMPRESSION_DEFLATE;
 
                if (level > 9) {level = 9;}
 
-         if ((Z_LVAL_PP(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) {
+         if ((client->compression & SOAP_COMPRESSION_ACCEPT) != 0) {
                        smart_str_append_const(&soap_headers_z,"Accept-Encoding: gzip, deflate\r\n");
          }
          if (level > 0) {
@@ -292,11 +288,9 @@ int make_http_soap_request(zval  *this_ptr,
          }
        }
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"), (void **)&tmp) == SUCCESS) {
-               php_stream_from_zval_no_verify(stream,tmp);
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
-                       use_proxy = Z_LVAL_PP(tmp);
-               }
+       if (client->stream) {
+               stream = client->stream;
+               use_proxy = client->use_proxy;
        } else {
                stream = NULL;
        }
@@ -339,31 +333,35 @@ try_again:
 
        /* Check if request to the same host */
        if (stream != NULL) {
-         php_url *orig;
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"), (void **)&tmp) == SUCCESS &&
-                   (orig = (php_url *) zend_fetch_resource(tmp TSRMLS_CC, -1, "httpurl", NULL, 1, le_url)) != NULL &&
+               if (client->url &&
                    ((use_proxy && !use_ssl) ||
-                    (((use_ssl && orig->scheme != NULL && strcmp(orig->scheme, "https") == 0) ||
-                     (!use_ssl && orig->scheme == NULL) ||
-                     (!use_ssl && strcmp(orig->scheme, "https") != 0)) &&
-                    strcmp(orig->host, phpurl->host) == 0 &&
-                    orig->port == phpurl->port))) {
-    } else {
+                    (((use_ssl && client->url->scheme != NULL && strcmp(client->url->scheme, "https") == 0) ||
+                     (!use_ssl && client->url->scheme == NULL) ||
+                     (!use_ssl && strcmp(client->url->scheme, "https") != 0)) &&
+                    strcmp(client->url->host, phpurl->host) == 0 &&
+                    client->url->port == phpurl->port))) {
+               } else {
                        php_stream_close(stream);
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
+                       if (client->url) {
+                               php_url_free(client->url);
+                               client->url = NULL;
+                       }
+                       client->stream = NULL;
+                       client->use_proxy = 0;
                        stream = NULL;
                        use_proxy = 0;
-    }
+               }
        }
 
        /* Check if keep-alive connection is still opened */
        if (stream != NULL && !stream_alive(stream TSRMLS_CC)) {
                php_stream_close(stream);
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
+               if (client->url) {
+                       php_url_free(client->url);
+                       client->url = NULL;
+               }
+               client->stream = NULL;
+               client->use_proxy = 0;
                stream = NULL;
                use_proxy = 0;
        }
@@ -372,8 +370,8 @@ try_again:
                stream = http_connect(this_ptr, phpurl, use_ssl, &use_proxy TSRMLS_CC);
                if (stream) {
                        php_stream_auto_cleanup(stream);
-                       add_property_resource(this_ptr, "httpsocket", php_stream_get_resource_id(stream));
-                       add_property_long(this_ptr, "_use_proxy", use_proxy);
+                       client->stream = stream;
+                       client->use_proxy = use_proxy;
                } else {
                        php_url_free(phpurl);
                        if (request != buf) {efree(request);}
@@ -385,12 +383,11 @@ try_again:
        PG(allow_url_fopen) = old_allow_url_fopen;
 
        if (stream) {
-               zval **cookies, **login, **password;
-         int ret = zend_list_insert(phpurl, le_url);
-
-               add_property_resource(this_ptr, "httpurl", ret);
-               /*zend_list_addref(ret);*/
-
+               if (client->url) {
+                       php_url_free(client->url);
+                       client->url = NULL;
+               }
+               client->url = phpurl;
                smart_str_append_const(&soap_headers, "POST ");
                if (use_proxy && !use_ssl) {
                        smart_str_appends(&soap_headers, phpurl->scheme);
@@ -423,11 +420,10 @@ try_again:
                        "Connection: close\r\n"
                        "Accept: text/html; text/xml; text/plain\r\n"
 */
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent"), (void **)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                       if (Z_STRLEN_PP(tmp) > 0) {
+               if (client->user_agent) {
+                       if (client->user_agent[0] != 0) {
                                smart_str_append_const(&soap_headers, "User-Agent: ");
-                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                               smart_str_appends(&soap_headers, client->user_agent);
                                smart_str_append_const(&soap_headers, "\r\n");
                        }
                } else{
@@ -436,7 +432,7 @@ try_again:
 
                smart_str_append(&soap_headers, &soap_headers_z);
                smart_str_free(&soap_headers_z);
-               
+
                if (soap_version == SOAP_1_2) {
                        smart_str_append_const(&soap_headers,"Content-Type: application/soap+xml; charset=utf-8");
                        if (soapaction) {
@@ -458,12 +454,9 @@ try_again:
                smart_str_append_const(&soap_headers, "\r\n");
 
                /* HTTP Authentication */
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
-                   Z_TYPE_PP(login) == IS_STRING) {
-                       zval **digest;
-
-                       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"), (void **)&digest) == SUCCESS) {
-                               if (Z_TYPE_PP(digest) == IS_ARRAY) {
+               if (client->login) {
+                       if (client->digest) {
+                               if (client->digest == 2) {
                                        char          HA1[33], HA2[33], response[33], cnonce[33], nc[9];
                                        PHP_MD5_CTX   md5ctx;
                                        unsigned char hash[16];
@@ -474,39 +467,27 @@ try_again:
                                        PHP_MD5Final(hash, &md5ctx);
                                        make_digest(cnonce, hash);
 
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "nc", sizeof("nc"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_LONG) {
-                                               Z_LVAL_PP(tmp)++;
-                                               sprintf(nc, "%08ld", Z_LVAL_PP(tmp));
-                                       } else {
-                                               add_assoc_long(*digest, "nc", 1);
-                                               strcpy(nc, "00000001");
-                                       }
+                                       client->digest_nc++;
+                                       sprintf(nc, "%08ld", client->digest_nc);
 
                                        PHP_MD5Init(&md5ctx);
-                                       PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+                                       PHP_MD5Update(&md5ctx, (unsigned char*)client->login, strlen(client->login));
                                        PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "realm", sizeof("realm"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
-                                               PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                       if (client->digest_realm) {
+                                               PHP_MD5Update(&md5ctx, (unsigned char*)client->digest_realm, strlen(client->digest_realm));
                                        }
                                        PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
-                                       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
-                                           Z_TYPE_PP(password) == IS_STRING) {
-                                               PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(password), Z_STRLEN_PP(password));
+                                       if (client->password) {
+                                               PHP_MD5Update(&md5ctx, (unsigned char*)client->password, strlen(client->password));
                                        }
                                        PHP_MD5Final(hash, &md5ctx);
                                        make_digest(HA1, hash);
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "algorithm", sizeof("algorithm"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING &&
-                                           Z_STRLEN_PP(tmp) == sizeof("md5-sess")-1 &&
-                                           stricmp(Z_STRVAL_PP(tmp), "md5-sess") == 0) {
+                                       if (client->digest_algorithm && stricmp(client->digest_algorithm, "md5-sess") == 0) {
                                                PHP_MD5Init(&md5ctx);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
-                                               if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
-                                                   Z_TYPE_PP(tmp) == IS_STRING) {
-                                                       PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               if (client->digest_nonce) {
+                                                       PHP_MD5Update(&md5ctx, (unsigned char*)client->digest_nonce, strlen(client->digest_nonce));
                                                }
                                                PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
@@ -526,10 +507,7 @@ try_again:
 
                                        /* TODO: Support for qop="auth-int" */
 /*
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING &&
-                                           Z_STRLEN_PP(tmp) == sizeof("auth-int")-1 &&
-                                           stricmp(Z_STRVAL_PP(tmp), "auth-int") == 0) {
+                                       if (client->digest_qop && stricmp(client->digest_qop, "auth-int") == 0) {
                                                PHP_MD5Update(&md5ctx, ":", 1);
                                                PHP_MD5Update(&md5ctx, HEntity, HASHHEXLEN);
                                        }
@@ -540,13 +518,11 @@ try_again:
                                        PHP_MD5Init(&md5ctx);
                                        PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32);
                                        PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
-                                               PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                       if (client->digest_nonce) {
+                                               PHP_MD5Update(&md5ctx, (unsigned char*)client->digest_nonce, strlen(client->digest_nonce));
                                        }
                                        PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
+                                       if (client->digest_qop) {
                                                PHP_MD5Update(&md5ctx, (unsigned char*)nc, 8);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
@@ -558,18 +534,16 @@ try_again:
                                        PHP_MD5Update(&md5ctx, (unsigned char*)HA2, 32);
                                        PHP_MD5Final(hash, &md5ctx);
                                        make_digest(response, hash);
-       
+
                                        smart_str_append_const(&soap_headers, "Authorization: Digest username=\"");
-                                       smart_str_appendl(&soap_headers, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "realm", sizeof("realm"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
+                                       smart_str_appends(&soap_headers, client->login);
+                                       if (client->digest_realm) {
                                                smart_str_append_const(&soap_headers, "\", realm=\"");
-                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               smart_str_appends(&soap_headers, client->digest_realm);
                                        }
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
+                                       if (client->digest_nonce) {
                                                smart_str_append_const(&soap_headers, "\", nonce=\"");
-                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               smart_str_appends(&soap_headers, client->digest_nonce);
                                        }
                                        smart_str_append_const(&soap_headers, "\", uri=\"");
                                        if (phpurl->path) {
@@ -583,8 +557,7 @@ try_again:
                                                        smart_str_appendc(&soap_headers, '#');
                                                        smart_str_appends(&soap_headers, phpurl->fragment);
                                        }
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
+                                       if (client->digest_qop) {
                                        /* TODO: Support for qop="auth-int" */
                                                smart_str_append_const(&soap_headers, "\", qop=\"auth");
                                                smart_str_append_const(&soap_headers, "\", nc=\"");
@@ -594,10 +567,9 @@ try_again:
                                        }
                                        smart_str_append_const(&soap_headers, "\", response=\"");
                                        smart_str_appendl(&soap_headers, response, 32);
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "opaque", sizeof("opaque"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
+                                       if (client->digest_opaque) {
                                                smart_str_append_const(&soap_headers, "\", opaque=\"");
-                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               smart_str_appends(&soap_headers, client->digest_opaque);
                                        }
                                        smart_str_append_const(&soap_headers, "\"\r\n");
                                }
@@ -606,11 +578,10 @@ try_again:
                                int len;
 
                                smart_str auth = {0};
-                               smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+                               smart_str_appends(&auth, client->login);
                                smart_str_appendc(&auth, ':');
-                               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
-                                   Z_TYPE_PP(password) == IS_STRING) {
-                                       smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
+                               if (client->password) {
+                                       smart_str_appends(&auth, client->password);
                                }
                                smart_str_0(&auth);
                                buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
@@ -628,22 +599,22 @@ try_again:
                }
 
                /* Send cookies along with request */
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
+               if (client->cookies) {
                        zval **data;
                        zstr key;
                        int i, n;
 
-                       n = zend_hash_num_elements(Z_ARRVAL_PP(cookies));
+                       n = zend_hash_num_elements(Z_ARRVAL_P(client->cookies));
                        if (n > 0) {
-                               zend_hash_internal_pointer_reset(Z_ARRVAL_PP(cookies));
+                               zend_hash_internal_pointer_reset(Z_ARRVAL_P(client->cookies));
                                smart_str_append_const(&soap_headers, "Cookie: ");
                                for (i = 0; i < n; i++) {
-                                       zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data);
+                                       zend_hash_get_current_data(Z_ARRVAL_P(client->cookies), (void **)&data);
                                        /* TODO: unicode support */
-                                       zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE);
+                                       zend_hash_get_current_key(Z_ARRVAL_P(client->cookies), &key, NULL, FALSE);
 
                                        if (Z_TYPE_PP(data) == IS_ARRAY) {
-                                         zval** value;
+                                               zval** value;
 
                                                if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&value) == SUCCESS &&
                                                    Z_TYPE_PP(value) == IS_STRING) {
@@ -660,16 +631,18 @@ try_again:
                                                        }
                                                }
                                        }
-                                       zend_hash_move_forward(Z_ARRVAL_PP(cookies));
+                                       zend_hash_move_forward(Z_ARRVAL_P(client->cookies));
                                }
                                smart_str_append_const(&soap_headers, "\r\n");
                        }
                }
                smart_str_append_const(&soap_headers, "\r\n");
                smart_str_0(&soap_headers);
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
-                   Z_LVAL_PP(trace) > 0) {
-                       add_property_stringl(this_ptr, "__last_request_headers", soap_headers.c, soap_headers.len, 1);
+               if (client->trace) {
+                       if (client->last_request_headers) {
+                               efree(client->last_request_headers);
+                       }
+                       client->last_request_headers = estrndup(soap_headers.c, soap_headers.len);
                }
                smart_str_appendl(&soap_headers, request, request_size);
                smart_str_0(&soap_headers);
@@ -679,9 +652,12 @@ try_again:
                        if (request != buf) {efree(request);}
                        smart_str_free(&soap_headers);
                        php_stream_close(stream);
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
+                       if (client->url) {
+                               php_url_free(client->url);
+                               client->url = NULL;
+                       }
+                       client->stream = NULL;
+                       client->use_proxy = 0;
                        add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL TSRMLS_CC);
                        return FALSE;
                }
@@ -694,8 +670,8 @@ try_again:
 
        if (!buffer) {
                php_stream_close(stream);
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
+               client->stream = NULL;
+               client->use_proxy = 0;
                return TRUE;
        }
 
@@ -704,15 +680,17 @@ try_again:
                        if (http_headers) {efree(http_headers);}
                        if (request != buf) {efree(request);}
                        php_stream_close(stream);
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
-                       zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
+                       client->stream = NULL;
+                       client->use_proxy = 0;
                        add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL TSRMLS_CC);
                        return FALSE;
                }
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
-                   Z_LVAL_PP(trace) > 0) {
-                       add_property_stringl(this_ptr, "__last_response_headers", http_headers, http_header_size, 1);
+               if (client->trace) {
+                       if (client->last_response_headers) {
+                               efree(client->last_response_headers);
+                       }
+                       client->last_response_headers = estrndup(http_headers, http_header_size);
                }
 
                /* Check to see what HTTP status was sent */
@@ -758,13 +736,10 @@ try_again:
        while (cookie_itt) {
                char *end_pos, *cookie;
                char *eqpos, *sempos;
-               zval **cookies;
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE) {
-                       zval *tmp_cookies;
-                       MAKE_STD_ZVAL(tmp_cookies);
-                       array_init(tmp_cookies);
-                       zend_hash_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), &tmp_cookies, sizeof(zval *), (void **)&cookies);
+               if (!client->cookies) {
+                       MAKE_STD_ZVAL(client->cookies);
+                       array_init(client->cookies);
                }
 
                end_pos = strstr(cookie_itt,"\r\n");
@@ -822,7 +797,7 @@ try_again:
                                add_index_string(zcookie, 2, phpurl->host, 1);
                        }
 
-                       add_assoc_zval_ex(*cookies, name.c, name.len+1, zcookie);
+                       add_assoc_zval_ex(client->cookies, name.c, name.len+1, zcookie);
                        smart_str_free(&name);
                }
 
@@ -843,14 +818,14 @@ try_again:
                }
        } else {
                http_close = TRUE;
-       }       
+       }
 
        if (!get_http_body(stream, http_close, http_headers, &http_body, &http_body_size TSRMLS_CC)) {
                if (request != buf) {efree(request);}
                php_stream_close(stream);
                efree(http_headers);
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
+               client->stream = NULL;
+               client->use_proxy = 0;
                add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL TSRMLS_CC);
                if (http_msg) {
                        efree(http_msg);
@@ -887,8 +862,8 @@ try_again:
 
        if (http_close) {
                php_stream_close(stream);
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
+               client->stream = NULL;
+               client->use_proxy = 0;
                stream = NULL;
        }
 
@@ -926,20 +901,15 @@ try_again:
                }
        } else if (http_status == 401) {
                /* Digest authentication */
-               zval **digest, **login, **password;
                char *auth = get_http_header_value(http_headers, "WWW-Authenticate: ");
 
-               if (auth &&
-                               strstr(auth, "Digest") == auth &&
-                   (zend_hash_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"), (void **)&digest) == FAILURE ||
-                    Z_TYPE_PP(digest) != IS_ARRAY) &&
-                   zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
-                   Z_TYPE_PP(login) == IS_STRING &&
-                   zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
-                   Z_TYPE_PP(password) == IS_STRING) {
+               if (auth && strstr(auth, "Digest") == auth &&
+                   (client->digest < 2) &&
+                   client->login && client->password) {
                        char *s;
-                       zval *digest = NULL;
+                       php_url *new_url;
 
+                       client->digest = 2;
                        s = auth + sizeof("Digest")-1;
                        while (*s != '\0') {
                                char *name, *val;
@@ -968,36 +938,36 @@ try_again:
                                                        ++s;
                                                }
                                        }
-                                       if (digest == NULL) {
-                                               ALLOC_INIT_ZVAL(digest);
-                                               array_init(digest);
+                                       if (strcmp(name, "realm") == 0) {
+                                               client->digest_realm = estrdup(val);
+                                       } else if (strcmp(name, "algorithm") == 0) {
+                                               client->digest_algorithm = estrdup(val);
+                                       } else if (strcmp(name, "nonce") == 0) {
+                                               client->digest_nonce = estrdup(val);
+                                       } else if (strcmp(name, "qop") == 0) {
+                                               client->digest_qop = estrdup(val);
+                                       } else if (strcmp(name, "opaque") == 0) {
+                                               client->digest_opaque = estrdup(val);
                                        }
-                                       add_assoc_string(digest, name, val ,1);
                                }
                        }
 
-                       if (digest != NULL) {
-                               php_url *new_url  = emalloc(sizeof(php_url));
-
-                               digest->refcount--;
-                               add_property_zval_ex(this_ptr, "_digest", sizeof("_digest"), digest TSRMLS_CC);
-
-                               *new_url = *phpurl;
-                               if (phpurl->scheme) phpurl->scheme = estrdup(phpurl->scheme);
-                               if (phpurl->user) phpurl->user = estrdup(phpurl->user);
-                               if (phpurl->pass) phpurl->pass = estrdup(phpurl->pass);
-                               if (phpurl->host) phpurl->host = estrdup(phpurl->host);
-                               if (phpurl->path) phpurl->path = estrdup(phpurl->path);
-                               if (phpurl->query) phpurl->query = estrdup(phpurl->query);
-                               if (phpurl->fragment) phpurl->fragment = estrdup(phpurl->fragment);
-                               phpurl = new_url;
-
-                               efree(auth);
-                               efree(http_headers);
-                               efree(http_body);
+                       new_url  = emalloc(sizeof(php_url));
+                       *new_url = *phpurl;
+                       if (phpurl->scheme) phpurl->scheme = estrdup(phpurl->scheme);
+                       if (phpurl->user) phpurl->user = estrdup(phpurl->user);
+                       if (phpurl->pass) phpurl->pass = estrdup(phpurl->pass);
+                       if (phpurl->host) phpurl->host = estrdup(phpurl->host);
+                       if (phpurl->path) phpurl->path = estrdup(phpurl->path);
+                       if (phpurl->query) phpurl->query = estrdup(phpurl->query);
+                       if (phpurl->fragment) phpurl->fragment = estrdup(phpurl->fragment);
+                       phpurl = new_url;
+
+                       efree(auth);
+                       efree(http_headers);
+                       efree(http_body);
 
-                               goto try_again;
-                       }
+                       goto try_again;
                }
                if (auth) efree(auth);
        }
index c6d0c4b098a6fed043b31650b8d06876f76c87c4..f6f3dc1ebaf435f5f67e86cc4f001d92320361d1 100644 (file)
@@ -226,7 +226,7 @@ static int is_wsdl_element(xmlNodePtr node)
        return 1;
 }
 
-static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC)
+static void load_wsdl_ex(char *struri, sdlCtx *ctx, int include TSRMLS_DC)
 {
        sdlPtr tmpsdl = ctx->sdl;
        xmlDocPtr wsdl;
@@ -296,7 +296,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
                                        uri = xmlBuildURI(tmp->children->content, base);
                                        xmlFree(base);
                                }
-                               load_wsdl_ex(this_ptr, (char*)uri, ctx, 1 TSRMLS_CC);
+                               load_wsdl_ex((char*)uri, ctx, 1 TSRMLS_CC);
                                xmlFree(uri);
                        }
 
@@ -628,7 +628,7 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
        return parameters;
 }
 
-static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
+static sdlPtr load_wsdl(char *struri TSRMLS_DC)
 {
        sdlCtx ctx;
        int i,n;
@@ -645,7 +645,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
        zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
        zend_hash_init(&ctx.services,  0, NULL, NULL, 0);
 
-       load_wsdl_ex(this_ptr, struri,&ctx, 0 TSRMLS_CC);
+       load_wsdl_ex(struri,&ctx, 0 TSRMLS_CC);
        schema_pass2(&ctx);
 
        n = zend_hash_num_elements(&ctx.services);
@@ -3079,7 +3079,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
        char* old_error_code = SOAP_GLOBAL(error_code);
        int uri_len = 0;
        php_stream_context *context=NULL;
-       zval **tmp, **proxy_host, **proxy_port, *orig_context = NULL, *new_context = NULL;
+       zval *orig_context = NULL, *new_context = NULL;
        smart_str headers = {0};
        char* key = NULL;
        time_t t = time(0);
@@ -3131,45 +3131,44 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
                }
        }
 
-       if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
-                       "_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
-               context = php_stream_context_from_zval(*tmp, 0);
-       }
-
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
-           Z_TYPE_PP(proxy_host) == IS_STRING &&
-           zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
-           Z_TYPE_PP(proxy_port) == IS_LONG) {
-               zval str_port, *str_proxy;
-               smart_str proxy = {0};
-               str_port = **proxy_port;
-               zval_copy_ctor(&str_port);
-               convert_to_string(&str_port);
-               smart_str_appends(&proxy,"tcp://");
-               smart_str_appends(&proxy,Z_STRVAL_PP(proxy_host));
-               smart_str_appends(&proxy,":");
-               smart_str_appends(&proxy,Z_STRVAL(str_port));
-               smart_str_0(&proxy);
-               zval_dtor(&str_port);
-               MAKE_STD_ZVAL(str_proxy);
-               ZVAL_STRING(str_proxy, proxy.c, 1);
-               smart_str_free(&proxy);
-               
-               if (!context) {
-                       context = php_stream_context_alloc();
+       if (this_ptr) {
+               soap_client_object *client;
+
+               client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+
+               if (client->stream_context) {
+                       context = client->stream_context;
                }
-               php_stream_context_set_option(context, "http", "proxy", str_proxy);
-               zval_ptr_dtor(&str_proxy);
 
-               MAKE_STD_ZVAL(str_proxy);
-               ZVAL_BOOL(str_proxy, 1);
-               php_stream_context_set_option(context, "http", "request_fulluri", str_proxy);
-               zval_ptr_dtor(&str_proxy);
+               if (client->proxy_host) {
+                       zval *str_proxy;
+                       smart_str proxy = {0};
 
-               proxy_authentication(this_ptr, &headers TSRMLS_CC);
-       }
+                       smart_str_appends(&proxy,"tcp://");
+                       smart_str_appends(&proxy, client->proxy_host);
+                       smart_str_appends(&proxy,":");
+                       smart_str_append_unsigned(&proxy, client->proxy_port);
+                       smart_str_0(&proxy);
+                       MAKE_STD_ZVAL(str_proxy);
+                       ZVAL_STRING(str_proxy, proxy.c, 1);
+                       smart_str_free(&proxy);
+               
+                       if (!context) {
+                               context = php_stream_context_alloc();
+                       }
+                       php_stream_context_set_option(context, "http", "proxy", str_proxy);
+                       zval_ptr_dtor(&str_proxy);
+       
+                       MAKE_STD_ZVAL(str_proxy);
+                       ZVAL_BOOL(str_proxy, 1);
+                       php_stream_context_set_option(context, "http", "request_fulluri", str_proxy);
+                       zval_ptr_dtor(&str_proxy);
 
-       basic_authentication(this_ptr, &headers TSRMLS_CC);
+                       proxy_authentication(this_ptr, &headers TSRMLS_CC);
+               }
+
+               basic_authentication(this_ptr, &headers TSRMLS_CC);
+       }
 
        if (headers.len > 0) {
                zval *str_headers;
@@ -3194,7 +3193,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
 
        SOAP_GLOBAL(error_code) = "WSDL";
 
-       sdl = load_wsdl(this_ptr, uri TSRMLS_CC);
+       sdl = load_wsdl(uri TSRMLS_CC);
        if (sdl) {
                sdl->is_persistent = 0;
        }
index 03037b9d13eac09a97894b4ebfd621909479c5a6..af8870d8c3421cb694456069e8190628d3f86606 100644 (file)
@@ -49,8 +49,6 @@
 # define stricmp strcasecmp
 #endif
 
-extern int le_url;
-
 typedef struct _encodeType encodeType, *encodeTypePtr;
 typedef struct _encode encode, *encodePtr;
 
@@ -68,7 +66,6 @@ typedef struct _sdlSoapBindingFunction sdlSoapBindingFunction, *sdlSoapBindingFu
 typedef struct _sdlSoapBindingFunctionBody sdlSoapBindingFunctionBody, *sdlSoapBindingFunctionBodyPtr;
 
 typedef struct _soapMapping soapMapping, *soapMappingPtr;
-typedef struct _soapService soapService, *soapServicePtr;
 
 #include "php_xml.h"
 #include "php_encoding.h"
@@ -99,8 +96,16 @@ struct _soapMapping {
 
 struct _soapHeader;
 
-struct _soapService {
-       sdlPtr sdl;
+typedef struct _soap_server_object {
+       zend_object zo;
+
+       sdlPtr     sdl;
+       char      *uri;
+       HashTable *mapping;
+       int        version;
+       HashTable *class_map;
+       int        features;
+       xmlCharEncodingHandlerPtr encoding;
 
        struct _soap_functions {
                HashTable *ft;
@@ -114,16 +119,63 @@ struct _soapService {
                int persistance;
        } soap_class;
 
-       HashTable *mapping;
-       int        version;
        int        type;
        char      *actor;
+       struct _soapHeader **soap_headers_ptr;
+} soap_server_object;
+
+typedef struct _soap_client_object {
+       zend_object zo;
+
+       sdlPtr     sdl;
        char      *uri;
-       xmlCharEncodingHandlerPtr encoding;
+       HashTable *mapping;
+       int        version;
        HashTable *class_map;
        int        features;
-       struct _soapHeader **soap_headers_ptr;
-};
+       xmlCharEncodingHandlerPtr encoding;
+
+       int style;
+       int use;
+       char *location;
+
+       char *login;
+       char *password;
+       
+       long digest;
+       long digest_nc;
+       char *digest_realm;
+       char *digest_algorithm;
+       char *digest_nonce;
+       char *digest_qop;
+       char *digest_opaque;
+
+       char *proxy_host;
+       long proxy_port;
+       char *proxy_login;
+       char *proxy_password;
+       
+       char *user_agent;
+
+       long connection_timeout;
+       long compression;
+
+       php_stream_context *stream_context;
+       php_stream *stream;
+       php_url *url;
+       zend_bool use_proxy;
+
+       zend_bool exceptions;
+       zend_bool trace;
+       char *last_request_headers;
+       char *last_request;
+       char *last_response_headers;
+       char *last_response;
+
+       zval *default_headers;
+       zval *cookies;
+       zval *fault;
+} soap_client_object;
 
 #define SOAP_CLASS 1
 #define SOAP_FUNCTIONS 2
index 151f7214dffb83667e15a579bd1cd1da80363fec..530f82a337a557217274455ee591e3c7f8b74ba6 100644 (file)
 #endif
 #include "zend_exceptions.h"
 
-static int le_sdl = 0;
-int le_url = 0;
-static int le_service = 0;
-
 typedef struct _soapHeader {
        sdlFunctionPtr                    function;
        zval                              function_name;
@@ -47,7 +43,6 @@ typedef struct _soapHeader {
 static void function_to_string(sdlFunctionPtr function, smart_str *buf);
 static void type_to_string(sdlTypePtr type, smart_str *buf, int level);
 
-static void clear_soap_fault(zval *obj TSRMLS_DC);
 static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, char *name TSRMLS_DC);
 static void soap_server_fault(char* code, char* string, char *actor, zval* details, char *name TSRMLS_DC);
 static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader* hdr TSRMLS_DC);
@@ -62,9 +57,6 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
 static xmlNodePtr serialize_parameter(sdlParamPtr param,zval *param_val,int index,char *name, int style, xmlNodePtr parent TSRMLS_DC);
 static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, int style, xmlNodePtr parent TSRMLS_DC);
 
-static void delete_service(void *service);
-static void delete_url(void *handle);
-
 static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args);
 
 #define SOAP_SERVER_BEGIN_CODE() \
@@ -121,30 +113,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const
        if (ZEND_NUM_ARGS() != 0) \
                WRONG_PARAM_COUNT;
 
-#define FETCH_THIS_SDL(ss) \
-       { \
-               zval **__tmp; \
-               if(FIND_SDL_PROPERTY(this_ptr,__tmp) != FAILURE) { \
-                       FETCH_SDL_RES(ss,__tmp); \
-               } else { \
-                       ss = NULL; \
-               } \
-       }
-
-#define FIND_SDL_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "sdl", sizeof("sdl"), (void **)&tmp)
-#define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource(tmp TSRMLS_CC, -1, "sdl", NULL, 1, le_sdl)
-
-#define FETCH_THIS_SERVICE(ss) \
-       { \
-               zval **tmp; \
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr),"service", sizeof("service"), (void **)&tmp) != FAILURE) { \
-                       ss = (soapServicePtr)zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service); \
-               } else { \
-                       ss = NULL; \
-               } \
-       }
-
-static zend_class_entry* soap_class_entry;
+static zend_class_entry* soap_client_class_entry;
 static zend_class_entry* soap_server_class_entry;
 static zend_class_entry* soap_fault_class_entry;
 static zend_class_entry* soap_header_class_entry;
@@ -356,13 +325,13 @@ ZEND_INI_MH(OnUpdateCacheEnabled)
 
        if (new_value_length==2 && strcasecmp("on", new_value)==0) {
                *p = 1;
-       } 
+       }
        else if (new_value_length==3 && strcasecmp("yes", new_value)==0) {
                *p = 1;
-       } 
+       }
        else if (new_value_length==4 && strcasecmp("true", new_value)==0) {
                *p = 1;
-       } 
+       }
        else {
                *p = (long) (atoi(new_value) != 0);
        }
@@ -467,6 +436,201 @@ PHP_RINIT_FUNCTION(soap)
        return SUCCESS;
 }
 
+static void soap_server_dtor(void *object, zend_object_handle handle TSRMLS_DC)
+{
+       soap_server_object *service = (soap_server_object*)object;
+
+       if (service->soap_functions.ft) {
+               zend_hash_destroy(service->soap_functions.ft);
+               efree(service->soap_functions.ft);
+       }
+
+       if (service->mapping) {
+               zend_hash_destroy(service->mapping);
+               efree(service->mapping);
+       }
+
+       if (service->soap_class.argc) {
+               int i;
+               for (i = 0; i < service->soap_class.argc;i++) {
+                       zval_ptr_dtor(&service->soap_class.argv[i]);
+               }
+               efree(service->soap_class.argv);
+       }
+
+       if (service->actor) {
+               efree(service->actor);
+       }
+       if (service->uri) {
+               efree(service->uri);
+       }
+       if (service->sdl) {
+               delete_sdl(service->sdl);
+       }
+       if (service->encoding) {
+               xmlCharEncCloseFunc(service->encoding);
+       }
+       if (service->class_map) {
+               zend_hash_destroy(service->class_map);
+               FREE_HASHTABLE(service->class_map);
+       }
+       zend_object_std_dtor(object TSRMLS_CC);
+       efree(object);
+}
+
+static zend_object_value soap_server_ctor(zend_class_entry *ce TSRMLS_DC)
+{
+       zend_object_value new_value;
+       soap_server_object *obj = (soap_server_object*)emalloc(sizeof(soap_server_object));
+
+       memset(obj, 0, sizeof(soap_server_object));
+
+       zend_object_std_init(&obj->zo, ce TSRMLS_CC);
+
+       obj->sdl = NULL;
+       obj->uri = NULL;
+       obj->mapping = NULL;
+       obj->version = SOAP_1_1;
+       obj->class_map = NULL;
+       obj->features = 0;
+       obj->encoding = NULL;
+
+       obj->soap_functions.ft = NULL;
+       obj->soap_functions.functions_all = 1;
+
+       obj->soap_class.ce = NULL;
+       obj->soap_class.argv = NULL;
+       obj->soap_class.argc = 0;
+       obj->soap_class.persistance = SOAP_PERSISTENCE_REQUEST;
+
+       obj->type = SOAP_MAP_FUNCTION;
+       obj->actor = NULL;
+       obj->soap_headers_ptr = NULL;
+
+       new_value.handle = zend_objects_store_put(obj, soap_server_dtor, NULL, NULL TSRMLS_CC);
+       new_value.handlers = zend_get_std_object_handlers();
+
+       return new_value;
+}
+
+static void soap_client_dtor(void *object, zend_object_handle handle TSRMLS_DC)
+{
+       soap_client_object *client = (soap_client_object*)object;
+
+       if (client->mapping) {
+               zend_hash_destroy(client->mapping);
+               efree(client->mapping);
+       }
+       if (client->uri) {
+               efree(client->uri);
+       }
+       if (client->sdl) {
+               delete_sdl(client->sdl);
+       }
+       if (client->encoding) {
+               xmlCharEncCloseFunc(client->encoding);
+       }
+       if (client->class_map) {
+               zend_hash_destroy(client->class_map);
+               FREE_HASHTABLE(client->class_map);
+       }
+       if (client->location) {
+               efree(client->location);
+       }
+       if (client->login) {
+               efree(client->login);
+       }
+       if (client->password) {
+               efree(client->password);
+       }
+       if (client->digest_realm) {
+               efree(client->digest_realm);
+       }
+       if (client->digest_algorithm) {
+               efree(client->digest_algorithm);
+       }
+       if (client->digest_nonce) {
+               efree(client->digest_nonce);
+       }
+       if (client->digest_qop) {
+               efree(client->digest_qop);
+       }
+       if (client->digest_opaque) {
+               efree(client->digest_opaque);
+       }
+       if (client->proxy_host) {
+               efree(client->proxy_host);
+       }
+       if (client->proxy_login) {
+               efree(client->proxy_login);
+       }
+       if (client->proxy_password) {
+               efree(client->proxy_password);
+       }
+       if (client->user_agent) {
+               efree(client->user_agent);
+       }
+
+       if (client->last_request_headers) {
+               efree(client->last_request_headers);
+       }
+       if (client->last_request) {
+               efree(client->last_request);
+       }
+       if (client->last_response_headers) {
+               efree(client->last_response_headers);
+       }
+       if (client->last_response) {
+               efree(client->last_response);
+       }
+       if (client->stream) {
+               php_stream_close(client->stream);
+       }
+       if (client->url) {
+               php_url_free(client->url);
+       }
+       if (client->default_headers) {
+               zval_ptr_dtor(&client->default_headers);
+       }
+       if (client->cookies) {
+               zval_ptr_dtor(&client->cookies);
+       }
+       if (client->fault) {
+               zval_ptr_dtor(&client->fault);
+       }
+
+       zend_object_std_dtor(object TSRMLS_CC);
+       efree(object);
+}
+
+static zend_object_value soap_client_ctor(zend_class_entry *ce TSRMLS_DC)
+{
+       zend_object_value new_value;
+       soap_client_object *obj = (soap_client_object*)emalloc(sizeof(soap_client_object));
+
+       memset(obj, 0, sizeof(soap_client_object));
+
+       zend_object_std_init(&obj->zo, ce TSRMLS_CC);
+
+       obj->sdl = NULL;
+       obj->uri = NULL;
+       obj->mapping = NULL;
+       obj->version = SOAP_1_1;
+       obj->class_map = NULL;
+       obj->features = 0;
+       obj->encoding = NULL;
+
+       obj->use = SOAP_ENCODED;
+       obj->style = SOAP_RPC;
+
+       obj->exceptions = 1;
+
+       new_value.handle = zend_objects_store_put(obj, soap_client_dtor, NULL, NULL TSRMLS_CC);
+       new_value.handlers = zend_get_std_object_handlers();
+
+       return new_value;
+}
+
 PHP_MINIT_FUNCTION(soap)
 {
        zend_class_entry ce;
@@ -495,7 +659,8 @@ PHP_MINIT_FUNCTION(soap)
 
                INIT_OVERLOADED_CLASS_ENTRY(ce, PHP_SOAP_CLIENT_CLASSNAME, soap_client_functions,
                        (zend_function *)&fe, NULL, NULL);
-               soap_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+               soap_client_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+               soap_client_class_entry->create_object = soap_client_ctor;
        }
 
        /* Register SoapVar class */
@@ -505,6 +670,7 @@ PHP_MINIT_FUNCTION(soap)
        /* Register SoapServer class */
        INIT_CLASS_ENTRY(ce, PHP_SOAP_SERVER_CLASSNAME, soap_server_functions);
        soap_server_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+       soap_server_class_entry->create_object = soap_server_ctor;
 
        /* Register SoapFault class */
        INIT_CLASS_ENTRY(ce, PHP_SOAP_FAULT_CLASSNAME, soap_fault_functions);
@@ -517,10 +683,6 @@ PHP_MINIT_FUNCTION(soap)
        INIT_CLASS_ENTRY(ce, PHP_SOAP_HEADER_CLASSNAME, soap_header_functions);
        soap_header_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
 
-       le_sdl = register_list_destructors(delete_sdl, NULL);
-       le_url = register_list_destructors(delete_url, NULL);
-       le_service = register_list_destructors(delete_service, NULL);
-
        REGISTER_LONG_CONSTANT("SOAP_1_1", SOAP_1_1, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("SOAP_1_2", SOAP_1_2, CONST_CS | CONST_PERSISTENT);
 
@@ -698,7 +860,7 @@ PHP_METHOD(SoapHeader, SoapHeader)
        zend_uchar name_type, ns_type;
        zend_bool must_understand = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tt|zbz", 
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tt|zbz",
                        &ns, &ns_len, &ns_type, &name, &name_len, &name_type,
                        &data, &must_understand, &actor) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
@@ -766,7 +928,7 @@ PHP_METHOD(SoapFault, SoapFault)
                fault_code_len = Z_STRLEN_P(code);
        } else if (Z_TYPE_P(code) == IS_UNICODE) {
                fault_code = soap_unicode_to_string(Z_USTRVAL_P(code), Z_USTRLEN_P(code) TSRMLS_CC);
-               fault_code_len = strlen(fault_code);            
+               fault_code_len = strlen(fault_code);
        } else if (Z_TYPE_P(code) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(code)) == 2) {
                zval **t_ns, **t_code;
 
@@ -788,7 +950,7 @@ PHP_METHOD(SoapFault, SoapFault)
                                fault_code_len = Z_STRLEN_PP(t_code);
                        } else {
                                fault_code = soap_unicode_to_string(Z_USTRVAL_PP(t_code), Z_USTRLEN_PP(t_code) TSRMLS_CC);
-                               fault_code_len = strlen(fault_code);            
+                               fault_code_len = strlen(fault_code);
                        }
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters. Invalid fault code.");
@@ -887,7 +1049,7 @@ PHP_METHOD(SoapVar, SoapVar)
        int stype_len, ns_len, name_len, namens_len;
        zend_uchar stype_type, ns_type, name_type, namens_type;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!z|tttt", 
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!z|tttt",
                        &data, &type,
                        &stype, &stype_len, &stype_type,
                        &ns, &ns_len, &ns_type,
@@ -946,10 +1108,9 @@ PHP_METHOD(SoapVar, SoapVar)
    SoapServer constructor */
 PHP_METHOD(SoapServer, SoapServer)
 {
-       soapServicePtr service;
+       soap_server_object *service;
        zval *zwsdl, *options = NULL;
        char *wsdl = NULL;
-       int ret;
        int version = SOAP_1_1;
        zend_bool cache_wsdl;
 
@@ -969,8 +1130,7 @@ PHP_METHOD(SoapServer, SoapServer)
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
        }
 
-       service = emalloc(sizeof(soapService));
-       memset(service, 0, sizeof(soapService));
+       service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
 
        cache_wsdl = SOAP_GLOBAL(cache);
 
@@ -990,9 +1150,9 @@ PHP_METHOD(SoapServer, SoapServer)
                                service->uri = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                        } else if (Z_TYPE_PP(tmp) == IS_UNICODE) {
                                service->uri = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
-                       }       
+                       }
                }
-               
+
                if (zend_hash_find(ht, "actor", sizeof("actor"), (void**)&tmp) == SUCCESS) {
                        if (Z_TYPE_PP(tmp) == IS_STRING) {
                                service->actor = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
@@ -1055,7 +1215,7 @@ PHP_METHOD(SoapServer, SoapServer)
        zend_u_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
 
        if (wsdl) {
-               service->sdl = get_sdl(this_ptr, wsdl, cache_wsdl TSRMLS_CC);
+               service->sdl = get_sdl(NULL, wsdl, cache_wsdl TSRMLS_CC);
                if (service->uri == NULL) {
                        if (service->sdl->target_ns) {
                                service->uri = estrdup(service->sdl->target_ns);
@@ -1067,9 +1227,6 @@ PHP_METHOD(SoapServer, SoapServer)
                efree(wsdl);
        }
 
-       ret = zend_list_insert(service, le_service);
-       add_property_resource(this_ptr, "service", ret);
-
        SOAP_SERVER_END_CODE();
 }
 /* }}} */
@@ -1089,7 +1246,7 @@ PHP_FUNCTION(PHP_SOAP_SERVER_CLASS, map)
                *to_zval_before = NULL, *to_zval = NULL, *to_zval_after = NULL;
        int type_len, class_name_len;
        char *ns, *ctype;
-       soapServicePtr service;
+       soap_server_object *service;
 
        SOAP_SERVER_BEGIN_CODE();
 
@@ -1200,12 +1357,12 @@ PHP_FUNCTION(PHP_SOAP_SERVER_CLASS, map)
    Sets persistence mode of SoapServer */
 PHP_METHOD(SoapServer, setPersistence)
 {
-       soapServicePtr service;
+       soap_server_object *service;
        long value;
 
        SOAP_SERVER_BEGIN_CODE();
 
-       FETCH_THIS_SERVICE(service);
+       service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) != FAILURE) {
                if (service->type == SOAP_CLASS) {
@@ -1229,14 +1386,14 @@ PHP_METHOD(SoapServer, setPersistence)
    Sets class which will handle SOAP requests */
 PHP_METHOD(SoapServer, setClass)
 {
-       soapServicePtr service;
+       soap_server_object *service;
        zend_class_entry **ce;
        int found, argc;
        zval ***argv;
 
        SOAP_SERVER_BEGIN_CODE();
 
-       FETCH_THIS_SERVICE(service);
+       service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
 
        argc = ZEND_NUM_ARGS();
        argv = safe_emalloc(argc, sizeof(zval **), 0);
@@ -1279,13 +1436,13 @@ PHP_METHOD(SoapServer, setClass)
    Returns list of defined functions */
 PHP_METHOD(SoapServer, getFunctions)
 {
-       soapServicePtr  service;
-       HashTable      *ft = NULL;
+       soap_server_object *service;
+       HashTable *ft = NULL;
 
        SOAP_SERVER_BEGIN_CODE();
 
        ZERO_PARAM()
-       FETCH_THIS_SERVICE(service);
+       service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
 
        array_init(return_value);
        if (service->type == SOAP_CLASS) {
@@ -1324,13 +1481,13 @@ PHP_METHOD(SoapServer, getFunctions)
    Adds one or several functions those will handle SOAP requests */
 PHP_METHOD(SoapServer, addFunction)
 {
-       soapServicePtr service;
+       soap_server_object *service;
        zval *function_name, *function_copy;
        HashPosition pos;
 
        SOAP_SERVER_BEGIN_CODE();
 
-       FETCH_THIS_SERVICE(service);
+       service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &function_name) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
@@ -1417,7 +1574,7 @@ PHP_METHOD(SoapServer, handle)
 {
        int soap_version, old_soap_version;
        sdlPtr old_sdl = NULL;
-       soapServicePtr service;
+       soap_server_object *service;
        xmlDocPtr doc_request=NULL, doc_return;
        zval function_name, **params, **raw_post, *soap_obj, retval;
        char *fn_name, cont_len[30];
@@ -1434,7 +1591,7 @@ PHP_METHOD(SoapServer, handle)
 
        SOAP_SERVER_BEGIN_CODE();
 
-       FETCH_THIS_SERVICE(service);
+       service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        SOAP_GLOBAL(soap_version) = service->version;
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &arg, &arg_len) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
@@ -1536,7 +1693,7 @@ PHP_METHOD(SoapServer, handle)
                                } else {
                                        doc_request = soap_xmlParseMemory(Z_STRVAL_PP(raw_post),Z_STRLEN_PP(raw_post));
                                }
-                       } else {                                
+                       } else {
                                /* unicode */
                                /* TODO: remove unicode->string conversion */
                                char *str_req = soap_unicode_to_string(Z_USTRVAL_PP(raw_post), Z_USTRLEN_PP(raw_post) TSRMLS_CC);
@@ -1833,7 +1990,7 @@ PHP_METHOD(SoapServer, handle)
 
                if (size == 0) {
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Dump memory failed");
-               }       
+               }
 
                sprintf(cont_len, "Content-Length: %d", size);
                sapi_add_header(cont_len, strlen(cont_len), 1);
@@ -1921,13 +2078,13 @@ PHP_METHOD(SoapServer, fault)
 
 PHP_METHOD(SoapServer, addSoapHeader)
 {
-       soapServicePtr service;
+       soap_server_object *service;
        zval *fault;
        soapHeader **p;
 
        SOAP_SERVER_BEGIN_CODE();
 
-       FETCH_THIS_SERVICE(service);
+       service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
 
        if (!service || !service->soap_headers_ptr) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "The SoapServer::addSoapHeader function may be called only during SOAP request processing");
@@ -2020,16 +2177,16 @@ static void soap_error_handler(int error_num, const char *error_filename, const
 
        if (SOAP_GLOBAL(error_object) &&
            Z_TYPE_P(SOAP_GLOBAL(error_object)) == IS_OBJECT &&
-           instanceof_function(Z_OBJCE_P(SOAP_GLOBAL(error_object)), soap_class_entry TSRMLS_CC)) {
-               zval **tmp;
+           instanceof_function(Z_OBJCE_P(SOAP_GLOBAL(error_object)), soap_client_class_entry TSRMLS_CC)) {
+               soap_client_object *client;
 
-               if ((error_num == E_USER_ERROR || 
-                    error_num == E_COMPILE_ERROR || 
+               client = (soap_client_object*)zend_object_store_get_object(SOAP_GLOBAL(error_object) TSRMLS_CC);
+               if ((error_num == E_USER_ERROR ||
+                    error_num == E_COMPILE_ERROR ||
                     error_num == E_CORE_ERROR ||
-                    error_num == E_ERROR || 
+                    error_num == E_ERROR ||
                     error_num == E_PARSE) &&
-                   (zend_hash_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object)), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
-                    Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
+                   client->exceptions) {
                        zval *fault, *exception;
                        char* code = SOAP_GLOBAL(error_code);
                        char *buffer;
@@ -2078,10 +2235,10 @@ static void soap_error_handler(int error_num, const char *error_filename, const
                zval fault_obj;
                va_list argcopy;
 
-               if (error_num == E_USER_ERROR || 
-                   error_num == E_COMPILE_ERROR || 
+               if (error_num == E_USER_ERROR ||
+                   error_num == E_COMPILE_ERROR ||
                    error_num == E_CORE_ERROR ||
-                   error_num == E_ERROR || 
+                   error_num == E_ERROR ||
                    error_num == E_PARSE) {
 
                        char* code = SOAP_GLOBAL(error_code);
@@ -2168,7 +2325,9 @@ PHP_METHOD(SoapClient, SoapClient)
        int  soap_version = SOAP_1_1;
        php_stream_context *context = NULL;
        zend_bool cache_wsdl;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        SOAP_CLIENT_BEGIN_CODE();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &zwsdl, &options) == FAILURE) {
@@ -2179,7 +2338,7 @@ PHP_METHOD(SoapClient, SoapClient)
        if (Z_TYPE_P(zwsdl) == IS_STRING) {
                wsdl = estrndup(Z_STRVAL_P(zwsdl), Z_STRLEN_P(zwsdl));
        } else if (Z_TYPE_P(zwsdl) == IS_UNICODE) {
-               wsdl = soap_unicode_to_string(Z_USTRVAL_P(zwsdl), Z_USTRLEN_P(zwsdl) TSRMLS_CC);                
+               wsdl = soap_unicode_to_string(Z_USTRVAL_P(zwsdl), Z_USTRLEN_P(zwsdl) TSRMLS_CC);
        } else if (Z_TYPE_P(zwsdl) != IS_NULL ) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "$wsdl must be string or null");
                return;
@@ -2198,9 +2357,9 @@ PHP_METHOD(SoapClient, SoapClient)
                        if (zend_hash_find(ht, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
                                (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                                if (Z_TYPE_PP(tmp) == IS_STRING) {
-                                       add_property_stringl(this_ptr, "uri", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                                       client->uri = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                                } else {
-                                       add_property_unicodel(this_ptr, "uri", Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
+                                       client->uri = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
                                }
                        } else {
                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "'uri' option is requred in nonWSDL mode");
@@ -2210,13 +2369,13 @@ PHP_METHOD(SoapClient, SoapClient)
                        if (zend_hash_find(ht, "style", sizeof("style"), (void**)&tmp) == SUCCESS &&
                                        Z_TYPE_PP(tmp) == IS_LONG &&
                                        (Z_LVAL_PP(tmp) == SOAP_RPC || Z_LVAL_PP(tmp) == SOAP_DOCUMENT)) {
-                               add_property_long(this_ptr, "style", Z_LVAL_PP(tmp));
+                               client->style = Z_LVAL_PP(tmp);
                        }
 
                        if (zend_hash_find(ht, "use", sizeof("use"), (void**)&tmp) == SUCCESS &&
                                        Z_TYPE_PP(tmp) == IS_LONG &&
                                        (Z_LVAL_PP(tmp) == SOAP_LITERAL || Z_LVAL_PP(tmp) == SOAP_ENCODED)) {
-                               add_property_long(this_ptr, "use", Z_LVAL_PP(tmp));
+                               client->use = Z_LVAL_PP(tmp);
                        }
                }
 
@@ -2228,9 +2387,9 @@ PHP_METHOD(SoapClient, SoapClient)
                if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
                    (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                        if (Z_TYPE_PP(tmp) == IS_STRING) {
-                               add_property_stringl(this_ptr, "location", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                               client->location = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                        } else {
-                               add_property_unicodel(this_ptr, "location", Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
+                               client->location = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
                        }
                } else if (wsdl == NULL) {
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' option is requred in nonWSDL mode");
@@ -2246,48 +2405,48 @@ PHP_METHOD(SoapClient, SoapClient)
                if (zend_hash_find(ht, "login", sizeof("login"), (void**)&tmp) == SUCCESS &&
                    (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                    if (Z_TYPE_PP(tmp) == IS_STRING) {
-                               add_property_stringl(this_ptr, "_login", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                       client->login = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                        } else {
-                               add_property_unicodel(this_ptr, "_login", Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
+                       client->login = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
                        }
                        if (zend_hash_find(ht, "password", sizeof("password"), (void**)&tmp) == SUCCESS &&
                            (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                            if (Z_TYPE_PP(tmp) == IS_STRING) {
-                                       add_property_stringl(this_ptr, "_password", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                               client->password = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                                } else {
-                                       add_property_unicodel(this_ptr, "_password", Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
+                               client->password = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
                                }
                        }
                        if (zend_hash_find(ht, "authentication", sizeof("authentication"), (void**)&tmp) == SUCCESS &&
                            Z_TYPE_PP(tmp) == IS_LONG &&
                            Z_LVAL_PP(tmp) == SOAP_AUTHENTICATION_DIGEST) {
-                               add_property_null(this_ptr, "_digest");
+                           client->digest = 1;
                        }
                }
                if (zend_hash_find(ht, "proxy_host", sizeof("proxy_host"), (void**)&tmp) == SUCCESS &&
                    (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                    if (Z_TYPE_PP(tmp) == IS_STRING) {
-                               add_property_stringl(this_ptr, "_proxy_host", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                       client->proxy_host = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                        } else {
-                               add_property_unicodel(this_ptr, "_proxy_host", Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
-                       }
+                       client->proxy_host = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
+                   }
                        if (zend_hash_find(ht, "proxy_port", sizeof("proxy_port"), (void**)&tmp) == SUCCESS &&
                            Z_TYPE_PP(tmp) == IS_LONG) {
-                               add_property_long(this_ptr, "_proxy_port", Z_LVAL_PP(tmp));
+                               client->proxy_port = Z_LVAL_PP(tmp);
                        }
                        if (zend_hash_find(ht, "proxy_login", sizeof("proxy_login"), (void**)&tmp) == SUCCESS &&
                            (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                            if (Z_TYPE_PP(tmp) == IS_STRING) {
-                                       add_property_stringl(this_ptr, "_proxy_login", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                               client->proxy_login = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                                } else {
-                                       add_property_unicodel(this_ptr, "_proxy_login", Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
+                               client->proxy_login = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
                                }
                                if (zend_hash_find(ht, "proxy_password", sizeof("proxy_password"), (void**)&tmp) == SUCCESS &&
                                    (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                                    if (Z_TYPE_PP(tmp) == IS_STRING) {
-                                               add_property_stringl(this_ptr, "_proxy_password", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                                       client->proxy_password = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                                        } else {
-                                               add_property_unicodel(this_ptr, "_proxy_password", Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
+                                       client->proxy_password = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
                                        }
                                }
                        }
@@ -2306,68 +2465,77 @@ PHP_METHOD(SoapClient, SoapClient)
                if (zend_hash_find(ht, "trace", sizeof("trace"), (void**)&tmp) == SUCCESS &&
                    (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) &&
                                Z_LVAL_PP(tmp) == 1) {
-                       add_property_long(this_ptr, "trace", 1);
+                       client->trace = 1;
                }
                if (zend_hash_find(ht, "exceptions", sizeof("exceptions"), (void**)&tmp) == SUCCESS &&
                    (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) &&
                                Z_LVAL_PP(tmp) == 0) {
-                       add_property_bool(this_ptr, "_exceptions", 0);
+                       client->exceptions = 0;
                }
                if (zend_hash_find(ht, "compression", sizeof("compression"), (void**)&tmp) == SUCCESS &&
                    Z_TYPE_PP(tmp) == IS_LONG &&
-             zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate")) &&
-             zend_hash_exists(EG(function_table), "gzdeflate", sizeof("gzdeflate")) &&
-             zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")) &&
-             zend_hash_exists(EG(function_table), "gzcompress", sizeof("gzcompress")) &&
-             zend_hash_exists(EG(function_table), "gzencode", sizeof("gzencode"))) {
-                       add_property_long(this_ptr, "compression", Z_LVAL_PP(tmp));
+                   zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate")) &&
+                   zend_hash_exists(EG(function_table), "gzdeflate", sizeof("gzdeflate")) &&
+                   zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")) &&
+                   zend_hash_exists(EG(function_table), "gzcompress", sizeof("gzcompress")) &&
+                   zend_hash_exists(EG(function_table), "gzencode", sizeof("gzencode"))) {
+                       client->compression = Z_LVAL_PP(tmp);
                }
                if (zend_hash_find(ht, "encoding", sizeof("encoding"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
+                   (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
                        xmlCharEncodingHandlerPtr encoding;
-               
-                       encoding = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
-       if (encoding == NULL) {
-                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_PP(tmp));
-           } else {
-                   xmlCharEncCloseFunc(encoding);
-                               add_property_stringl(this_ptr, "_encoding", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);                     
+                       char *str;
+
+                       if (Z_TYPE_PP(tmp) == IS_UNICODE) {
+                               str = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
+                       } else {
+                               str = Z_STRVAL_PP(tmp);
+                       }
+                       encoding = xmlFindCharEncodingHandler(str);
+                       if (encoding == NULL) {
+                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments. Invalid 'encoding' option - '%v'.", Z_TYPE_PP(tmp), Z_UNIVAL_PP(tmp));
+                       } else {
+                               client->encoding = encoding;
+                       }
+                       if (Z_TYPE_PP(tmp) == IS_UNICODE) {
+                               efree(str);
                        }
                }
                if (zend_hash_find(ht, "classmap", sizeof("classmap"), (void**)&tmp) == SUCCESS &&
                        Z_TYPE_PP(tmp) == IS_ARRAY) {
-                       zval *class_map;
+                       zval *ztmp;
 
-                       MAKE_STD_ZVAL(class_map);
-                       *class_map = **tmp;
-                       INIT_PZVAL(class_map);
-                       zval_copy_ctor(class_map);
-                       class_map->refcount--;
-                       add_property_zval(this_ptr, "_classmap", class_map);
+                       ALLOC_HASHTABLE(client->class_map);
+                       zend_u_hash_init(client->class_map, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
+                       zend_hash_copy(client->class_map, (*tmp)->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &ztmp, sizeof(zval *));
                }
 
                if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS &&
                        Z_TYPE_PP(tmp) == IS_LONG) {
-                       add_property_long(this_ptr, "_features", Z_LVAL_PP(tmp));
+                       client->features = Z_LVAL_PP(tmp);
            }
 
                if (zend_hash_find(ht, "connection_timeout", sizeof("connection_timeout"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_LONG && Z_LVAL_PP(tmp) > 0) {
-                       add_property_long(this_ptr, "_connection_timeout", Z_LVAL_PP(tmp));
+                   Z_TYPE_PP(tmp) == IS_LONG && Z_LVAL_PP(tmp) >= 0) {
+                   client->connection_timeout = Z_LVAL_PP(tmp);
                }
 
                if (context) {
-                       add_property_resource(this_ptr, "_stream_context", context->rsrc_id);
+                       client->stream_context = context;
                }
-       
+
                if (zend_hash_find(ht, "cache_wsdl", sizeof("cache_wsdl"), (void**)&tmp) == SUCCESS &&
                    Z_TYPE_PP(tmp) == IS_LONG) {
                        cache_wsdl = Z_LVAL_PP(tmp);
                }
 
                if (zend_hash_find(ht, "user_agent", sizeof("user_agent"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                       add_property_stringl(this_ptr, "_user_agent", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+                   (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE)) {
+                   if (Z_TYPE_PP(tmp) == IS_STRING) {
+                       client->user_agent = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                       } else {
+                       client->user_agent = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
+                       }
                }
 
        } else if (wsdl == NULL) {
@@ -2375,19 +2543,18 @@ PHP_METHOD(SoapClient, SoapClient)
                return;
        }
 
-       add_property_long(this_ptr, "_soap_version", soap_version);
+       client->version = soap_version;
 
        if (wsdl) {
-               int    old_soap_version, ret;
+               int    old_soap_version;
                sdlPtr sdl;
 
                old_soap_version = SOAP_GLOBAL(soap_version);
                SOAP_GLOBAL(soap_version) = soap_version;
 
                sdl = get_sdl(this_ptr, wsdl, cache_wsdl TSRMLS_CC);
-               ret = zend_list_insert(sdl, le_sdl);
 
-               add_property_resource(this_ptr, "sdl", ret);
+               client->sdl = sdl;
 
                SOAP_GLOBAL(soap_version) = old_soap_version;
                efree(wsdl);
@@ -2404,9 +2571,9 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
        int    buf_size;
        zval   func, param0, param1, param2, param3, param4;
        zval  *params[5];
-       zval **trace;
-       zval **fault;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        INIT_ZVAL(*response);
 
        xmlDocDumpMemory(request, (xmlChar**)&buf, &buf_size);
@@ -2415,9 +2582,11 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
                return FALSE;
        }
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
-           Z_LVAL_PP(trace) > 0) {
-               add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1);
+       if (client->trace) {
+               if (client->last_request) {
+                       efree(client->last_request);
+               }
+               client->last_request = estrndup(buf, buf_size);
        }
 
        INIT_ZVAL(func);
@@ -2453,7 +2622,7 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
                add_soap_fault(this_ptr, "Client", "SoapSlient::__doRequest() failed", NULL, NULL TSRMLS_CC);
                ret = FALSE;
        } else if (Z_TYPE_P(response) != IS_STRING && Z_TYPE_P(response) != IS_UNICODE) {
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == FAILURE) {
+               if (!client->fault) {
                        add_soap_fault(this_ptr, "Client", "SoapSlient::__doRequest() returned non string value", NULL, NULL TSRMLS_CC);
                }
                ret = FALSE;
@@ -2461,16 +2630,18 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
            if (Z_TYPE_P(response) == IS_UNICODE) {
                zval_unicode_to_string_ex(response, ZEND_U_CONVERTER(UG(runtime_encoding_conv)) TSRMLS_CC);
            }
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
-                   Z_LVAL_PP(trace) > 0) {
-                       add_property_stringl(this_ptr, "__last_response", Z_STRVAL_P(response), Z_STRLEN_P(response), 1);
+               if (client->trace) {
+                       if (client->last_response) {
+                               efree(client->last_response);
+                       }
+                       client->last_response = estrndup(Z_STRVAL_P(response), Z_STRLEN_P(response));
                }
        }
        xmlFree(buf);
-       if (ret && zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
-         return FALSE;
-       }         
-  return ret;
+       if (ret && client->fault) {
+               return FALSE;
+       }
+       return ret;
 }
 
 static void do_soap_call(zval* this_ptr,
@@ -2486,8 +2657,6 @@ static void do_soap_call(zval* this_ptr,
                          zval* output_headers
                          TSRMLS_DC)
 {
-       zval **tmp;
-       zval **trace;
        sdlPtr sdl = NULL;
        sdlPtr old_sdl = NULL;
        sdlFunctionPtr fn;
@@ -2498,68 +2667,44 @@ static void do_soap_call(zval* this_ptr,
        xmlCharEncodingHandlerPtr old_encoding;
        HashTable *old_class_map;
        int old_features;
-       int free_location = 0;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        SOAP_CLIENT_BEGIN_CODE();
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS
-               && Z_LVAL_PP(trace) > 0) {
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "__last_request", sizeof("__last_request"));
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response"));
-       }
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_soap_version", sizeof("_soap_version"), (void **) &tmp) == SUCCESS
-               && Z_LVAL_PP(tmp) == SOAP_1_2) {
-               soap_version = SOAP_1_2;
-       } else {
-               soap_version = SOAP_1_1;
+       if (client->trace) {
+               if (client->last_request) {
+                       efree(client->last_request);
+                       client->last_request = NULL;
+               }
+               if (client->last_response) {
+                       efree(client->last_response);
+                       client->last_response = NULL;
+               }
        }
 
+       soap_version = client->version;
+
        if (location == NULL) {
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS) {
-                       if (Z_TYPE_PP(tmp) == IS_STRING) {
-                               location = Z_STRVAL_PP(tmp);
-                       } else if (Z_TYPE_PP(tmp) == IS_UNICODE) {
-                               free_location = 1;
-                               location = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
-                       }
-           }
+               location = client->location;
        }
 
-       if (FIND_SDL_PROPERTY(this_ptr,tmp) != FAILURE) {
-               FETCH_SDL_RES(sdl,tmp);
-       }
+       sdl = client->sdl;
 
-       clear_soap_fault(this_ptr TSRMLS_CC);
+       if (client->fault) {
+               zval_ptr_dtor(&client->fault);
+               client->fault = NULL;
+       }
 
        SOAP_GLOBAL(soap_version) = soap_version;
        old_sdl = SOAP_GLOBAL(sdl);
        SOAP_GLOBAL(sdl) = sdl;
        old_encoding = SOAP_GLOBAL(encoding);
-       SOAP_GLOBAL(encoding) = NULL;
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_encoding", sizeof("_encoding"), (void **) &tmp) == SUCCESS) {
-               if (Z_TYPE_PP(tmp) == IS_STRING) {
-                       SOAP_GLOBAL(encoding) = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
-               } else if (Z_TYPE_PP(tmp) == IS_UNICODE) {
-                       char *encoding_str = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC);
-
-                       SOAP_GLOBAL(encoding) = xmlFindCharEncodingHandler(encoding_str);
-                       efree(encoding_str);
-               }
-       }
+       SOAP_GLOBAL(encoding) = client->encoding;
        old_class_map = SOAP_GLOBAL(class_map);
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_classmap", sizeof("_classmap"), (void **) &tmp) == SUCCESS &&
-           Z_TYPE_PP(tmp) == IS_ARRAY) {
-               SOAP_GLOBAL(class_map) = (*tmp)->value.ht;
-       } else {
-               SOAP_GLOBAL(class_map) = NULL;
-       }
+       SOAP_GLOBAL(class_map) = client->class_map;
        old_features = SOAP_GLOBAL(features);
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_features", sizeof("_features"), (void **) &tmp) == SUCCESS &&
-           Z_TYPE_PP(tmp) == IS_LONG) {
-               SOAP_GLOBAL(features) = Z_LVAL_PP(tmp);
-       } else {
-               SOAP_GLOBAL(features) = 0;
-       }
+       SOAP_GLOBAL(features) = client->features;
 
        if (sdl != NULL) {
                fn = get_function(sdl, function);
@@ -2603,23 +2748,15 @@ static void do_soap_call(zval* this_ptr,
                        smart_str_free(&error);
                }
        } else {
-               zval **uri;
                smart_str action = {0};
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) {
+               if (!client->uri) {
                        add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC);
                } else if (location == NULL) {
                        add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
                } else {
-                       int free_uri = 0;
-
                        if (call_uri == NULL) {
-                               if (Z_TYPE_PP(uri) == IS_STRING) {
-                                       call_uri = Z_STRVAL_PP(uri);
-                               } else if (Z_TYPE_PP(uri) == IS_UNICODE) {
-                                       free_uri = 1;
-                                       call_uri = soap_unicode_to_string(Z_USTRVAL_PP(uri), Z_USTRLEN_PP(uri) TSRMLS_CC);
-                               }
+                               call_uri = client->uri;
                        }
                        request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
 
@@ -2632,10 +2769,6 @@ static void do_soap_call(zval* this_ptr,
                        }
                        smart_str_0(&action);
 
-                       if (free_uri) {
-                               efree(call_uri);
-                       }
-
                        ret = do_request(this_ptr, request, location, action.c, soap_version, 0, &response TSRMLS_CC);
 
                        smart_str_free(&action);
@@ -2650,25 +2783,25 @@ static void do_soap_call(zval* this_ptr,
        }
 
        if (!ret) {
-               zval** fault;
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
-                       *return_value = **fault;
+               if (client->fault) {
+                       *return_value = *client->fault;
                        zval_copy_ctor(return_value);
+                       INIT_PZVAL(return_value);
                } else {
                        *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC);
                        zval_copy_ctor(return_value);
+                       INIT_PZVAL(return_value);
                }
        } else {
-               zval** fault;
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
-                       *return_value = **fault;
+               if (client->fault) {
+                       *return_value = *client->fault;
                        zval_copy_ctor(return_value);
+                       INIT_PZVAL(return_value);
                }
        }
        if (Z_TYPE_P(return_value) == IS_OBJECT &&
            instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry TSRMLS_CC) &&
-           (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
-                  Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
+        client->exceptions) {
                zval *exception;
 
                MAKE_STD_ZVAL(exception);
@@ -2677,17 +2810,11 @@ static void do_soap_call(zval* this_ptr,
                INIT_PZVAL(exception);
                zend_throw_exception_object(exception TSRMLS_CC);
        }
-       if (SOAP_GLOBAL(encoding) != NULL) {
-               xmlCharEncCloseFunc(SOAP_GLOBAL(encoding));
-       }
        SOAP_GLOBAL(features) = old_features;
        SOAP_GLOBAL(class_map) = old_class_map;
        SOAP_GLOBAL(encoding) = old_encoding;
        SOAP_GLOBAL(sdl) = old_sdl;
        SOAP_CLIENT_END_CODE();
-       if (free_location) {
-               efree(location);
-       }
 }
 
 static void verify_soap_headers_array(HashTable *ht TSRMLS_DC)
@@ -2723,9 +2850,10 @@ PHP_METHOD(SoapClient, __call)
        int arg_count;
        zval **tmp;
        zend_bool free_soap_headers = 0, free_location = 0, free_soap_action = 0, free_uri = 0;
-
        HashPosition pos;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ta|zzz",
                &function, &function_len, &function_type, &args, &options, &headers, &output_headers) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
@@ -2785,9 +2913,10 @@ PHP_METHOD(SoapClient, __call)
        }
 
        /* Add default headers */
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"), (void **) &tmp)==SUCCESS) {
-               HashTable *default_headers = Z_ARRVAL_P(*tmp);
+       if (client->default_headers) {
                if (soap_headers) {
+                       HashTable *default_headers = Z_ARRVAL_P(client->default_headers);
+
                        if (!free_soap_headers) {
                                HashTable *tmp =  emalloc(sizeof(HashTable));
                                zend_hash_init(tmp, 0, NULL, ZVAL_PTR_DTOR, 0);
@@ -2802,11 +2931,11 @@ PHP_METHOD(SoapClient, __call)
                                zend_hash_move_forward(default_headers);
                        }
                } else {
-                       soap_headers = Z_ARRVAL_P(*tmp);
+                       soap_headers = Z_ARRVAL_P(client->default_headers);
                        free_soap_headers = 0;
                }
        }
-       
+
        arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
 
        if (arg_count > 0) {
@@ -2857,9 +2986,10 @@ PHP_METHOD(SoapClient, __getFunctions)
 {
        sdlPtr sdl;
        HashPosition pos;
+       soap_client_object *client;
 
-       FETCH_THIS_SDL(sdl);
-
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       sdl = client->sdl;
        if (sdl) {
                smart_str buf = {0};
                sdlFunctionPtr *function;
@@ -2883,9 +3013,10 @@ PHP_METHOD(SoapClient, __getTypes)
 {
        sdlPtr sdl;
        HashPosition pos;
+       soap_client_object *client;
 
-       FETCH_THIS_SDL(sdl);
-
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       sdl = client->sdl;
        if (sdl) {
                sdlTypePtr *type;
                smart_str buf = {0};
@@ -2909,10 +3040,11 @@ PHP_METHOD(SoapClient, __getTypes)
    Returns last SOAP request */
 PHP_METHOD(SoapClient, __getLastRequest)
 {
-       zval **tmp;
+       soap_client_object *client;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_request", sizeof("__last_request"), (void **)&tmp) == SUCCESS) {
-               RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       if (client->last_request) {
+               RETURN_STRING(client->last_request, 1);
        }
        RETURN_NULL();
 }
@@ -2923,10 +3055,11 @@ PHP_METHOD(SoapClient, __getLastRequest)
    Returns last SOAP response */
 PHP_METHOD(SoapClient, __getLastResponse)
 {
-       zval **tmp;
+       soap_client_object *client;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response"), (void **)&tmp) == SUCCESS) {
-               RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       if (client->last_response) {
+               RETURN_STRING(client->last_response, 1);
        }
        RETURN_NULL();
 }
@@ -2937,10 +3070,11 @@ PHP_METHOD(SoapClient, __getLastResponse)
    Returns last SOAP request headers */
 PHP_METHOD(SoapClient, __getLastRequestHeaders)
 {
-       zval **tmp;
+       soap_client_object *client;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_request_headers", sizeof("__last_request_headers"), (void **)&tmp) == SUCCESS) {
-               RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       if (client->last_request_headers) {
+               RETURN_STRING(client->last_request_headers, 1);
        }
        RETURN_NULL();
 }
@@ -2951,10 +3085,11 @@ PHP_METHOD(SoapClient, __getLastRequestHeaders)
    Returns last SOAP response headers */
 PHP_METHOD(SoapClient, __getLastResponseHeaders)
 {
-       zval **tmp;
+       soap_client_object *client;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_response_headers", sizeof("__last_response_headers"), (void **)&tmp) == SUCCESS) {
-               RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
+       if (client->last_response_headers) {
+               RETURN_STRING(client->last_response_headers, 1);
        }
        RETURN_NULL();
 }
@@ -2980,8 +3115,10 @@ PHP_METHOD(SoapClient, __doRequest)
        if (SOAP_GLOBAL(features) & SOAP_WAIT_ONE_WAY_CALLS) {
                one_way = 0;
        }
-       if (one_way && make_http_soap_request(this_ptr, buf, buf_size, location, action, version, NULL, NULL TSRMLS_CC)) {
-               RETURN_EMPTY_STRING();
+       if (one_way) {
+               if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version, NULL, NULL TSRMLS_CC)) {
+                       RETURN_EMPTY_STRING();
+               }
        } else if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version,
            &Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC)) {
                return_value->type = IS_STRING;
@@ -3000,8 +3137,9 @@ PHP_METHOD(SoapClient, __setCookie)
        char *name;
        char *val = NULL;
        int  name_len, val_len;
-       zval **cookies;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
            &name, &name_len, &val, &val_len) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
@@ -3009,24 +3147,21 @@ PHP_METHOD(SoapClient, __setCookie)
        }
 
        if (val == NULL) {
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
-                       zend_hash_del(Z_ARRVAL_PP(cookies), name, name_len+1);
+               if (client->cookies) {
+                       zend_hash_del(Z_ARRVAL_P(client->cookies), name, name_len+1);
                }
        } else {
                zval *zcookie;
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE) {
-                       zval *tmp_cookies;
-
-                       MAKE_STD_ZVAL(tmp_cookies);
-                       array_init(tmp_cookies);
-                       zend_hash_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), &tmp_cookies, sizeof(zval *), (void **)&cookies);
+               if (!client->cookies) {
+                       MAKE_STD_ZVAL(client->cookies);
+                       array_init(client->cookies);
                }
 
                ALLOC_INIT_ZVAL(zcookie);
                array_init(zcookie);
                add_index_stringl(zcookie, 0, val, val_len, 1);
-               add_assoc_zval_ex(*cookies, name, name_len+1, zcookie);
+               add_assoc_zval_ex(client->cookies, name, name_len+1, zcookie);
        }
 }
 /* }}} */
@@ -3037,29 +3172,32 @@ PHP_METHOD(SoapClient, __setCookie)
    If no value is specified, all of the headers are removed. */
 PHP_METHOD(SoapClient, __setSoapHeaders)
 {
-       zval *headers;
+       zval *headers = NULL;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &headers) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
-         RETURN_NULL();
+               RETURN_NULL();
        }
 
+       if (client->default_headers) {
+               zval_ptr_dtor(&client->default_headers);
+               client->default_headers = NULL;
+       }
        if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"));
        } else if (Z_TYPE_P(headers) == IS_ARRAY) {
-               zval *default_headers;
-
                verify_soap_headers_array(Z_ARRVAL_P(headers) TSRMLS_CC);
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"), (void **) &default_headers)==FAILURE) {
-                       add_property_zval(this_ptr, "__default_headers", headers);
-               }
+               ALLOC_ZVAL(client->default_headers);
+               *client->default_headers = *headers;
+               INIT_PZVAL(client->default_headers);
+               zval_copy_ctor(client->default_headers);
        } else if (Z_TYPE_P(headers) == IS_OBJECT &&
                   instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry TSRMLS_CC)) {
-               zval *default_headers;
-               ALLOC_INIT_ZVAL(default_headers);
-               array_init(default_headers);
-               add_next_index_zval(default_headers, headers);
-               add_property_zval(this_ptr, "__default_headers", default_headers);
+               ALLOC_INIT_ZVAL(client->default_headers);
+               array_init(client->default_headers);
+               headers->refcount++;
+               add_next_index_zval(client->default_headers, headers);
        } else{
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid SOAP header");
        }
@@ -3070,61 +3208,54 @@ PHP_METHOD(SoapClient, __setSoapHeaders)
 
 
 /* {{{ proto string SoapClient::__setLocation([string new_location])
-   Sets the location option (the endpoint URL that will be touched by the 
+   Sets the location option (the endpoint URL that will be touched by the
    following SOAP requests).
    If new_location is not specified or null then SoapClient will use endpoint
-   from WSDL file. 
+   from WSDL file.
    The function returns old value of location options. */
 PHP_METHOD(SoapClient, __setLocation)
 {
        void* location = NULL;
        int  location_len;
        zend_uchar location_type;
-       zval **tmp;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|t",
            &location, &location_len, &location_type) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
          RETURN_NULL();
        }
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS) {
-               if (Z_TYPE_PP(tmp) == IS_STRING) {
-                       RETVAL_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
-               } else if (Z_TYPE_PP(tmp) == IS_UNICODE) {
-                       RETVAL_UNICODEL(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp), 1);
-               } else {
-                       RETVAL_NULL();
-           }
+       if (client->location) {
+               RETVAL_STRING(client->location, 1);
+               if (UG(unicode)) {
+                       zval_string_to_unicode_ex(return_value, UG(utf8_conv) TSRMLS_CC);
+               }
+               efree(client->location);
+               client->location = NULL;
        } else {
          RETVAL_NULL();
        }
        if (location && location_len) {
                if (location_type == IS_STRING) {
-                       add_property_stringl(this_ptr, "location", location, location_len, 1);
+                       client->location = estrndup(location, location_len);
                } else {
-                       add_property_unicodel(this_ptr, "location", location, location_len, 1);
+                       client->location = soap_unicode_to_string(location, location_len TSRMLS_CC);
                }
-       } else {
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "location", sizeof("location"));
        }
 }
 /* }}} */
 
-static void clear_soap_fault(zval *obj TSRMLS_DC)
-{
-       if (obj != NULL && obj->type == IS_OBJECT) {
-               zend_hash_del(Z_OBJPROP_P(obj), "__soap_fault", sizeof("__soap_fault"));
-       }
-}
-
 zval* add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC)
 {
-       zval *fault;
-       ALLOC_INIT_ZVAL(fault);
-       set_soap_fault(fault, NULL, fault_code, fault_string, fault_actor, fault_detail, NULL TSRMLS_CC);
-       fault->refcount--;
-       add_property_zval(obj, "__soap_fault", fault);
-       return fault;
+       soap_client_object *client;
+
+       client = (soap_client_object*)zend_object_store_get_object(obj TSRMLS_CC);
+       if (!client->fault) {
+               ALLOC_INIT_ZVAL(client->fault);
+               set_soap_fault(client->fault, NULL, fault_code, fault_string, fault_actor, fault_detail, NULL TSRMLS_CC);
+       }
+       return client->fault;
 }
 
 static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, char *name TSRMLS_DC)
@@ -3818,8 +3949,8 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                }
 
                if (fault_ns == NULL &&
-                   fault && 
-                   fault->details && 
+                   fault &&
+                   fault->details &&
                    zend_hash_num_elements(fault->details) == 1) {
                        sdlParamPtr sparam;
 
@@ -3840,7 +3971,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                                if (fault_ns) {
                                        xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
                                        xmlNodeSetContent(node, xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0));
-                               } else {        
+                               } else {
                                        xmlNodeSetContentLen(node, BAD_CAST(str), new_len);
                                }
                                efree(str);
@@ -3863,7 +3994,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                                if (fault_ns) {
                                        xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
                                        xmlNodeSetContent(node, xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0));
-                               } else {        
+                               } else {
                                        xmlNodeSetContentLen(node, BAD_CAST(str), new_len);
                                }
                                efree(str);
@@ -4047,7 +4178,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                }
        }
 
-       if (function && function->responseName == NULL && 
+       if (function && function->responseName == NULL &&
            body->children == NULL && head == NULL) {
                xmlFreeDoc(doc);
                return NULL;
@@ -4060,10 +4191,11 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
        xmlDoc *doc;
        xmlNodePtr envelope = NULL, body, method = NULL, head = NULL;
        xmlNsPtr ns = NULL;
-       zval **zstyle, **zuse;
        int i, style, use;
        HashTable *hdrs = NULL;
+       soap_client_object *client;
 
+       client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
        encode_reset_ns();
 
        doc = xmlNewDoc(BAD_CAST("1.0"));
@@ -4105,11 +4237,7 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
                        }
                }
        } else {
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "style", sizeof("style"), (void **)&zstyle) == SUCCESS) {
-                       style = Z_LVAL_PP(zstyle);
-               } else {
-                       style = SOAP_RPC;
-               }
+               style = client->style;
                /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
                /*style = SOAP_RPC;*/
                if (style == SOAP_RPC) {
@@ -4117,8 +4245,7 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
                        method = xmlNewChild(body, ns, BAD_CAST(function_name), NULL);
                }
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS &&
-                         Z_LVAL_PP(zuse) == SOAP_LITERAL) {
+               if (client->use == SOAP_LITERAL) {
                        use = SOAP_LITERAL;
                } else {
                        use = SOAP_ENCODED;
@@ -4402,7 +4529,7 @@ static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int inde
                        return *tmp;
                } else {
                        HashPosition pos;
-               
+
                        zend_hash_internal_pointer_reset_ex(ht, &pos);
                        while (zend_hash_get_current_data_ex(ht, (void **)&tmp, &pos) != FAILURE) {
                                if ((*tmp)->paramName && strcmp(param_name, (*tmp)->paramName) == 0) {
@@ -4733,49 +4860,3 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
        smart_str_free(&spaces);
        smart_str_0(buf);
 }
-
-static void delete_url(void *handle)
-{
-       php_url_free((php_url*)handle);
-}
-
-static void delete_service(void *data)
-{
-       soapServicePtr service = (soapServicePtr)data;
-
-       if (service->soap_functions.ft) {
-               zend_hash_destroy(service->soap_functions.ft);
-               efree(service->soap_functions.ft);
-       }
-
-       if (service->mapping) {
-               zend_hash_destroy(service->mapping);
-               efree(service->mapping);
-       }
-
-       if (service->soap_class.argc) {
-               int i;
-               for (i = 0; i < service->soap_class.argc;i++) {
-                       zval_ptr_dtor(&service->soap_class.argv[i]);
-               }
-               efree(service->soap_class.argv);
-       }
-
-       if (service->actor) {
-               efree(service->actor);
-       }
-       if (service->uri) {
-               efree(service->uri);
-       }
-       if (service->sdl) {
-               delete_sdl(service->sdl);
-       }
-       if (service->encoding) {
-               xmlCharEncCloseFunc(service->encoding);
-       }
-       if (service->class_map) {
-               zend_hash_destroy(service->class_map);
-               FREE_HASHTABLE(service->class_map);
-       }
-       efree(service);
-}
index 4ad9c5ee852facbc66250016431dabf1034c3c96..b2b3a0933177f528cfbb0581298b312d9bb2f0ab 100644 (file)
@@ -13,8 +13,8 @@ function test() {
 $server = new soapserver(null,array('uri'=>"http://testuri.org"));
 $server->addfunction("test");
 
-$HTTP_RAW_POST_DATA = gzencode(<<<EOF
-<?xml version="1.0" encoding="ISO-8859-1"?>
+$HTTP_RAW_POST_DATA = gzencode(
+b'<?xml version="1.0" encoding="ISO-8859-1"?>
 <SOAP-ENV:Envelope
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
@@ -25,8 +25,7 @@ $HTTP_RAW_POST_DATA = gzencode(<<<EOF
     <ns1:test xmlns:ns1="http://testuri.org" />
   </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>
-EOF
-, 9, FORCE_GZIP);
+', 9, FORCE_GZIP);
 $_SERVER['HTTP_CONTENT_ENCODING'] = "gzip";
 $server->handle();
 echo "ok\n";
index bacbc57849915f0d1d4a389a6114112adeb9bb7e..151dd3d7cd0687d16b7e5f7e8d598261c5ad2842 100644 (file)
@@ -13,8 +13,8 @@ function test() {
 $server = new soapserver(null,array('uri'=>"http://testuri.org"));
 $server->addfunction("test");
 
-$HTTP_RAW_POST_DATA = gzcompress(<<<EOF
-<?xml version="1.0" encoding="ISO-8859-1"?>
+$HTTP_RAW_POST_DATA = gzcompress(
+b'<?xml version="1.0" encoding="ISO-8859-1"?>
 <SOAP-ENV:Envelope
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
@@ -25,8 +25,7 @@ $HTTP_RAW_POST_DATA = gzcompress(<<<EOF
     <ns1:test xmlns:ns1="http://testuri.org" />
   </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>
-EOF
-, 9);
+', 9);
 $_SERVER['HTTP_CONTENT_ENCODING'] = "deflate";
 $server->handle();
 echo "ok\n";
diff --git a/ext/soap/tests/setheaders.phpt b/ext/soap/tests/setheaders.phpt
new file mode 100755 (executable)
index 0000000..cb90d37
--- /dev/null
@@ -0,0 +1,38 @@
+--TEST--
+SOAP: SoapClient::__setHeaders
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$client = new SoapClient(NULL, array("location"=>"test://","uri"=>"test://",
+  "exceptions"=>0,"trace"=>1));
+$client->test();
+echo $client->__getLastRequest();
+$client->__setSoapHeaders(new SoapHeader("test://","HDR1"));
+$client->test();
+echo $client->__getLastRequest();
+$client->test();
+echo $client->__getLastRequest();
+$client->__setSoapHeaders();
+$client->test();
+echo $client->__getLastRequest();
+$client->__setSoapHeaders(array(new SoapHeader("test://","HDR1"),new SoapHeader("test://","HDR2")));
+$client->test();
+echo $client->__getLastRequest();
+$h = array(new SoapHeader("test://","HDR0"));
+$client->__soapCall("test", array(), null, $h);
+echo $client->__getLastRequest();
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR1/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR1/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR1/><ns1:HDR2/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR0/><ns1:HDR1/><ns1:HDR2/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>