]> granicus.if.org Git - php/commitdiff
ext/soap support for phpng (incomplete - just compilable)
authorDmitry Stogov <dmitry@zend.com>
Wed, 14 May 2014 22:44:47 +0000 (02:44 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 14 May 2014 22:44:47 +0000 (02:44 +0400)
13 files changed:
Zend/zend_API.c
Zend/zend_API.h
ext/soap/php_encoding.c
ext/soap/php_encoding.h
ext/soap/php_http.c
ext/soap/php_http.h
ext/soap/php_packet_soap.c
ext/soap/php_schema.c
ext/soap/php_schema.h
ext/soap/php_sdl.c
ext/soap/php_sdl.h
ext/soap/php_soap.h
ext/soap/soap.c

index f1e9614a220baa9b633d39f4861a3eb088d72133..d4df4d37296d7446f9d7a974a123dedf9f97806b 100644 (file)
@@ -1757,6 +1757,20 @@ ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, do
 }
 /* }}} */
 
+ZEND_API int add_property_str_ex(zval *arg, const char *key, uint key_len, zend_string *str TSRMLS_DC) /* {{{ */
+{
+       zval tmp;
+       zval z_key;
+
+       ZVAL_STR(&tmp, str);
+       ZVAL_STRINGL(&z_key, key, key_len);
+       Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, -1 TSRMLS_CC);
+//???  zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
+       zval_ptr_dtor(&z_key);
+       return SUCCESS;
+}
+/* }}} */
+
 ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, const char *str TSRMLS_DC) /* {{{ */
 {
        zval tmp;
index 882841c61eb4602407c111fcbd014d28fef42163..73152caa1c4522016230d9ccbf82888bc908b798 100644 (file)
@@ -440,6 +440,7 @@ ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRML
 ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int b TSRMLS_DC);
 ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, zend_resource *r TSRMLS_DC);
 ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, double d TSRMLS_DC);
+ZEND_API int add_property_str_ex(zval *arg, const char *key, uint key_len, zend_string *str TSRMLS_DC);
 ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, const char *str TSRMLS_DC);
 ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len,  const char *str, uint length TSRMLS_DC);
 ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC);
@@ -449,6 +450,7 @@ ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval
 #define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key), __b TSRMLS_CC)
 #define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key), __r TSRMLS_CC)
 #define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key), __d TSRMLS_CC)
+#define add_property_str(__arg, __key, __str) add_property_str_ex(__arg, __key, strlen(__key), __str TSRMLS_CC)
 #define add_property_string(__arg, __key, __str) add_property_string_ex(__arg, __key, strlen(__key), __str TSRMLS_CC)
 #define add_property_stringl(__arg, __key, __str, __length) add_property_stringl_ex(__arg, __key, strlen(__key), __str, __length TSRMLS_CC)
 #define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key), __value TSRMLS_CC)       
index c4ce4476bc1649c8601306e1f2f1700c07d670e0..071c0fd3e1a7508a065c5c848b8a56830433d5c7 100644 (file)
 #include "zend_interfaces.h"
 
 /* zval type decode */
-static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_double(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_long(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_bool(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_string(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_stringr(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_stringc(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_map(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_null(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_base64(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_hexbin(zval* ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
 
 static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
@@ -71,17 +71,17 @@ static xmlNodePtr to_xml_gday(encodeTypePtr type, zval *data, int style, xmlNode
 static xmlNodePtr to_xml_gmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 static xmlNodePtr to_xml_duration(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 
-static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
-static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_object(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
 
 static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 
-static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *to_zval_any(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
 static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 
 /* Try and guess for non-wsdl clients and servers */
-static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+static zval *guess_zval_convert(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
 static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 
 static int is_map(zval *array);
@@ -118,16 +118,12 @@ static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type);
        { \
                xmlAttrPtr null; \
                if (!xml) { \
-                       zval *ret; \
-                       ALLOC_INIT_ZVAL(ret); \
                        ZVAL_NULL(ret); \
                        return ret; \
                } \
                if (xml->properties) { \
                        null = get_attribute(xml->properties, "nil"); \
                        if (null) { \
-                               zval *ret; \
-                               ALLOC_INIT_ZVAL(ret); \
                                ZVAL_NULL(ret); \
                                return ret; \
                        } \
@@ -151,7 +147,8 @@ encode defaultEncoding[] = {
        {{IS_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
        {{IS_LONG, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
        {{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double},
-       {{IS_BOOL, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
+       {{IS_FALSE, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
+       {{IS_TRUE, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
        {{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
        {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map},
        {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
@@ -275,37 +272,34 @@ void whiteSpace_collapse(xmlChar* str)
 static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type)
 {
        if (sdl && sdl->encoders) {
-               HashPosition pos;
-               encodePtr *enc;
+               encodePtr enc;
 
-               for (zend_hash_internal_pointer_reset_ex(sdl->encoders, &pos);
-                    zend_hash_get_current_data_ex(sdl->encoders, (void **) &enc, &pos) == SUCCESS;
-                    zend_hash_move_forward_ex(sdl->encoders, &pos)) {
-                   if (strcmp((*enc)->details.type_str, type) == 0) {
-                               return *enc;
+               ZEND_HASH_FOREACH_PTR(sdl->encoders, enc)  {
+                   if (strcmp(enc->details.type_str, type) == 0) {
+                               return enc;
                        }
-               }
+               } ZEND_HASH_FOREACH_END();
        }
        return NULL;
 }
 
 static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
-       xmlNodePtr *node_ptr;
+       xmlNodePtr node_ptr;
 
        if (SOAP_GLOBAL(ref_map)) {
                if (Z_TYPE_P(data) == IS_OBJECT) {
-                       data = (zval*)zend_objects_get_address(data TSRMLS_CC);
+                       data = (zval*)Z_OBJ_P(data);
                }
-               if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node_ptr) == SUCCESS) {
-                       xmlAttrPtr attr = (*node_ptr)->properties;
+               if ((node_ptr = zend_hash_index_find_ptr(SOAP_GLOBAL(ref_map), (ulong)data)) != NULL) {
+                       xmlAttrPtr attr = node_ptr->properties;
                        char *id;
                        smart_str prefix = {0};
 
-                       if (*node_ptr == node) {
+                       if (node_ptr == node) {
                                return 0;
                        }
-                       xmlNodeSetName(node, (*node_ptr)->name);
-                       xmlSetNs(node, (*node_ptr)->ns);
+                       xmlNodeSetName(node, node_ptr->name);
+                       xmlSetNs(node, node_ptr->ns);
                        if (SOAP_GLOBAL(soap_version) == SOAP_1_1) {
                                while (1) {
                                        attr = get_attribute(attr, "id");
@@ -319,14 +313,14 @@ static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
                                        smart_str_appendc(&prefix, '#');
                                        smart_str_appends(&prefix, id);
                                        smart_str_0(&prefix);
-                                       id = prefix.c;
+                                       id = prefix.s->val;
                                } else {
                                        SOAP_GLOBAL(cur_uniq_ref)++;
                                        smart_str_appendl(&prefix, "#ref", 4);
                                        smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
                                        smart_str_0(&prefix);
-                                       id = prefix.c;
-                                       xmlSetProp((*node_ptr), BAD_CAST("id"), BAD_CAST(id+1));
+                                       id = prefix.s->val;
+                                       xmlSetProp(node_ptr, BAD_CAST("id"), BAD_CAST(id+1));
                                }
                                xmlSetProp(node, BAD_CAST("href"), BAD_CAST(id));
                        } else {
@@ -336,21 +330,21 @@ static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
                                        smart_str_appendc(&prefix, '#');
                                        smart_str_appends(&prefix, id);
                                        smart_str_0(&prefix);
-                                       id = prefix.c;
+                                       id = prefix.s->val;
                                } else {
                                        SOAP_GLOBAL(cur_uniq_ref)++;
                                        smart_str_appendl(&prefix, "#ref", 4);
                                        smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
                                        smart_str_0(&prefix);
-                                       id = prefix.c;
-                                       set_ns_prop((*node_ptr), SOAP_1_2_ENC_NAMESPACE, "id", id+1);
+                                       id = prefix.s->val;
+                                       set_ns_prop(node_ptr, SOAP_1_2_ENC_NAMESPACE, "id", id+1);
                                }
                                set_ns_prop(node, SOAP_1_2_ENC_NAMESPACE, "ref", id);
                        }
                        smart_str_free(&prefix);
                        return 1;
                } else {
-                       zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node, sizeof(xmlNodePtr), NULL);
+                       zend_hash_index_update_ptr(SOAP_GLOBAL(ref_map), (ulong)data, node);
                }
        }
        return 0;
@@ -358,32 +352,34 @@ static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
 
 static zval* soap_find_xml_ref(xmlNodePtr node TSRMLS_DC)
 {
-       zval **data_ptr;
+       zval *data_ptr;
 
        if (SOAP_GLOBAL(ref_map) && 
-           zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
-               Z_SET_ISREF_PP(data_ptr);
-               Z_ADDREF_PP(data_ptr);
-               return *data_ptr;
+           (data_ptr = zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node)) != NULL) {
+//???          Z_SET_ISREF_PP(data_ptr);
+           SEPARATE_ZVAL_TO_MAKE_IS_REF(data_ptr);
+               Z_ADDREF_P(data_ptr);
+               return data_ptr;
        }
        return NULL;
 }
 
-static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC)
+static zend_bool soap_check_xml_ref(zval *data, xmlNodePtr node TSRMLS_DC)
 {
-       zval **data_ptr;
+       zval *data_ptr;
 
        if (SOAP_GLOBAL(ref_map)) {
-               if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
-                       if (*data != *data_ptr) {
+               if ((data_ptr = zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node)) != NULL) {
+                       if (data != data_ptr) {
                                zval_ptr_dtor(data);
-                               *data = *data_ptr;
-                               Z_SET_ISREF_PP(data);
-                               Z_ADDREF_PP(data);
+                               ZVAL_COPY_VALUE(data, data_ptr);
+//???                          Z_SET_ISREF_PP(data);
+                           SEPARATE_ZVAL_TO_MAKE_IS_REF(data);
+                               Z_ADDREF_P(data);
                                return 1;
                        }
                } else {
-                       zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)node, (void**)data, sizeof(zval*), NULL);
+                       zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)node, data);
                }
        }
        return 0;
@@ -398,92 +394,81 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml
        if (data &&
            Z_TYPE_P(data) == IS_OBJECT &&
            Z_OBJCE_P(data) == soap_var_class_entry) {
-               zval **ztype, **zdata, **zns, **zstype, **zname, **znamens;
+               zval *ztype, *zdata, *zns, *zstype, *zname, *znamens;
                encodePtr enc = NULL;
                HashTable *ht = Z_OBJPROP_P(data);
 
-               if (zend_hash_find(ht, "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
+               if ((ztype = zend_hash_str_find(ht, "enc_type", sizeof("enc_type")-1)) == NULL) {
                        soap_error0(E_ERROR, "Encoding: SoapVar has no 'enc_type' property");
                }
 
-               if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
-                       if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
-                               enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
+               if ((zstype = zend_hash_str_find(ht, "enc_stype", sizeof("enc_stype")-1)) != NULL) {
+                       if ((zns = zend_hash_str_find(ht, "enc_ns", sizeof("enc_ns")-1)) != NULL) {
+                               enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_P(zns), Z_STRVAL_P(zstype));
                        } else {
                                zns = NULL;
-                               enc = get_encoder_ex(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype));
+                               enc = get_encoder_ex(SOAP_GLOBAL(sdl), Z_STRVAL_P(zstype), Z_STRLEN_P(zstype));
                        }
                        if (enc == NULL && SOAP_GLOBAL(typemap)) {
-                               encodePtr *new_enc;
                                smart_str nscat = {0};
 
                                if (zns != NULL) {
-                                       smart_str_appendl(&nscat, Z_STRVAL_PP(zns), Z_STRLEN_PP(zns));
+                                       smart_str_appendl(&nscat, Z_STRVAL_P(zns), Z_STRLEN_P(zns));
                                        smart_str_appendc(&nscat, ':');
                                }
-                               smart_str_appendl(&nscat, Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype));
+                               smart_str_appendl(&nscat, Z_STRVAL_P(zstype), Z_STRLEN_P(zstype));
                                smart_str_0(&nscat);
-                               if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
-                                       enc = *new_enc;
-                               }
+                               enc = zend_hash_find_ptr(SOAP_GLOBAL(typemap), nscat.s);
                                smart_str_free(&nscat);                 
                        }
                }
                if (enc == NULL) {
-                       enc = get_conversion(Z_LVAL_P(*ztype));
+                       enc = get_conversion(Z_LVAL_P(ztype));
                }
                if (enc == NULL) {
                        enc = encode;
                }
 
-               if (zend_hash_find(ht, "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) {
-                       node = master_to_xml(enc, NULL, style, parent TSRMLS_CC);
-               } else {
-                       node = master_to_xml(enc, *zdata, style, parent TSRMLS_CC);
-               }
+               zdata = zend_hash_str_find(ht, "enc_value", sizeof("enc_value")-1);
+               node = master_to_xml(enc, zdata, style, parent TSRMLS_CC);
 
                if (style == SOAP_ENCODED || (SOAP_GLOBAL(sdl) && encode != enc)) {
-                       if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
-                               if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
-                                       set_ns_and_type_ex(node, Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
+                       if ((ztype = zend_hash_str_find(ht, "enc_stype", sizeof("enc_stype")-1)) != NULL) {
+                               if ((zns = zend_hash_str_find(ht, "enc_ns", sizeof("enc_ns")-1)) != NULL) {
+                                       set_ns_and_type_ex(node, Z_STRVAL_P(zns), Z_STRVAL_P(zstype));
                                } else {
-                                       set_ns_and_type_ex(node, NULL, Z_STRVAL_PP(zstype));
+                                       set_ns_and_type_ex(node, NULL, Z_STRVAL_P(zstype));
                                }
                        }
                }
 
-               if (zend_hash_find(ht, "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) {
-                       xmlNodeSetName(node, BAD_CAST(Z_STRVAL_PP(zname)));
+               if ((zname = zend_hash_str_find(ht, "enc_name", sizeof("enc_name")-1)) != NULL) {
+                       xmlNodeSetName(node, BAD_CAST(Z_STRVAL_P(zname)));
                }
-               if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) {
-                       xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens));
+               if ((znamens = zend_hash_str_find(ht, "enc_namens", sizeof("enc_namens")-1)) != NULL) {
+                       xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_P(znamens));
                        xmlSetNs(node, nsp);
                }
        } else {
                if (check_class_map && SOAP_GLOBAL(class_map) && data &&
                    Z_TYPE_P(data) == IS_OBJECT &&
-                   !Z_OBJPROP_P(data)->nApplyCount) {
+                   !ZEND_HASH_GET_APPLY_COUNT(Z_OBJPROP_P(data))) {
                        zend_class_entry *ce = Z_OBJCE_P(data);
-                       HashPosition pos;
-                       zval **tmp;
-                       char *type_name = NULL;
-                       uint type_len;
-                       ulong idx;
-
-                       for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(class_map), &pos);
-                            zend_hash_get_current_data_ex(SOAP_GLOBAL(class_map), (void **) &tmp, &pos) == SUCCESS;
-                            zend_hash_move_forward_ex(SOAP_GLOBAL(class_map), &pos)) {
-                               if (Z_TYPE_PP(tmp) == IS_STRING &&
-                                   ce->name_length == Z_STRLEN_PP(tmp) &&
-                                   zend_binary_strncasecmp(ce->name, ce->name_length, Z_STRVAL_PP(tmp), ce->name_length, ce->name_length) == 0 &&
-                                   zend_hash_get_current_key_ex(SOAP_GLOBAL(class_map), &type_name, &type_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) {
+                       zval *tmp;
+                       zend_string *type_name;
+
+                       ZEND_HASH_FOREACH_STR_KEY_VAL(SOAP_GLOBAL(class_map), type_name, tmp) {
+                               if (Z_TYPE_P(tmp) == IS_STRING &&
+                                   ce->name->len == Z_STRLEN_P(tmp) &&
+                                   zend_binary_strncasecmp(ce->name->val, ce->name->len, Z_STRVAL_P(tmp), ce->name->len, ce->name->len) == 0 &&
+                                   type_name) {
 
                                        /* TODO: namespace isn't stored */
                                        encodePtr enc = NULL;
                                        if (SOAP_GLOBAL(sdl)) {
-                                               enc = get_encoder(SOAP_GLOBAL(sdl), SOAP_GLOBAL(sdl)->target_ns, type_name);
+                                               enc = get_encoder(SOAP_GLOBAL(sdl), SOAP_GLOBAL(sdl)->target_ns, type_name->val);
                                                if (!enc) {
-                                                       enc = find_encoder_by_type_name(SOAP_GLOBAL(sdl), type_name);
+                                                       enc = find_encoder_by_type_name(SOAP_GLOBAL(sdl), type_name->val);
                                                }
                                        }
                                        if (enc) {
@@ -494,7 +479,7 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml
                                        }
                                        break;
                                }
-                       }
+                       } ZEND_HASH_FOREACH_END();
                }
 
                if (encode == NULL) {
@@ -502,7 +487,7 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml
                }
                if (SOAP_GLOBAL(typemap) && encode->details.type_str) {
                        smart_str nscat = {0};
-                       encodePtr *new_enc;
+                       encodePtr new_enc;
 
                        if (encode->details.ns) {
                                smart_str_appends(&nscat, encode->details.ns);
@@ -510,8 +495,8 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml
                        }
                        smart_str_appends(&nscat, encode->details.type_str);
                        smart_str_0(&nscat);
-                       if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
-                               encode = *new_enc;
+                       if ((new_enc = zend_hash_find_ptr(SOAP_GLOBAL(typemap), nscat.s)) != NULL) {
+                               encode = new_enc;
                        }
                        smart_str_free(&nscat);                 
                }
@@ -530,14 +515,12 @@ xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr par
        return master_to_xml_int(encode, data, style, parent, 1 TSRMLS_CC);
 }
 
-static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data TSRMLS_DC)
+static zval *master_to_zval_int(zval *ret, encodePtr encode, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret = NULL;
-
        if (SOAP_GLOBAL(typemap)) {
                if (encode->details.type_str) {
                        smart_str nscat = {0};
-                       encodePtr *new_enc;
+                       encodePtr new_enc;
 
                        if (encode->details.ns) {
                                smart_str_appends(&nscat, encode->details.ns);
@@ -545,15 +528,15 @@ static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data TSRMLS_DC)
                        }
                        smart_str_appends(&nscat, encode->details.type_str);
                        smart_str_0(&nscat);
-                       if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
-                               encode = *new_enc;
+                       if ((new_enc = zend_hash_find_ptr(SOAP_GLOBAL(typemap), nscat.s)) != NULL) {
+                               encode = new_enc;
                        }
                        smart_str_free(&nscat);                 
                } else {
                        xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE);
 
                        if (type_attr != NULL) {
-                               encodePtr *new_enc;
+                               encodePtr new_enc;
                                xmlNsPtr nsptr;
                                char *ns, *cptype;
                                smart_str nscat = {0};
@@ -568,20 +551,20 @@ static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data TSRMLS_DC)
                                smart_str_0(&nscat);
                                efree(cptype);
                                if (ns) {efree(ns);}
-                               if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
-                                       encode = *new_enc;
+                               if ((new_enc = zend_hash_find_ptr(SOAP_GLOBAL(typemap), nscat.s)) != NULL) {
+                                       encode = new_enc;
                                }
                                smart_str_free(&nscat);                 
                        }
                }
        }
        if (encode->to_zval) {
-               ret = encode->to_zval(&encode->details, data TSRMLS_CC);
+               ret = encode->to_zval(ret, &encode->details, data TSRMLS_CC);
        }
        return ret;
 }
 
-zval *master_to_zval(encodePtr encode, xmlNodePtr data TSRMLS_DC)
+zval *master_to_zval(zval *ret, encodePtr encode, xmlNodePtr data TSRMLS_DC)
 {
        data = check_and_resolve_href(data);
 
@@ -612,22 +595,22 @@ zval *master_to_zval(encodePtr encode, xmlNodePtr data TSRMLS_DC)
                        }
                }
        }
-       return master_to_zval_int(encode, data TSRMLS_CC);
+       return master_to_zval_int(ret, encode, data TSRMLS_CC);
 }
 
 xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC)
 {
        xmlNodePtr ret = NULL;
-       zval *return_value;
+       zval return_value;
 
-       if (type && type->map && type->map->to_xml) {
-               MAKE_STD_ZVAL(return_value);
+       if (type && type->map && Z_TYPE(type->map->to_xml) != IS_UNDEF) {
+               ZVAL_NULL(&return_value);
 
-               if (call_user_function(EG(function_table), NULL, type->map->to_xml, return_value, 1, &data TSRMLS_CC) == FAILURE) {
+               if (call_user_function(EG(function_table), NULL, &type->map->to_xml, &return_value, 1, data TSRMLS_CC) == FAILURE) {
                        soap_error0(E_ERROR, "Encoding: Error calling to_xml callback");
                }
-               if (Z_TYPE_P(return_value) == IS_STRING) {              
-                       xmlDocPtr doc = soap_xmlParseMemory(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
+               if (Z_TYPE(return_value) == IS_STRING) {                
+                       xmlDocPtr doc = soap_xmlParseMemory(Z_STRVAL(return_value), Z_STRLEN(return_value));
                        if (doc && doc->children) {                             
                                ret = xmlDocCopyNode(doc->children, parent->doc, 1);
                        }
@@ -646,41 +629,37 @@ xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr par
        return ret;
 }
 
-zval *to_zval_user(encodeTypePtr type, xmlNodePtr node TSRMLS_DC)
+zval *to_zval_user(zval *ret, encodeTypePtr type, xmlNodePtr node TSRMLS_DC)
 {
-       zval *return_value;
-
-       if (type && type->map && type->map->to_zval) {
+       if (type && type->map && Z_TYPE(type->map->to_zval) != IS_UNDEF) {
                xmlBufferPtr buf;
-               zval *data;
+               zval data;
                xmlNodePtr copy;
 
                copy = xmlCopyNode(node, 1);
                buf = xmlBufferCreate();
                xmlNodeDump(buf, NULL, copy, 0, 0);
-               MAKE_STD_ZVAL(data);
-               ZVAL_STRING(data, (char*)xmlBufferContent(buf), 1);
+               ZVAL_STRING(&data, (char*)xmlBufferContent(buf));
                xmlBufferFree(buf);
                xmlFreeNode(copy);
 
-               ALLOC_INIT_ZVAL(return_value);
+               ZVAL_NULL(ret);
                
-               if (call_user_function(EG(function_table), NULL, type->map->to_zval, return_value, 1, &data TSRMLS_CC) == FAILURE) {
+               if (call_user_function(EG(function_table), NULL, &type->map->to_zval, ret, 1, &data TSRMLS_CC) == FAILURE) {
                        soap_error0(E_ERROR, "Encoding: Error calling from_xml callback");
                }
                zval_ptr_dtor(&data);
        } else {
-               ALLOC_INIT_ZVAL(return_value);
+               ZVAL_NULL(ret);
        }
-       return return_value;
+       return ret;
 }
 
 /* TODO: get rid of "bogus".. ither by passing in the already created xmlnode or passing in the node name */
 /* String encode/decode */
-static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_string(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
        if (data && data->children) {
                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
@@ -690,17 +669,17 @@ static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                                int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
 
                                if (n >= 0) {
-                                       ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
+                                       ZVAL_STRING(ret, (char*)xmlBufferContent(out));
                                } else {
-                                       ZVAL_STRING(ret, (char*)data->children->content, 1);
+                                       ZVAL_STRING(ret, (char*)data->children->content);
                                }
                                xmlBufferFree(out);
                                xmlBufferFree(in);
                        } else {
-                               ZVAL_STRING(ret, (char*)data->children->content, 1);
+                               ZVAL_STRING(ret, (char*)data->children->content);
                        }
                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
-                       ZVAL_STRING(ret, (char*)data->children->content, 1);
+                       ZVAL_STRING(ret, (char*)data->children->content);
                } else {
                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                }
@@ -710,10 +689,9 @@ static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
        return ret;
 }
 
-static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_stringr(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
        if (data && data->children) {
                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
@@ -724,17 +702,17 @@ static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                                int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
 
                                if (n >= 0) {
-                                       ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
+                                       ZVAL_STRING(ret, (char*)xmlBufferContent(out));
                                } else {
-                                       ZVAL_STRING(ret, (char*)data->children->content, 1);
+                                       ZVAL_STRING(ret, (char*)data->children->content);
                                }
                                xmlBufferFree(out);
                                xmlBufferFree(in);
                        } else {
-                               ZVAL_STRING(ret, (char*)data->children->content, 1);
+                               ZVAL_STRING(ret, (char*)data->children->content);
                        }
                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
-                       ZVAL_STRING(ret, (char*)data->children->content, 1);
+                       ZVAL_STRING(ret, (char*)data->children->content);
                } else {
                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                }
@@ -744,10 +722,9 @@ static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
        return ret;
 }
 
-static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_stringc(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
        if (data && data->children) {
                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
@@ -758,17 +735,17 @@ static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                                int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
 
                                if (n >= 0) {
-                                       ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
+                                       ZVAL_STRING(ret, (char*)xmlBufferContent(out));
                                } else {
-                                       ZVAL_STRING(ret, (char*)data->children->content, 1);
+                                       ZVAL_STRING(ret, (char*)data->children->content);
                                }
                                xmlBufferFree(out);
                                xmlBufferFree(in);
                        } else {
-                               ZVAL_STRING(ret, (char*)data->children->content, 1);
+                               ZVAL_STRING(ret, (char*)data->children->content);
                        }
                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
-                       ZVAL_STRING(ret, (char*)data->children->content, 1);
+                       ZVAL_STRING(ret, (char*)data->children->content);
                } else {
                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                }
@@ -778,28 +755,26 @@ static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
        return ret;
 }
 
-static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_base64(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       char *str;
-       int str_len;
+       zend_string *str;
 
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
        if (data && data->children) {
                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                        whiteSpace_collapse(data->children->content);
-                       str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
+                       str = php_base64_decode(data->children->content, strlen((char*)data->children->content));
                        if (!str) {
                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                        }
-                       ZVAL_STRINGL(ret, str, str_len, 0);
+                       ZVAL_STR(ret, str);
                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
-                       str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
+                       str = php_base64_decode(data->children->content, strlen((char*)data->children->content));
                        if (!str) {
                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                        }
-                       ZVAL_STRINGL(ret, str, str_len, 0);
+                       ZVAL_STR(ret, str);
                } else {
                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                }
@@ -809,14 +784,13 @@ static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
        return ret;
 }
 
-static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       unsigned char *str;
-       int str_len, i, j;
+       zend_string *str;
+       int i, j;
        unsigned char c;
 
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
        if (data && data->children) {
                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
@@ -825,32 +799,31 @@ static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                        return ret;
                }
-               str_len = strlen((char*)data->children->content) / 2;
-               str = emalloc(str_len+1);
-               for (i = j = 0; i < str_len; i++) {
+               str = STR_ALLOC(strlen((char*)data->children->content) / 2, 0);
+               for (i = j = 0; i < str->len; i++) {
                        c = data->children->content[j++];
                        if (c >= '0' && c <= '9') {
-                               str[i] = (c - '0') << 4;
+                               str->val[i] = (c - '0') << 4;
                        } else if (c >= 'a' && c <= 'f') {
-                               str[i] = (c - 'a' + 10) << 4;
+                               str->val[i] = (c - 'a' + 10) << 4;
                        } else if (c >= 'A' && c <= 'F') {
-                               str[i] = (c - 'A' + 10) << 4;
+                               str->val[i] = (c - 'A' + 10) << 4;
                        } else {
                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                        }
                        c = data->children->content[j++];
                        if (c >= '0' && c <= '9') {
-                               str[i] |= c - '0';
+                               str->val[i] |= c - '0';
                        } else if (c >= 'a' && c <= 'f') {
-                               str[i] |= c - 'a' + 10;
+                               str->val[i] |= c - 'a' + 10;
                        } else if (c >= 'A' && c <= 'F') {
-                               str[i] |= c - 'A' + 10;
+                               str->val[i] |= c - 'A' + 10;
                        } else {
                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                        }
                }
-               str[str_len] = '\0';
-               ZVAL_STRINGL(ret, (char*)str, str_len, 0);
+               str->val[str->len] = '\0';
+               ZVAL_STR(ret, str);
        } else {
                ZVAL_EMPTY_STRING(ret);
        }
@@ -948,27 +921,26 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
 static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC)
 {
        xmlNodePtr ret, text;
-       unsigned char *str;
-       int str_len;
+       zend_string *str;
 
        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
        xmlAddChild(parent, ret);
        FIND_ZVAL_NULL(data, ret, style);
 
        if (Z_TYPE_P(data) == IS_STRING) {
-               str = php_base64_encode((unsigned char*)Z_STRVAL_P(data), Z_STRLEN_P(data), &str_len);
-               text = xmlNewTextLen(str, str_len);
+               str = php_base64_encode((unsigned char*)Z_STRVAL_P(data), Z_STRLEN_P(data));
+               text = xmlNewTextLen(BAD_CAST(str->val), str->len);
                xmlAddChild(ret, text);
-               efree(str);
+               STR_RELEASE(str);
        } else {
-               zval tmp = *data;
-
-               zval_copy_ctor(&tmp);
+               zval tmp;
+               
+               ZVAL_DUP(&tmp, data);
                convert_to_string(&tmp);
-               str = php_base64_encode((unsigned char*)Z_STRVAL(tmp), Z_STRLEN(tmp), &str_len);
-               text = xmlNewTextLen(str, str_len);
+               str = php_base64_encode((unsigned char*)Z_STRVAL(tmp), Z_STRLEN(tmp));
+               text = xmlNewTextLen(BAD_CAST(str->val), str->len);
                xmlAddChild(ret, text);
-               efree(str);
+               STR_RELEASE(str);
                zval_dtor(&tmp);
        }
 
@@ -1017,10 +989,9 @@ static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNo
        return ret;
 }
 
-static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_double(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
 
        if (data && data->children) {
@@ -1031,12 +1002,10 @@ static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                        whiteSpace_collapse(data->children->content);
                        switch (is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0)) {
                                case IS_LONG:
-                                       Z_TYPE_P(ret) = IS_DOUBLE;
-                                       Z_DVAL_P(ret) = lval;
+                                       ZVAL_DOUBLE(ret, lval);
                                        break;
                                case IS_DOUBLE:
-                                       Z_TYPE_P(ret) = IS_DOUBLE;
-                                       Z_DVAL_P(ret) = dval;
+                                       ZVAL_DOUBLE(ret, dval);
                                        break;
                                default:
                                        if (strncasecmp((char*)data->children->content, "NaN", sizeof("NaN")-1) == 0) {
@@ -1058,10 +1027,9 @@ static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
        return ret;
 }
 
-static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_long(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
 
        if (data && data->children) {
@@ -1072,12 +1040,12 @@ static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                        whiteSpace_collapse(data->children->content);
                        errno = 0;
 
-                       switch ((Z_TYPE_P(ret) = is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0))) {
+                       switch (is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0)) {
                                case IS_LONG:
-                                       Z_LVAL_P(ret) = lval;
+                                       ZVAL_LONG(ret, lval);
                                        break;
                                case IS_DOUBLE:
-                                       Z_DVAL_P(ret) = dval;
+                                       ZVAL_DOUBLE(ret, dval);
                                        break;
                                default:
                                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
@@ -1149,10 +1117,9 @@ static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNo
        return ret;
 }
 
-static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_bool(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
 
        if (data && data->children) {
@@ -1161,13 +1128,13 @@ static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                        if (stricmp((char*)data->children->content, "true") == 0 ||
                                stricmp((char*)data->children->content, "t") == 0 ||
                                strcmp((char*)data->children->content, "1") == 0) {
-                               ZVAL_BOOL(ret, 1);
+                               ZVAL_TRUE(ret);
                        } else if (stricmp((char*)data->children->content, "false") == 0 ||
                                stricmp((char*)data->children->content, "f") == 0 ||
                                strcmp((char*)data->children->content, "0") == 0) {
-                               ZVAL_BOOL(ret, 0);
+                               ZVAL_FALSE(ret);
                        } else {
-                               ZVAL_STRING(ret, (char*)data->children->content, 1);
+                               ZVAL_STRING(ret, (char*)data->children->content);
                                convert_to_boolean(ret);
                        }
                } else {
@@ -1200,10 +1167,8 @@ static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNode
 }
 
 /* Null encode/decode */
-static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_null(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
        ZVAL_NULL(ret);
        return ret;
 }
@@ -1231,25 +1196,26 @@ static void set_zval_property(zval* object, char* name, zval* val TSRMLS_DC)
        EG(scope) = old_scope;
 }
 
-static zval* get_zval_property(zval* object, char* name TSRMLS_DC)
+static zval* get_zval_property(zval* object, char* name, zval *rv TSRMLS_DC)
 {
        if (Z_TYPE_P(object) == IS_OBJECT) {
-               zval member;
+               zval member, rv;
                zval *data;
                zend_class_entry *old_scope;
 
-               INIT_PZVAL(&member);
-               ZVAL_STRING(&member, name, 0);
+//???          INIT_PZVAL(&member);
+//???          ZVAL_STRING(&member, name, 0);
+               ZVAL_STRING(&member, name);
                old_scope = EG(scope);
                EG(scope) = Z_OBJCE_P(object);
-               data = Z_OBJ_HT_P(object)->read_property(object, &member, BP_VAR_IS, 0 TSRMLS_CC);
-               if (data == EG(uninitialized_zval_ptr)) {
+               data = Z_OBJ_HT_P(object)->read_property(object, &member, BP_VAR_IS, 0, &rv TSRMLS_CC);
+               if (data == &EG(uninitialized_zval)) {
                        /* Hack for bug #32455 */
                        zend_property_info *property_info;
 
                        property_info = zend_get_property_info(Z_OBJCE_P(object), &member, 1 TSRMLS_CC);
                        EG(scope) = old_scope;
-                       if (property_info && zend_hash_quick_exists(Z_OBJPROP_P(object), property_info->name, property_info->name_length+1, property_info->h)) {
+                       if (property_info && zend_hash_exists(Z_OBJPROP_P(object), property_info->name)) {
                                return data;
                        }
                        return NULL;
@@ -1257,13 +1223,13 @@ static zval* get_zval_property(zval* object, char* name TSRMLS_DC)
                EG(scope) = old_scope;
                return data;
        } else if (Z_TYPE_P(object) == IS_ARRAY) {
-               zval **data_ptr;
+               zval *data_ptr;
 
-               if (zend_hash_find(Z_ARRVAL_P(object), name, strlen(name)+1, (void**)&data_ptr) == SUCCESS) {
-                 return *data_ptr;
+               if ((data_ptr = zend_hash_str_find(Z_ARRVAL_P(object), name, strlen(name))) != NULL) {
+                 return data_ptr;
                }
        }
-  return NULL;
+       return NULL;
 }
 
 static void unset_zval_property(zval* object, char* name TSRMLS_DC)
@@ -1272,48 +1238,49 @@ static void unset_zval_property(zval* object, char* name TSRMLS_DC)
                zval member;
                zend_class_entry *old_scope;
 
-               INIT_PZVAL(&member);
-               ZVAL_STRING(&member, name, 0);
+//???          INIT_PZVAL(&member);
+//???          ZVAL_STRING(&member, name, 0);
+               ZVAL_STRING(&member, name);
                old_scope = EG(scope);
                EG(scope) = Z_OBJCE_P(object);
                Z_OBJ_HT_P(object)->unset_property(object, &member, 0 TSRMLS_CC);
                EG(scope) = old_scope;
        } else if (Z_TYPE_P(object) == IS_ARRAY) {
-               zend_hash_del(Z_ARRVAL_P(object), name, strlen(name)+1);
+               zend_hash_str_del(Z_ARRVAL_P(object), name, strlen(name));
        }
 }
 
 static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC)
 {
+       zval rv, arr;
        zval* any = NULL;
        char* name = NULL;
 
        while (node != NULL) {
-               if (get_zval_property(ret, (char*)node->name TSRMLS_CC) == NULL) {
-                       zval* val = master_to_zval(get_conversion(XSD_ANYXML), node TSRMLS_CC);
+               if (get_zval_property(ret, (char*)node->name, &rv TSRMLS_CC) == NULL) {
+                       zval* val = master_to_zval(ret, get_conversion(XSD_ANYXML), node TSRMLS_CC);
                        
                        if (any && Z_TYPE_P(any) != IS_ARRAY) {
                                /* Convert into array */
-                               zval *arr;
-
-                               MAKE_STD_ZVAL(arr);
-                               array_init(arr);
+                               array_init(&arr);
                                if (name) {
-                                       add_assoc_zval(arr, name, any);
+                                       add_assoc_zval(&arr, name, any);
                                } else {
-                                       add_next_index_zval(arr, any);
+                                       add_next_index_zval(&arr, any);
                                }
-                               any = arr;
+                               any = &arr;
                        }
 
                        if (Z_TYPE_P(val) == IS_STRING && *Z_STRVAL_P(val) == '<') {
                                name = NULL;
                                while (node->next != NULL) {
-                                       zval* val2 = master_to_zval(get_conversion(XSD_ANYXML), node->next TSRMLS_CC);
-                                       if (Z_TYPE_P(val2) != IS_STRING ||  *Z_STRVAL_P(val) != '<') {
+                                       zval val2;
+
+                                       master_to_zval(&val2, get_conversion(XSD_ANYXML), node->next TSRMLS_CC);
+                                       if (Z_TYPE(val2) != IS_STRING ||  *Z_STRVAL_P(val) != '<') {
                                                break;
                                        }
-                                       add_string_to_string(val, val, val2);
+                                       add_string_to_string(val, val, &val2);
                                        zval_ptr_dtor(&val2);
                                        node = node->next;
                                }
@@ -1324,12 +1291,9 @@ static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC)
                        if (any == NULL) {
                                if (name) {
                                        /* Convert into array */
-                                       zval *arr;
-
-                                       MAKE_STD_ZVAL(arr);
-                                       array_init(arr);
-                                       add_assoc_zval(arr, name, val);
-                                       any = arr;
+                                       array_init(&arr);
+                                       add_assoc_zval(&arr, name, val);
+                                       any = &arr;
                                        name = NULL;
                                } else {
                                        any = val;
@@ -1337,18 +1301,15 @@ static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC)
                        } else {
                                /* Add array element */
                                if (name) {
-                                       zval **el;
-                                       if (zend_hash_find(Z_ARRVAL_P(any), name, strlen(name)+1, (void**)&el) == SUCCESS) {
-                                               if (Z_TYPE_PP(el) != IS_ARRAY) {
+                                       zval *el;
+                                       if ((el = zend_hash_str_find(Z_ARRVAL_P(any), name, strlen(name))) != NULL) {
+                                               if (Z_TYPE_P(el) != IS_ARRAY) {
                                                        /* Convert into array */
-                                                       zval *arr;
-       
-                                                       MAKE_STD_ZVAL(arr);
-                                                       array_init(arr);
-                                                       add_next_index_zval(arr, *el);
-                                                       *el = arr;
+                                                       array_init(&arr);
+                                                       add_next_index_zval(&arr, el);
+                                                       el = &arr;
                                                }
-                                               add_next_index_zval(*el, val);
+                                               add_next_index_zval(el, val);
                                        } else {
                                                add_assoc_zval(any, name, val);
                                        }
@@ -1373,7 +1334,7 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr
                                xmlNodePtr node = get_node(data->children, model->u.element->name);
 
                                if (node) {
-                                       zval *val;
+                                       zval val;
                                        xmlNodePtr r_node;
 
                                        r_node = check_and_resolve_href(node);
@@ -1381,78 +1342,73 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr
                                                if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)r_node->children->content) != 0) {
                                                        soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, r_node->children->content);
                                                }
-                                               val = master_to_zval(model->u.element->encode, r_node TSRMLS_CC);
+                                               master_to_zval(&val, model->u.element->encode, r_node TSRMLS_CC);
                                        } else if (model->u.element->fixed) {
                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed));
-                                               val = master_to_zval(model->u.element->encode, dummy TSRMLS_CC);
+                                               master_to_zval(&val, model->u.element->encode, dummy TSRMLS_CC);
                                                xmlFreeNode(dummy);
                                        } else if (model->u.element->def && !model->u.element->nillable) {
                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def));
-                                               val = master_to_zval(model->u.element->encode, dummy TSRMLS_CC);
+                                               master_to_zval(&val, model->u.element->encode, dummy TSRMLS_CC);
                                                xmlFreeNode(dummy);
                                        } else {
-                                               val = master_to_zval(model->u.element->encode, r_node TSRMLS_CC);
+                                               master_to_zval(&val, model->u.element->encode, r_node TSRMLS_CC);
                                        }
                                        if ((node = get_node(node->next, model->u.element->name)) != NULL) {
-                                               zval *array;
+                                               zval array;
 
-                                               MAKE_STD_ZVAL(array);
-                                               array_init(array);
-                                               add_next_index_zval(array, val);
+                                               array_init(&array);
+                                               add_next_index_zval(&array, &val);
                                                do {
                                                        if (node && node->children && node->children->content) {
                                                                if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)node->children->content) != 0) {
                                                                        soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, node->children->content);
                                                                }
-                                                               val = master_to_zval(model->u.element->encode, node TSRMLS_CC);
+                                                               master_to_zval(&val, model->u.element->encode, node TSRMLS_CC);
                                                        } else if (model->u.element->fixed) {
                                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed));
-                                                               val = master_to_zval(model->u.element->encode, dummy TSRMLS_CC);
+                                                               master_to_zval(&val, model->u.element->encode, dummy TSRMLS_CC);
                                                                xmlFreeNode(dummy);
                                                        } else if (model->u.element->def && !model->u.element->nillable) {
                                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def));
-                                                               val = master_to_zval(model->u.element->encode, dummy TSRMLS_CC);
+                                                               master_to_zval(&val, model->u.element->encode, dummy TSRMLS_CC);
                                                                xmlFreeNode(dummy);
                                                        } else {
-                                                               val = master_to_zval(model->u.element->encode, node TSRMLS_CC);
+                                                               master_to_zval(&val, model->u.element->encode, node TSRMLS_CC);
                                                        }
-                                                       add_next_index_zval(array, val);
+                                                       add_next_index_zval(&array, &val);
                                                } while ((node = get_node(node->next, model->u.element->name)) != NULL);
-                                               val = array;
-                                       } else if ((Z_TYPE_P(val) != IS_NULL || !model->u.element->nillable) &&
+                                               ZVAL_COPY_VALUE(&val, &array);
+                                       } else if ((Z_TYPE(val) != IS_NULL || !model->u.element->nillable) &&
                                                   (SOAP_GLOBAL(features) & SOAP_SINGLE_ELEMENT_ARRAYS) &&
                                                   (model->max_occurs == -1 || model->max_occurs > 1)) {
-                                               zval *array;
+                                               zval array;
 
-                                               MAKE_STD_ZVAL(array);
-                                               array_init(array);
-                                               add_next_index_zval(array, val);
-                                               val = array;
+                                               array_init(&array);
+                                               add_next_index_zval(&array, &val);
+                                               ZVAL_COPY_VALUE(&val, &array);
                                        }
-                                       set_zval_property(ret, model->u.element->name, val TSRMLS_CC);
+                                       set_zval_property(ret, model->u.element->name, &val TSRMLS_CC);
                                }
                        }
                        break;
                case XSD_CONTENT_ALL:
                case XSD_CONTENT_SEQUENCE:
                case XSD_CONTENT_CHOICE: {
-                       sdlContentModelPtr *tmp;
-                       HashPosition pos;
+                       sdlContentModelPtr tmp;
                        sdlContentModelPtr any = NULL;
 
-                       zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
-                       while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
-                               if ((*tmp)->kind == XSD_CONTENT_ANY) {
-                                       any = *tmp;
+                       ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                               if (tmp->kind == XSD_CONTENT_ANY) {
+                                       any = tmp;
                                } else {
-                                       model_to_zval_object(ret, *tmp, data, sdl TSRMLS_CC);
+                                       model_to_zval_object(ret, tmp, data, sdl TSRMLS_CC);
                                }
-                               zend_hash_move_forward_ex(model->u.content, &pos);
-                       }
+                       } ZEND_HASH_FOREACH_END();
                        if (any) {
                                model_to_zval_any(ret, data->children TSRMLS_CC);
                        }
@@ -1467,24 +1423,23 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr
 }
 
 /* Struct encode/decode */
-static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_entry *pce TSRMLS_DC)
+static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, zend_class_entry *pce TSRMLS_DC)
 {
-       zval *ret;
        xmlNodePtr trav;
        sdlPtr sdl;
        sdlTypePtr sdlType = type->sdl_type;
        zend_class_entry *ce = ZEND_STANDARD_CLASS_DEF_PTR;
-       zval *redo_any = NULL;
+       zval *redo_any = NULL, rv, arr;
 
        if (pce) {
                ce = pce;
        } else if (SOAP_GLOBAL(class_map) && type->type_str) {
-               zval             **classname;
+               zval              *classname;
                zend_class_entry  *tmp;
 
-               if (zend_hash_find(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str)+1, (void**)&classname) == SUCCESS &&
-                   Z_TYPE_PP(classname) == IS_STRING &&
-                   (tmp = zend_fetch_class(Z_STRVAL_PP(classname), Z_STRLEN_PP(classname), ZEND_FETCH_CLASS_AUTO TSRMLS_CC)) != NULL) {
+               if ((classname = zend_hash_str_find(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str))) != NULL &&
+                   Z_TYPE_P(classname) == IS_STRING &&
+                   (tmp = zend_fetch_class(Z_STR_P(classname), ZEND_FETCH_CLASS_AUTO TSRMLS_CC)) != NULL) {
                        ce = tmp;
                }
        }
@@ -1502,20 +1457,20 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
                                enc = enc->details.sdl_type->encode;
                        }
                        if (enc) {
-                               zval *base;
+                               zval base;
 
-                               ALLOC_INIT_ZVAL(ret);
-                               if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
+                               ZVAL_NULL(ret);
+                               if (soap_check_xml_ref(ret, data TSRMLS_CC)) {
                                        return ret;
                                }
 
                                object_init_ex(ret, ce);
-                               base = master_to_zval_int(enc, data TSRMLS_CC);
-                               set_zval_property(ret, "_", base TSRMLS_CC);
+                               master_to_zval_int(&base, enc, data TSRMLS_CC);
+                               set_zval_property(ret, "_", &base TSRMLS_CC);
                        } else {
-                               ALLOC_INIT_ZVAL(ret);
+                               ZVAL_NULL(ret);
                                FIND_XML_NULL(data, ret);
-                               if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
+                               if (soap_check_xml_ref(ret, data TSRMLS_CC)) {
                                        return ret;
                                }
                                object_init_ex(ret, ce);
@@ -1542,34 +1497,34 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
                                (sdlType->encode->details.sdl_type->encode == NULL ||
                                 (sdlType->encode->details.sdl_type->encode->details.type != IS_ARRAY &&
                                  sdlType->encode->details.sdl_type->encode->details.type != SOAP_ENC_ARRAY))) {
-                                       ret = to_zval_object_ex(&sdlType->encode->details, data, ce TSRMLS_CC);
+                                       to_zval_object_ex(ret, &sdlType->encode->details, data, ce TSRMLS_CC);
                            } else {
-                                       ret = master_to_zval_int(sdlType->encode, data TSRMLS_CC);
+                                       master_to_zval_int(ret, sdlType->encode, data TSRMLS_CC);
                                }
-                               if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
+                               if (soap_check_xml_ref(ret, data TSRMLS_CC)) {
                                        return ret;
                                }
-                               redo_any = get_zval_property(ret, "any" TSRMLS_CC);
+                               redo_any = get_zval_property(ret, "any", &rv TSRMLS_CC);
                                if (Z_TYPE_P(ret) == IS_OBJECT && ce != ZEND_STANDARD_CLASS_DEF_PTR) {
-                                       zend_object *zobj = zend_objects_get_address(ret TSRMLS_CC);
+                                       zend_object *zobj = Z_OBJ_P(ret);
                                        zobj->ce = ce;
                                }
                        } else {
-                               zval *base;
+                               zval base;
 
-                               ALLOC_INIT_ZVAL(ret);
-                               if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
+                               ZVAL_NULL(ret);
+                               if (soap_check_xml_ref(ret, data TSRMLS_CC)) {
                                        return ret;
                                }
 
                                object_init_ex(ret, ce);
-                               base = master_to_zval_int(sdlType->encode, data TSRMLS_CC);
-                               set_zval_property(ret, "_", base TSRMLS_CC);
+                               master_to_zval_int(&base, sdlType->encode, data TSRMLS_CC);
+                               set_zval_property(ret, "_", &base TSRMLS_CC);
                        }
                } else {
-                       ALLOC_INIT_ZVAL(ret);
+                       ZVAL_NULL(ret);
                        FIND_XML_NULL(data, ret);
-                       if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
+                       if (soap_check_xml_ref(ret, data TSRMLS_CC)) {
                                return ret;
                        }
                        object_init_ex(ret, ce);
@@ -1581,7 +1536,7 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
                        }
                        model_to_zval_object(ret, sdlType->model, data, sdl TSRMLS_CC);
                        if (redo_any) {
-                               zval *tmp = get_zval_property(ret, "any" TSRMLS_CC);
+                               zval *tmp = get_zval_property(ret, "any", &rv TSRMLS_CC);
 
                                if (tmp == NULL) {
                                        model_to_zval_any(ret, data->children TSRMLS_CC);
@@ -1589,49 +1544,45 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
                                        zval_dtor(tmp);
                                        efree(tmp);
                                }
-                               zval_ptr_dtor(&redo_any);
+                               zval_ptr_dtor(redo_any);
                        }
                }
                if (sdlType->attributes) {
-                       sdlAttributePtr *attr;
-                       HashPosition pos;
+                       sdlAttributePtr attr;
 
-                       zend_hash_internal_pointer_reset_ex(sdlType->attributes, &pos);
-                       while (zend_hash_get_current_data_ex(sdlType->attributes, (void**)&attr, &pos) == SUCCESS) {
-                               if ((*attr)->name) {
-                                       xmlAttrPtr val = get_attribute(data->properties, (*attr)->name);
+                       ZEND_HASH_FOREACH_PTR(sdlType->attributes, attr) {
+                               if (attr->name) {
+                                       xmlAttrPtr val = get_attribute(data->properties, attr->name);
                                        char *str_val = NULL;
 
                                        if (val && val->children && val->children->content) {
                                                str_val = (char*)val->children->content;
-                                               if ((*attr)->fixed && strcmp((*attr)->fixed, str_val) != 0) {
-                                                       soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", (*attr)->name, (*attr)->fixed, str_val);
+                                               if (attr->fixed && strcmp(attr->fixed, str_val) != 0) {
+                                                       soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", attr->name, attr->fixed, str_val);
                                                }
-                                       } else if ((*attr)->fixed) {
-                                               str_val = (*attr)->fixed;
-                                       } else if ((*attr)->def) {
-                                               str_val = (*attr)->def;
+                                       } else if (attr->fixed) {
+                                               str_val = attr->fixed;
+                                       } else if (attr->def) {
+                                               str_val = attr->def;
                                        }
                                        if (str_val) {
                                                xmlNodePtr dummy, text;
-                                               zval *data;
+                                               zval data;
 
                                                dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                                                text = xmlNewText(BAD_CAST(str_val));
                                                xmlAddChild(dummy, text);
-                                               data = master_to_zval((*attr)->encode, dummy TSRMLS_CC);
+                                               master_to_zval(&data, attr->encode, dummy TSRMLS_CC);
                                                xmlFreeNode(dummy);
-                                               set_zval_property(ret, (*attr)->name, data TSRMLS_CC);
+                                               set_zval_property(ret, attr->name, &data TSRMLS_CC);
                                        }
                                }
-                               zend_hash_move_forward_ex(sdlType->attributes, &pos);
-                       }
+                       } ZEND_HASH_FOREACH_END();
                }
        } else {
-
-               ALLOC_INIT_ZVAL(ret);
+               ZVAL_NULL(ret);
                FIND_XML_NULL(data, ret);
-               if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
+               if (soap_check_xml_ref(ret, data TSRMLS_CC)) {
                        return ret;
                }
 
@@ -1640,38 +1591,34 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
 
                while (trav != NULL) {
                        if (trav->type == XML_ELEMENT_NODE) {
-                               zval  *tmpVal;
+                               zval  tmpVal, rv;
                                zval *prop;
 
-                               tmpVal = master_to_zval(NULL, trav TSRMLS_CC);
+                               master_to_zval(&tmpVal, NULL, trav TSRMLS_CC);
 
-                               prop = get_zval_property(ret, (char*)trav->name TSRMLS_CC);
+                               prop = get_zval_property(ret, (char*)trav->name, &rv TSRMLS_CC);
                                if (!prop) {
                                        if (!trav->next || !get_node(trav->next, (char*)trav->name)) {
-                                               set_zval_property(ret, (char*)trav->name, tmpVal TSRMLS_CC);
+                                               set_zval_property(ret, (char*)trav->name, &tmpVal TSRMLS_CC);
                                        } else {
-                                               zval *arr;
+                                               zval arr;
 
-                                               MAKE_STD_ZVAL(arr);
-                                               array_init(arr);
-                                               add_next_index_zval(arr, tmpVal);
-                                               set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC);
+                                               array_init(&arr);
+                                               add_next_index_zval(&arr, &tmpVal);
+                                               set_zval_property(ret, (char*)trav->name, &arr TSRMLS_CC);
                                        }
                                } else {
                                        /* Property already exist - make array */
                                        if (Z_TYPE_P(prop) != IS_ARRAY) {
                                                /* Convert into array */
-                                               zval *arr;
-
-                                               MAKE_STD_ZVAL(arr);
-                                               array_init(arr);
+                                               array_init(&arr);
                                                Z_ADDREF_P(prop);
-                                               add_next_index_zval(arr, prop);
-                                               set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC);
-                                               prop = arr;
+                                               add_next_index_zval(&arr, prop);
+                                               set_zval_property(ret, (char*)trav->name, &arr TSRMLS_CC);
+                                               prop = &arr;
                                        }
                                        /* Add array element */
-                                       add_next_index_zval(prop, tmpVal);
+                                       add_next_index_zval(prop, &tmpVal);
                                }
                        }
                        trav = trav->next;
@@ -1680,9 +1627,9 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
        return ret;
 }
 
-static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_object(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       return to_zval_object_ex(type, data, NULL TSRMLS_CC);
+       return to_zval_object_ex(ret, type, data, NULL TSRMLS_CC);
 }
 
 
@@ -1693,8 +1640,9 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval *
                        zval *data;
                        xmlNodePtr property;
                        encodePtr enc;
+                       zval rv;
 
-                       data = get_zval_property(object, model->u.element->name TSRMLS_CC);
+                       data = get_zval_property(object, model->u.element->name, &rv TSRMLS_CC);
                        if (data &&
                            Z_TYPE_P(data) == IS_NULL &&
                            !model->u.element->nillable &&
@@ -1708,16 +1656,15 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval *
                                    Z_TYPE_P(data) == IS_ARRAY &&
                                    !is_map(data)) {
                                        HashTable *ht = Z_ARRVAL_P(data);
-                                       zval **val;
+                                       zval *val;
 
-                                       zend_hash_internal_pointer_reset(ht);
-                                       while (zend_hash_get_current_data(ht,(void**)&val) == SUCCESS) {
-                                               if (Z_TYPE_PP(val) == IS_NULL && model->u.element->nillable) {
+                                       ZEND_HASH_FOREACH_VAL(ht, val) {
+                                               if (Z_TYPE_P(val) == IS_NULL && model->u.element->nillable) {
                                                        property = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                                                        xmlAddChild(node, property);
                                                        set_xsi_nil(property);
                                                } else {
-                                                       property = master_to_xml(enc, *val, style, node TSRMLS_CC);
+                                                       property = master_to_xml(enc, val, style, node TSRMLS_CC);
                                                        if (property->children && property->children->content &&
                                                            model->u.element->fixed && strcmp(model->u.element->fixed, (char*)property->children->content) != 0) {
                                                                soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, property->children->content);
@@ -1730,8 +1677,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval *
                                                        xmlNsPtr nsp = encode_add_ns(property, model->u.element->namens);
                                                        xmlSetNs(property, nsp);
                                                }
-                                               zend_hash_move_forward(ht);
-                                       }
+                                       } ZEND_HASH_FOREACH_END();
                                } else {
                                        if (Z_TYPE_P(data) == IS_NULL && model->u.element->nillable) {
                                                property = xmlNewNode(NULL, BAD_CAST("BOGUS"));
@@ -1780,21 +1726,20 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval *
                        zval *data;
                        xmlNodePtr property;
                        encodePtr enc;
+                       zval rv;
 
-                       data = get_zval_property(object, "any" TSRMLS_CC);
+                       data = get_zval_property(object, "any", &rv TSRMLS_CC);
                        if (data) {
                                enc = get_conversion(XSD_ANYXML);
                                if ((model->max_occurs == -1 || model->max_occurs > 1) &&
                                    Z_TYPE_P(data) == IS_ARRAY &&
                                    !is_map(data)) {
                                        HashTable *ht = Z_ARRVAL_P(data);
-                                       zval **val;
+                                       zval *val;
 
-                                       zend_hash_internal_pointer_reset(ht);
-                                       while (zend_hash_get_current_data(ht,(void**)&val) == SUCCESS) {
-                                               property = master_to_xml(enc, *val, style, node TSRMLS_CC);
-                                               zend_hash_move_forward(ht);
-                                       }
+                                       ZEND_HASH_FOREACH_VAL(ht, val) {
+                                               property = master_to_xml(enc, val, style, node TSRMLS_CC);
+                                       } ZEND_HASH_FOREACH_END();
                                } else {
                                        property = master_to_xml(enc, data, style, node TSRMLS_CC);
                                }
@@ -1811,36 +1756,30 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval *
                }
                case XSD_CONTENT_SEQUENCE:
                case XSD_CONTENT_ALL: {
-                       sdlContentModelPtr *tmp;
-                       HashPosition pos;
+                       sdlContentModelPtr tmp;
 
-                       zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
-                       while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
-                               if (!model_to_xml_object(node, *tmp, object, style, strict && ((*tmp)->min_occurs > 0) TSRMLS_CC)) {
-                                       if (!strict || (*tmp)->min_occurs > 0) {
+                       ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                               if (!model_to_xml_object(node, tmp, object, style, strict && (tmp->min_occurs > 0) TSRMLS_CC)) {
+                                       if (!strict || tmp->min_occurs > 0) {
                                                return 0;
                                        }
                                }
                                strict = 1;
-                               zend_hash_move_forward_ex(model->u.content, &pos);
-                       }
+                       } ZEND_HASH_FOREACH_END();
                        return 1;
                }
                case XSD_CONTENT_CHOICE: {
-                       sdlContentModelPtr *tmp;
-                       HashPosition pos;
+                       sdlContentModelPtr tmp;
                        int ret = 0;
 
-                       zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
-                       while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
-                               int tmp_ret = model_to_xml_object(node, *tmp, object, style, 0 TSRMLS_CC);
+                       ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                               int tmp_ret = model_to_xml_object(node, tmp, object, style, 0 TSRMLS_CC);
                                if (tmp_ret == 1) {
                                        return 1;
                                } else if (tmp_ret != 0) {
                                        ret = 1;
                                }
-                               zend_hash_move_forward_ex(model->u.content, &pos);
-                       }
+                       } ZEND_HASH_FOREACH_END();
                        return ret;
                }
                case XSD_CONTENT_GROUP: {
@@ -1865,15 +1804,14 @@ static sdlTypePtr model_array_element(sdlContentModelPtr model)
                case XSD_CONTENT_SEQUENCE:
                case XSD_CONTENT_ALL:
                case XSD_CONTENT_CHOICE: {
-                       sdlContentModelPtr *tmp;
-                       HashPosition pos;
+                       sdlContentModelPtr tmp;
 
                        if (zend_hash_num_elements(model->u.content) != 1) {
                          return NULL;
                        }
-                       zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
-                       zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos);
-                       return model_array_element(*tmp);
+                       ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                               return model_array_element(tmp);
+                       } ZEND_HASH_FOREACH_END();
                }
                case XSD_CONTENT_GROUP: {
                        return model_array_element(model->u.group->model);
@@ -1920,7 +1858,8 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
                                enc = enc->details.sdl_type->encode;
                        }
                        if (enc) {
-                               zval *tmp = get_zval_property(data, "_" TSRMLS_CC);
+                               zval rv;
+                               zval *tmp = get_zval_property(data, "_", &rv TSRMLS_CC);
                                if (tmp) {
                                        xmlParam = master_to_xml(enc, tmp, style, parent TSRMLS_CC);
                                } else if (prop == NULL) {
@@ -1940,11 +1879,12 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
 
-                               if (prop) prop->nApplyCount++;
+                               if (prop) ZEND_HASH_INC_APPLY_COUNT(prop);
                                xmlParam = master_to_xml(sdlType->encode, data, style, parent TSRMLS_CC);
-                               if (prop) prop->nApplyCount--;
+                               if (prop) ZEND_HASH_DEC_APPLY_COUNT(prop);
                        } else {
-                               zval *tmp = get_zval_property(data, "_" TSRMLS_CC);
+                               zval rv;
+                               zval *tmp = get_zval_property(data, "_", &rv TSRMLS_CC);
 
                                if (tmp) {
                                        xmlParam = master_to_xml(sdlType->encode, tmp, style, parent TSRMLS_CC);
@@ -1971,17 +1911,16 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
                      sdlType->attributes == NULL &&
                      sdlType->model != NULL &&
                      (array_el = model_array_element(sdlType->model)) != NULL) {
-                               zval **val;
+                               zval *val;
 
-                               zend_hash_internal_pointer_reset(prop);
-                               while (zend_hash_get_current_data(prop,(void**)&val) == SUCCESS) {
+                               ZEND_HASH_FOREACH_VAL(prop, val) {
                                        xmlNodePtr property;
-                                       if (Z_TYPE_PP(val) == IS_NULL && array_el->nillable) {
+                                       if (Z_TYPE_P(val) == IS_NULL && array_el->nillable) {
                                                property = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                                                xmlAddChild(xmlParam, property);
                                                set_xsi_nil(property);
                                        } else {
-                                               property = master_to_xml(array_el->encode, *val, style, xmlParam TSRMLS_CC);
+                                               property = master_to_xml(array_el->encode, val, style, xmlParam TSRMLS_CC);
                                        }
                                        xmlNodeSetName(property, BAD_CAST(array_el->name));
                                        if (style == SOAP_LITERAL &&
@@ -1990,47 +1929,43 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
                                                xmlNsPtr nsp = encode_add_ns(property, array_el->namens);
                                                xmlSetNs(property, nsp);
                                        }
-                                       zend_hash_move_forward(prop);
-                               }
+                               } ZEND_HASH_FOREACH_END();
                        } else if (sdlType->model) {
                                model_to_xml_object(xmlParam, sdlType->model, data, style, 1 TSRMLS_CC);
                        }
                        if (sdlType->attributes) {
-                               sdlAttributePtr *attr;
-                               zval *zattr;
-                               HashPosition pos;
-
-                               zend_hash_internal_pointer_reset_ex(sdlType->attributes, &pos);
-                               while (zend_hash_get_current_data_ex(sdlType->attributes, (void**)&attr, &pos) == SUCCESS) {
-                                       if ((*attr)->name) {
-                                               zattr = get_zval_property(data, (*attr)->name TSRMLS_CC);
+                               sdlAttributePtr attr;
+                               zval *zattr, rv;
+
+                               ZEND_HASH_FOREACH_PTR(sdlType->attributes, attr) {
+                                       if (attr->name) {
+                                               zattr = get_zval_property(data, attr->name, &rv TSRMLS_CC);
                                                if (zattr) {
                                                        xmlNodePtr dummy;
 
-                                                       dummy = master_to_xml((*attr)->encode, zattr, SOAP_LITERAL, xmlParam TSRMLS_CC);
+                                                       dummy = master_to_xml(attr->encode, zattr, SOAP_LITERAL, xmlParam TSRMLS_CC);
                                                        if (dummy->children && dummy->children->content) {
-                                                               if ((*attr)->fixed && strcmp((*attr)->fixed, (char*)dummy->children->content) != 0) {
-                                                                       soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", (*attr)->name, (*attr)->fixed, dummy->children->content);
+                                                               if (attr->fixed && strcmp(attr->fixed, (char*)dummy->children->content) != 0) {
+                                                                       soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", attr->name, attr->fixed, dummy->children->content);
                                                                }
                                                                /* we need to handle xml: namespace specially, since it is
                                                                   an implicit schema. Otherwise, use form.
                                                                */
-                                                               if ((*attr)->namens &&
-                                                                   (!strncmp((*attr)->namens, XML_NAMESPACE, sizeof(XML_NAMESPACE)) ||
-                                                                    (*attr)->form == XSD_FORM_QUALIFIED)) {
-                                                                       xmlNsPtr nsp = encode_add_ns(xmlParam, (*attr)->namens);
+                                                               if (attr->namens &&
+                                                                   (!strncmp(attr->namens, XML_NAMESPACE, sizeof(XML_NAMESPACE)) ||
+                                                                    attr->form == XSD_FORM_QUALIFIED)) {
+                                                                       xmlNsPtr nsp = encode_add_ns(xmlParam, attr->namens);
 
-                                                                       xmlSetNsProp(xmlParam, nsp, BAD_CAST((*attr)->name), dummy->children->content);
+                                                                       xmlSetNsProp(xmlParam, nsp, BAD_CAST(attr->name), dummy->children->content);
                                                                } else {
-                                                                       xmlSetProp(xmlParam, BAD_CAST((*attr)->name), dummy->children->content);
+                                                                       xmlSetProp(xmlParam, BAD_CAST(attr->name), dummy->children->content);
                                                                }
                                                        }
                                                        xmlUnlinkNode(dummy);
                                                        xmlFreeNode(dummy);
                                                }
                                        }
-                                       zend_hash_move_forward_ex(sdlType->attributes, &pos);
-                               }
+                               } ZEND_HASH_FOREACH_END();
                        }
                }
                if (style == SOAP_ENCODED) {
@@ -2049,16 +1984,15 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
 
                        for (;i > 0;i--) {
                                xmlNodePtr property;
-                               zval **zprop;
-                               char *str_key;
+                               zval *zprop;
+                               zend_string *str_key;
                                ulong index;
                                int key_type;
-                               unsigned int str_key_len;
 
-                               key_type = zend_hash_get_current_key_ex(prop, &str_key, &str_key_len, &index, FALSE, NULL);
-                               zend_hash_get_current_data(prop, (void **)&zprop);
+                               key_type = zend_hash_get_current_key_ex(prop, &str_key, &index, FALSE, &prop->nInternalPointer);
+                               zprop = zend_hash_get_current_data(prop);
 
-                               property = master_to_xml(get_conversion((*zprop)->type), (*zprop), style, xmlParam TSRMLS_CC);
+                               property = master_to_xml(get_conversion(Z_TYPE_P(zprop)), zprop, style, xmlParam TSRMLS_CC);
 
                                if (key_type == HASH_KEY_IS_STRING) {
                                        const char *prop_name;
@@ -2066,9 +2000,9 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
                                        if (Z_TYPE_P(data) == IS_OBJECT) {
                                                const char *class_name;
 
-                                               zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
+                                               zend_unmangle_property_name(str_key->val, str_key->len, &class_name, &prop_name);
                                        } else {
-                                               prop_name = str_key;
+                                               prop_name = str_key->val;
                                        }
                                        if (prop_name) {
                                                xmlNodeSetName(property, BAD_CAST(prop_name));
@@ -2209,11 +2143,11 @@ static void add_xml_array_elements(xmlNodePtr xmlParam,
        int j;
 
        if (data && Z_TYPE_P(data) == IS_ARRAY) {
-               zend_hash_internal_pointer_reset(data->value.ht);
+               zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
                for (j=0; j<dims[0]; j++) {
-                       zval **zdata;
+                       zval *zdata;
 
-                       if (zend_hash_get_current_data(data->value.ht, (void **)&zdata) != SUCCESS) {
+                       if ((zdata = zend_hash_get_current_data(Z_ARRVAL_P(data))) == NULL) {
                                zdata = NULL;
                        }
                        if (dimension == 1) {
@@ -2221,9 +2155,9 @@ static void add_xml_array_elements(xmlNodePtr xmlParam,
 
                                if (zdata) {
                                        if (enc == NULL) {
-                                               xparam = master_to_xml(get_conversion((*zdata)->type), (*zdata), style, xmlParam TSRMLS_CC);
+                                               xparam = master_to_xml(get_conversion(Z_TYPE_P(zdata)), zdata, style, xmlParam TSRMLS_CC);
                                        } else {
-                                               xparam = master_to_xml(enc, (*zdata), style, xmlParam TSRMLS_CC);
+                                               xparam = master_to_xml(enc, zdata, style, xmlParam TSRMLS_CC);
                                        }
                                } else {
                                        xparam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
@@ -2240,12 +2174,12 @@ static void add_xml_array_elements(xmlNodePtr xmlParam,
                                }
                        } else {
                                if (zdata) {
-                                 add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, *zdata, style TSRMLS_CC);
+                                 add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, zdata, style TSRMLS_CC);
                                } else {
                                  add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, NULL, style TSRMLS_CC);
                                }
                        }
-                       zend_hash_move_forward(data->value.ht);
+                       zend_hash_move_forward(Z_ARRVAL_P(data));
                }
        } else {
                for (j=0; j<dims[0]; j++) {
@@ -2272,8 +2206,8 @@ static void add_xml_array_elements(xmlNodePtr xmlParam,
 static inline int array_num_elements(HashTable* ht)
 {
        if (ht->nNumUsed &&
-           ht->arData[ht->nNumUsed-1].xData &&
-           ht->arData[ht->nNumUsed-1].nKeyLength == 0) {
+           Z_TYPE(ht->arData[ht->nNumUsed-1].val) != IS_UNUSED &&
+           ht->arData[ht->nNumUsed-1].key == NULL) {
 
            return ht->arData[ht->nNumUsed-1].h - 1;
        }
@@ -2291,8 +2225,9 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
        int dimension = 1;
        int* dims;
        int soap_version;
-       zval *array_copy = NULL;
+       zval array_copy;
 
+       ZVAL_UNDEF(&array_copy);
        soap_version = SOAP_GLOBAL(soap_version);
 
        xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
@@ -2313,11 +2248,9 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
        if (Z_TYPE_P(data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(data), zend_ce_traversable TSRMLS_CC)) {
                zend_object_iterator   *iter;
                zend_class_entry       *ce = Z_OBJCE_P(data);
-               zval                  **val;
+               zval                   *val;
 
-               ALLOC_ZVAL(array_copy);
-               INIT_PZVAL(array_copy);
-               array_init(array_copy);
+               array_init(&array_copy);
 
                iter = ce->get_iterator(ce, data, 0 TSRMLS_CC);
 
@@ -2337,7 +2270,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
                                goto iterator_done;
                        }
 
-                       iter->funcs->get_current_data(iter, &val TSRMLS_CC);
+                       val = iter->funcs->get_current_data(iter TSRMLS_CC);
                        if (EG(exception)) {
                                goto iterator_done;
                        }
@@ -2347,13 +2280,13 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
                                if (EG(exception)) {
                                        goto iterator_done;
                                }
-                               array_set_zval_key(Z_ARRVAL_P(array_copy), &key, *val);
+                               array_set_zval_key(Z_ARRVAL(array_copy), &key, val);
                                zval_ptr_dtor(val);
                                zval_dtor(&key);
                        } else {
-                               add_next_index_zval(array_copy, *val);
+                               add_next_index_zval(&array_copy, val);
                        }
-                       Z_ADDREF_PP(val);
+                       Z_ADDREF_P(val);
 
                        iter->funcs->move_forward(iter TSRMLS_CC);
                        if (EG(exception)) {
@@ -2364,54 +2297,54 @@ iterator_done:
                iter->funcs->dtor(iter TSRMLS_CC);
                if (EG(exception)) {
                        zval_ptr_dtor(&array_copy);
-                       array_copy = NULL;
+                       ZVAL_UNDEF(&array_copy);
                } else {
-                       data = array_copy;
+                       data = &array_copy;
                }
        }
 
        if (Z_TYPE_P(data) == IS_ARRAY) {
-               sdlAttributePtr *arrayType;
-               sdlExtraAttributePtr *ext;
+               sdlAttributePtr arrayType;
+               sdlExtraAttributePtr ext;
                sdlTypePtr elementType;
 
                i = zend_hash_num_elements(Z_ARRVAL_P(data));
 
                if (sdl_type &&
                    sdl_type->attributes &&
-                   zend_hash_find(sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
-                     sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"),
-                     (void **)&arrayType) == SUCCESS &&
-                   (*arrayType)->extraAttributes &&
-                   zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
+                   (arrayType = zend_hash_str_find_ptr(sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
+                     sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType")-1)) != NULL &&
+                   arrayType->extraAttributes &&
+                   (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType")-1)) != NULL) {
 
                        char *value, *end;
-                       zval** el;
+                       zval *el;
 
-                       value = estrdup((*ext)->val);
+                       value = estrdup(ext->val);
                        end = strrchr(value,'[');
                        if (end) {
                                *end = '\0';
                                end++;
                                dimension = calc_dimension(end);
                        }
-                       if ((*ext)->ns != NULL) {
-                               enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, value);
-                               get_type_str(xmlParam, (*ext)->ns, value, &array_type);
+                       if (ext->ns != NULL) {
+                               enc = get_encoder(SOAP_GLOBAL(sdl), ext->ns, value);
+                               get_type_str(xmlParam, ext->ns, value, &array_type);
                        } else {
                                smart_str_appends(&array_type, value);
                        }
 
                        dims = safe_emalloc(sizeof(int), dimension, 0);
                        dims[0] = i;
-                       el = &data;
+                       //??? el = &data;
+                       el = data;
                        for (i = 1; i < dimension; i++) {
-                               if (el != NULL && Z_TYPE_PP(el) == IS_ARRAY &&
-                                   zend_hash_num_elements(Z_ARRVAL_PP(el)) > 0) {
-                                 zend_hash_internal_pointer_reset(Z_ARRVAL_PP(el));
-                                       zend_hash_get_current_data(Z_ARRVAL_PP(el), (void**)&el);
-                                       if (Z_TYPE_PP(el) == IS_ARRAY) {
-                                               dims[i] = zend_hash_num_elements(Z_ARRVAL_PP(el));
+                               if (el != NULL && Z_TYPE_P(el) == IS_ARRAY &&
+                                   zend_hash_num_elements(Z_ARRVAL_P(el)) > 0) {
+                                       zend_hash_internal_pointer_reset(Z_ARRVAL_P(el));
+                                       el = zend_hash_get_current_data(Z_ARRVAL_P(el));
+                                       if (Z_TYPE_P(el) == IS_ARRAY) {
+                                               dims[i] = zend_hash_num_elements(Z_ARRVAL_P(el));
                                        } else {
                                                dims[i] = 0;
                                        }
@@ -2428,24 +2361,22 @@ iterator_done:
 
                } else if (sdl_type &&
                           sdl_type->attributes &&
-                          zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
-                            sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"),
-                            (void **)&arrayType) == SUCCESS &&
-                          (*arrayType)->extraAttributes &&
-                          zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) {
-                       if ((*ext)->ns != NULL) {
-                               enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, (*ext)->val);
-                               get_type_str(xmlParam, (*ext)->ns, (*ext)->val, &array_type);
+                          (arrayType = zend_hash_str_find_ptr(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
+                            sizeof(SOAP_1_2_ENC_NAMESPACE":itemType")-1)) != NULL &&
+                          arrayType->extraAttributes &&
+                          (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType")-1)) != NULL) {
+                       if (ext->ns != NULL) {
+                               enc = get_encoder(SOAP_GLOBAL(sdl), ext->ns, ext->val);
+                               get_type_str(xmlParam, ext->ns, ext->val, &array_type);
                        } else {
-                               smart_str_appends(&array_type, (*ext)->val);
-                       }
-                       if (zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
-                                          sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
-                                          (void **)&arrayType) == SUCCESS &&
-                           (*arrayType)->extraAttributes &&
-                           zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) {
-                               dimension = calc_dimension_12((*ext)->val);
-                               dims = get_position_12(dimension, (*ext)->val);
+                               smart_str_appends(&array_type, ext->val);
+                       }
+                       if ((arrayType = zend_hash_str_find_ptr(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
+                                          sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize")-1)) != NULL &&
+                           arrayType->extraAttributes &&
+                           (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize")-1)) != NULL) {
+                               dimension = calc_dimension_12(ext->val);
+                               dims = get_position_12(dimension, ext->val);
                                if (dims[0] == 0) {dims[0] = i;}
 
                                smart_str_append_long(&array_size, dims[0]);
@@ -2460,13 +2391,12 @@ iterator_done:
                        }
                } else if (sdl_type &&
                           sdl_type->attributes &&
-                          zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
-                            sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
-                            (void **)&arrayType) == SUCCESS &&
-                          (*arrayType)->extraAttributes &&
-                          zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraySize"), (void **)&ext) == SUCCESS) {
-                       dimension = calc_dimension_12((*ext)->val);
-                       dims = get_position_12(dimension, (*ext)->val);
+                          (arrayType = zend_hash_str_find_ptr(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
+                            sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize")-1)) != NULL &&
+                          arrayType->extraAttributes &&
+                          (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraySize")-1)) != NULL) {
+                       dimension = calc_dimension_12(ext->val);
+                       dims = get_position_12(dimension, ext->val);
                        if (dims[0] == 0) {dims[0] = i;}
 
                        smart_str_append_long(&array_size, dims[0]);
@@ -2478,8 +2408,7 @@ iterator_done:
                        if (sdl_type && sdl_type->elements &&
                            zend_hash_num_elements(sdl_type->elements) == 1 &&
                            (zend_hash_internal_pointer_reset(sdl_type->elements),
-                            zend_hash_get_current_data(sdl_type->elements, (void**)&elementType) == SUCCESS) &&
-                                       (elementType = *(sdlTypePtr*)elementType) != NULL &&
+                            (elementType = zend_hash_get_current_data_ptr(sdl_type->elements)) != NULL) &&
                             elementType->encode && elementType->encode->details.type_str) {
                                element_type = elementType;
                                enc = elementType->encode;
@@ -2490,8 +2419,7 @@ iterator_done:
                } else if (sdl_type && sdl_type->elements &&
                           zend_hash_num_elements(sdl_type->elements) == 1 &&
                           (zend_hash_internal_pointer_reset(sdl_type->elements),
-                           zend_hash_get_current_data(sdl_type->elements, (void**)&elementType) == SUCCESS) &&
-                          (elementType = *(sdlTypePtr*)elementType) != NULL &&
+                           (elementType = zend_hash_get_current_data_ptr(sdl_type->elements)) != NULL) &&
                           elementType->encode && elementType->encode->details.type_str) {
 
                        element_type = elementType;
@@ -2513,7 +2441,7 @@ iterator_done:
                if (style == SOAP_ENCODED) {
                        if (soap_version == SOAP_1_1) {
                                smart_str_0(&array_type);
-                               if (strcmp(array_type.c,"xsd:anyType") == 0) {
+                               if (strcmp(array_type.s->val,"xsd:anyType") == 0) {
                                        smart_str_free(&array_type);
                                        smart_str_appendl(&array_type,"xsd:ur-type",sizeof("xsd:ur-type")-1);
                                }
@@ -2521,17 +2449,17 @@ iterator_done:
                                smart_str_append(&array_type, &array_size);
                                smart_str_appendc(&array_type, ']');
                                smart_str_0(&array_type);
-                               set_ns_prop(xmlParam, SOAP_1_1_ENC_NAMESPACE, "arrayType", array_type.c);
+                               set_ns_prop(xmlParam, SOAP_1_1_ENC_NAMESPACE, "arrayType", array_type.s->val);
                        } else {
                                int i = 0;
-                               while (i < array_size.len) {
-                                       if (array_size.c[i] == ',') {array_size.c[i] = ' ';}
+                               while (i < array_size.s->len) {
+                                       if (array_size.s->val[i] == ',') {array_size.s->val[i] = ' ';}
                                        ++i;
                                }
                                smart_str_0(&array_type);
                                smart_str_0(&array_size);
-                               set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "itemType", array_type.c);
-                               set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "arraySize", array_size.c);
+                               set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "itemType", array_type.s->val);
+                               set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "arraySize", array_size.s->val);
                        }
                }
                smart_str_free(&array_type);
@@ -2548,16 +2476,13 @@ iterator_done:
                }
        }
 
-       if (array_copy) {
-               zval_ptr_dtor(&array_copy);
-       }
+       zval_ptr_dtor(&array_copy);
 
        return xmlParam;
 }
 
-static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret;
        xmlNodePtr trav;
        encodePtr enc = NULL;
        int dimension = 1;
@@ -2565,11 +2490,11 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
        int* pos = NULL;
        xmlAttrPtr attr;
        sdlPtr sdl;
-       sdlAttributePtr *arrayType;
-       sdlExtraAttributePtr *ext;
+       sdlAttributePtr arrayType;
+       sdlExtraAttributePtr ext;
        sdlTypePtr elementType;
 
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
        sdl = SOAP_GLOBAL(sdl);
 
@@ -2625,20 +2550,19 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 
        } else if (type->sdl_type != NULL &&
                   type->sdl_type->attributes != NULL &&
-                  zend_hash_find(type->sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
-                                 sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"),
-                                 (void **)&arrayType) == SUCCESS &&
-                  (*arrayType)->extraAttributes &&
-                  zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
+                  (arrayType = zend_hash_str_find_ptr(type->sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
+                                 sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType")-1)) != NULL &&
+                  arrayType->extraAttributes &&
+                  (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType")-1)) != NULL) {
                char *type, *end;
 
-               type = estrdup((*ext)->val);
+               type = estrdup(ext->val);
                end = strrchr(type,'[');
                if (end) {
                        *end = '\0';
                }
-               if ((*ext)->ns != NULL) {
-                       enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, type);
+               if (ext->ns != NULL) {
+                       enc = get_encoder(SOAP_GLOBAL(sdl), ext->ns, type);
                }
                efree(type);
 
@@ -2647,50 +2571,45 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 
        } else if (type->sdl_type != NULL &&
                   type->sdl_type->attributes != NULL &&
-                  zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
-                                 sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"),
-                                 (void **)&arrayType) == SUCCESS &&
-                  (*arrayType)->extraAttributes &&
-                  zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) {
-
-               if ((*ext)->ns != NULL) {
-                       enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, (*ext)->val);
-               }
-
-               if (zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
-                                  sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
-                                  (void **)&arrayType) == SUCCESS &&
-                   (*arrayType)->extraAttributes &&
-                   zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) {
-                       dimension = calc_dimension_12((*ext)->val);
-                       dims = get_position_12(dimension, (*ext)->val);
+                  (arrayType = zend_hash_str_find_ptr(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
+                                 sizeof(SOAP_1_2_ENC_NAMESPACE":itemType")-1)) != NULL &&
+                  arrayType->extraAttributes &&
+                  (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType")-1)) != NULL) {
+
+               if (ext->ns != NULL) {
+                       enc = get_encoder(SOAP_GLOBAL(sdl), ext->ns, ext->val);
+               }
+
+               if ((arrayType = zend_hash_str_find_ptr(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
+                                  sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize")-1)) != NULL &&
+                   arrayType->extraAttributes &&
+                   (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize")-1)) != NULL) {
+                       dimension = calc_dimension_12(ext->val);
+                       dims = get_position_12(dimension, ext->val);
                } else {
                        dims = emalloc(sizeof(int));
                        *dims = 0;
                }
        } else if (type->sdl_type != NULL &&
                   type->sdl_type->attributes != NULL &&
-                  zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
-                                 sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
-                                 (void **)&arrayType) == SUCCESS &&
-                  (*arrayType)->extraAttributes &&
-                  zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) {
-
-               dimension = calc_dimension_12((*ext)->val);
-               dims = get_position_12(dimension, (*ext)->val);
+                  (arrayType = zend_hash_str_find_ptr(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
+                                 sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize")-1)) != NULL &&
+                  arrayType->extraAttributes &&
+                  (ext = zend_hash_str_find_ptr(arrayType->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize")-1)) != NULL) {
+
+               dimension = calc_dimension_12(ext->val);
+               dims = get_position_12(dimension, ext->val);
                if (type->sdl_type && type->sdl_type->elements &&
                    zend_hash_num_elements(type->sdl_type->elements) == 1 &&
                    (zend_hash_internal_pointer_reset(type->sdl_type->elements),
-                    zend_hash_get_current_data(type->sdl_type->elements, (void**)&elementType) == SUCCESS) &&
-                   (elementType = *(sdlTypePtr*)elementType) != NULL &&
+                    (elementType = zend_hash_get_current_data_ptr(type->sdl_type->elements)) != NULL) &&
                    elementType->encode) {
                        enc = elementType->encode;
                }
        } else if (type->sdl_type && type->sdl_type->elements &&
                   zend_hash_num_elements(type->sdl_type->elements) == 1 &&
                   (zend_hash_internal_pointer_reset(type->sdl_type->elements),
-                   zend_hash_get_current_data(type->sdl_type->elements, (void**)&elementType) == SUCCESS) &&
-                  (elementType = *(sdlTypePtr*)elementType) != NULL &&
+                   (elementType = zend_hash_get_current_data_ptr(type->sdl_type->elements)) != NULL) &&
                   elementType->encode) {
                enc = elementType->encode;
        }
@@ -2717,10 +2636,10 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
        while (trav) {
                if (trav->type == XML_ELEMENT_NODE) {
                        int i;
-                       zval *tmpVal, *ar;
+                       zval tmpVal, *ar;
                        xmlAttrPtr position = get_attribute(trav->properties,"position");
 
-                       tmpVal = master_to_zval(enc, trav TSRMLS_CC);
+                       master_to_zval(&tmpVal, enc, trav TSRMLS_CC);
                        if (position != NULL && position->children && position->children->content) {
                                char* tmp = strrchr((char*)position->children->content, '[');
                                if (tmp == NULL) {
@@ -2733,19 +2652,17 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                        i = 0;
                        ar = ret;
                        while (i < dimension-1) {
-                               zval** ar2;
-                               if (zend_hash_index_find(Z_ARRVAL_P(ar), pos[i], (void**)&ar2) == SUCCESS) {
-                                       ar = *ar2;
+                               zval* ar2;
+                               if ((ar2 = zend_hash_index_find(Z_ARRVAL_P(ar), pos[i])) != NULL) {
+                                       ar = ar2;
                                } else {
-                                       zval *tmpAr;
-                                       MAKE_STD_ZVAL(tmpAr);
-                                       array_init(tmpAr);
-                                       zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpAr, sizeof(zval*), (void**)&ar2);
-                                       ar = *ar2;
+                                       zval tmpAr;
+                                       array_init(&tmpAr);
+                                       ar = zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpAr);
                                }
                                i++;
                        }
-                       zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpVal, sizeof(zval *), NULL);
+                       zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpVal);
 
                        /* Increment position */
                        i = dimension;
@@ -2782,24 +2699,24 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP
 
        if (Z_TYPE_P(data) == IS_ARRAY) {
                i = zend_hash_num_elements(Z_ARRVAL_P(data));
-               zend_hash_internal_pointer_reset(data->value.ht);
+               zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
                for (;i > 0;i--) {
                        xmlNodePtr xparam, item;
                        xmlNodePtr key;
-                       zval **temp_data;
-                       char *key_val;
+                       zval *temp_data;
+                       zend_string *key_val;
                        ulong int_val;
 
-                       zend_hash_get_current_data(data->value.ht, (void **)&temp_data);
+                       temp_data = zend_hash_get_current_data(Z_ARRVAL_P(data));
                        item = xmlNewNode(NULL, BAD_CAST("item"));
                        xmlAddChild(xmlParam, item);
                        key = xmlNewNode(NULL, BAD_CAST("key"));
                        xmlAddChild(item,key);
-                       if (zend_hash_get_current_key(data->value.ht, &key_val, &int_val, FALSE) == HASH_KEY_IS_STRING) {
+                       if (zend_hash_get_current_key(Z_ARRVAL_P(data), &key_val, &int_val, FALSE) == HASH_KEY_IS_STRING) {
                                if (style == SOAP_ENCODED) {
                                        set_xsi_type(key, "xsd:string");
                                }
-                               xmlNodeSetContent(key, BAD_CAST(key_val));
+                               xmlNodeSetContent(key, BAD_CAST(key_val->val));
                        } else {
                                smart_str tmp = {0};
                                smart_str_append_long(&tmp, int_val);
@@ -2808,15 +2725,15 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP
                                if (style == SOAP_ENCODED) {
                                        set_xsi_type(key, "xsd:int");
                                }
-                               xmlNodeSetContentLen(key, BAD_CAST(tmp.c), tmp.len);
+                               xmlNodeSetContentLen(key, BAD_CAST(tmp.s->val), tmp.s->len);
 
                                smart_str_free(&tmp);
                        }
 
-                       xparam = master_to_xml(get_conversion((*temp_data)->type), (*temp_data), style, item TSRMLS_CC);
+                       xparam = master_to_xml(get_conversion(Z_TYPE_P(temp_data)), temp_data, style, item TSRMLS_CC);
                        xmlNodeSetName(xparam, BAD_CAST("value"));
 
-                       zend_hash_move_forward(data->value.ht);
+                       zend_hash_move_forward(Z_ARRVAL_P(data));
                }
        }
        if (style == SOAP_ENCODED) {
@@ -2826,12 +2743,12 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP
        return xmlParam;
 }
 
-static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_map(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
-       zval *ret, *key, *value;
+       zval key, value;
        xmlNodePtr trav, item, xmlKey, xmlValue;
 
-       MAKE_STD_ZVAL(ret);
+       ZVAL_NULL(ret);
        FIND_XML_NULL(data, ret);
 
        if (data && data->children) {
@@ -2850,13 +2767,13 @@ static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                                soap_error0(E_ERROR,  "Encoding: Can't decode apache map, missing value");
                        }
 
-                       key = master_to_zval(NULL, xmlKey TSRMLS_CC);
-                       value = master_to_zval(NULL, xmlValue TSRMLS_CC);
+                       master_to_zval(&key, NULL, xmlKey TSRMLS_CC);
+                       master_to_zval(&value, NULL, xmlValue TSRMLS_CC);
 
-                       if (Z_TYPE_P(key) == IS_STRING) {
-                               zend_symtable_update(Z_ARRVAL_P(ret), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
-                       } else if (Z_TYPE_P(key) == IS_LONG) {
-                               zend_hash_index_update(Z_ARRVAL_P(ret), Z_LVAL_P(key), &value, sizeof(zval *), NULL);
+                       if (Z_TYPE(key) == IS_STRING) {
+                               zend_symtable_update(Z_ARRVAL_P(ret), Z_STR(key), &value);
+                       } else if (Z_TYPE(key) == IS_LONG) {
+                               zend_hash_index_update(Z_ARRVAL_P(ret), Z_LVAL(key), &value);
                        } else {
                                soap_error0(E_ERROR,  "Encoding: Can't decode apache map, only Strings or Longs are allowd as keys");
                        }
@@ -2876,7 +2793,7 @@ static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, x
        xmlNodePtr ret;
 
        if (data) {
-               enc = get_conversion(data->type);
+               enc = get_conversion(Z_TYPE_P(data));
        } else {
                enc = get_conversion(IS_NULL);
        }
@@ -2889,12 +2806,11 @@ static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, x
        return ret;
 }
 
-static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *guess_zval_convert(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
        encodePtr enc = NULL;
        xmlAttrPtr tmpattr;
        xmlChar *type_name = NULL;
-       zval *ret;
 
        data = check_and_resolve_href(data);
 
@@ -2947,26 +2863,25 @@ static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                        }
                }
        }
-       ret = master_to_zval_int(enc, data TSRMLS_CC);
+       master_to_zval_int(ret, enc, data TSRMLS_CC);
        if (SOAP_GLOBAL(sdl) && type_name && enc->details.sdl_type) {
-               zval* soapvar;
+               zval soapvar;
                char *ns, *cptype;
                xmlNsPtr nsptr;
 
-               MAKE_STD_ZVAL(soapvar);
-               object_init_ex(soapvar, soap_var_class_entry);
-               add_property_long(soapvar, "enc_type", enc->details.type);
+               object_init_ex(&soapvar, soap_var_class_entry);
+               add_property_long(&soapvar, "enc_type", enc->details.type);
                Z_DELREF_P(ret);
-               add_property_zval(soapvar, "enc_value", ret);
+               add_property_zval(&soapvar, "enc_value", ret);
                parse_namespace(type_name, &cptype, &ns);
                nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns));
-               add_property_string(soapvar, "enc_stype", cptype);
+               add_property_string(&soapvar, "enc_stype", cptype);
                if (nsptr) {
-                       add_property_string(soapvar, "enc_ns", (char*)nsptr->href);
+                       add_property_string(&soapvar, "enc_ns", (char*)nsptr->href);
                }
                efree(cptype);
                if (ns) {efree(ns);}
-               ret = soapvar;
+               ZVAL_COPY_VALUE(ret, &soapvar);
        }
        return ret;
 }
@@ -3083,9 +2998,9 @@ static xmlNodePtr to_xml_gmonth(encodeTypePtr type, zval *data, int style, xmlNo
        return to_xml_datetime_ex(type, data, "--%m--", style, parent TSRMLS_CC);
 }
 
-static zval* to_zval_list(encodeTypePtr enc, xmlNodePtr data TSRMLS_DC) {
+static zval* to_zval_list(zval *ret, encodeTypePtr enc, xmlNodePtr data TSRMLS_DC) {
        /*FIXME*/
-       return to_zval_stringc(enc, data TSRMLS_CC);
+       return to_zval_stringc(ret, enc, data TSRMLS_CC);
 }
 
 static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent TSRMLS_DC) {
@@ -3093,27 +3008,26 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP
        encodePtr list_enc = NULL;
 
        if (enc->sdl_type && enc->sdl_type->kind == XSD_TYPEKIND_LIST && enc->sdl_type->elements) {
-               sdlTypePtr *type;
+               sdlTypePtr type;
 
-               zend_hash_internal_pointer_reset(enc->sdl_type->elements);
-               if (zend_hash_get_current_data(enc->sdl_type->elements, (void**)&type) == SUCCESS) {
-                       list_enc = (*type)->encode;
-               }
+               ZEND_HASH_FOREACH_PTR(enc->sdl_type->elements, type) {
+                       list_enc = type->encode;
+                       break;
+               } ZEND_HASH_FOREACH_END();
        }
 
        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
        xmlAddChild(parent, ret);
        FIND_ZVAL_NULL(data, ret, style);
        if (Z_TYPE_P(data) == IS_ARRAY) {
-               zval **tmp;
+               zval *tmp;
                smart_str list = {0};
                HashTable *ht = Z_ARRVAL_P(data);
 
-               zend_hash_internal_pointer_reset(ht);
-               while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
-                       xmlNodePtr dummy = master_to_xml(list_enc, *tmp, SOAP_LITERAL, ret TSRMLS_CC);
+               ZEND_HASH_FOREACH_VAL(ht, tmp) {
+                       xmlNodePtr dummy = master_to_xml(list_enc, tmp, SOAP_LITERAL, ret TSRMLS_CC);
                        if (dummy && dummy->children && dummy->children->content) {
-                               if (list.len != 0) {
+                               if (list.s && list.s->len != 0) {
                                        smart_str_appendc(&list, ' ');
                                }
                                smart_str_appends(&list, (char*)dummy->children->content);
@@ -3122,10 +3036,9 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP
                        }
                        xmlUnlinkNode(dummy);
                        xmlFreeNode(dummy);
-                       zend_hash_move_forward(ht);
-               }
+               } ZEND_HASH_FOREACH_END();
                smart_str_0(&list);
-               xmlNodeSetContentLen(ret, BAD_CAST(list.c), list.len);
+               xmlNodeSetContentLen(ret, BAD_CAST(list.s->val), list.s->len);
                smart_str_free(&list);
        } else {
                zval tmp = *data;
@@ -3149,10 +3062,11 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP
                          *next = '\0';
                          next++;
                        }
-                       ZVAL_STRING(&dummy_zval, start, 0);
+//???                  ZVAL_STRING(&dummy_zval, start, 0);
+                       ZVAL_STRING(&dummy_zval, start);
                        dummy = master_to_xml(list_enc, &dummy_zval, SOAP_LITERAL, ret TSRMLS_CC);
                        if (dummy && dummy->children && dummy->children->content) {
-                               if (list.len != 0) {
+                               if (list.s && list.s->len != 0) {
                                        smart_str_appendc(&list, ' ');
                                }
                                smart_str_appends(&list, (char*)dummy->children->content);
@@ -3165,7 +3079,7 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP
                        start = next;
                }
                smart_str_0(&list);
-               xmlNodeSetContentLen(ret, BAD_CAST(list.c), list.len);
+               xmlNodeSetContentLen(ret, BAD_CAST(list.s->val), list.s->len);
                smart_str_free(&list);
                efree(str);
                if (data == &tmp) {zval_dtor(&tmp);}
@@ -3178,9 +3092,9 @@ static xmlNodePtr to_xml_list1(encodeTypePtr enc, zval *data, int style, xmlNode
        return to_xml_list(enc,data,style, parent TSRMLS_CC);
 }
 
-static zval* to_zval_union(encodeTypePtr enc, xmlNodePtr data TSRMLS_DC) {
+static zval* to_zval_union(zval *ret, encodeTypePtr enc, xmlNodePtr data TSRMLS_DC) {
        /*FIXME*/
-       return to_zval_list(enc, data TSRMLS_CC);
+       return to_zval_list(ret, enc, data TSRMLS_CC);
 }
 
 static xmlNodePtr to_xml_union(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent TSRMLS_DC) {
@@ -3188,14 +3102,13 @@ static xmlNodePtr to_xml_union(encodeTypePtr enc, zval *data, int style, xmlNode
        return to_xml_list(enc,data,style, parent TSRMLS_CC);
 }
 
-static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
+static zval *to_zval_any(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
 {
        xmlBufferPtr buf;
-       zval *ret;
 
        if (SOAP_GLOBAL(sdl) && SOAP_GLOBAL(sdl)->elements && data->name) {
                smart_str nscat = {0};          
-               sdlTypePtr *sdl_type;
+               sdlTypePtr sdl_type;
 
                if (data->ns && data->ns->href) {
                        smart_str_appends(&nscat, (char*)data->ns->href);
@@ -3204,18 +3117,17 @@ static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data TSRMLS_DC)
                smart_str_appends(&nscat, (char*)data->name);
                smart_str_0(&nscat);
 
-               if (zend_hash_find(SOAP_GLOBAL(sdl)->elements, nscat.c, nscat.len+1, (void **)&sdl_type) == SUCCESS &&
-                   (*sdl_type)->encode) {
+               if ((sdl_type = zend_hash_find_ptr(SOAP_GLOBAL(sdl)->elements, nscat.s)) != NULL &&
+                   sdl_type->encode) {
                        smart_str_free(&nscat);
-                       return master_to_zval_int((*sdl_type)->encode, data TSRMLS_CC);
+                       return master_to_zval_int(ret, sdl_type->encode, data TSRMLS_CC);
                }               
                smart_str_free(&nscat);
        }
 
        buf = xmlBufferCreate();
        xmlNodeDump(buf, NULL, data, 0, 0);
-       MAKE_STD_ZVAL(ret);
-       ZVAL_STRING(ret, (char*)xmlBufferContent(buf), 1);
+       ZVAL_STRING(ret, (char*)xmlBufferContent(buf));
        xmlBufferFree(buf);
        return ret;
 }
@@ -3225,23 +3137,17 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP
        xmlNodePtr ret = NULL;
 
        if (Z_TYPE_P(data) == IS_ARRAY) {
-               HashPosition pos;
-               zval **el;
+               zval *el;
                encodePtr enc = get_conversion(XSD_ANYXML);
-               char *name;
-               uint name_len;
-               ulong idx;
-
-               for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos);
-                    zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &el, &pos) == SUCCESS;
-                    zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos)) {
-                       ret = master_to_xml(enc, *el, style, parent TSRMLS_CC);
+               zend_string *name;
+
+               ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(data), name, el) {
+                       ret = master_to_xml(enc, el, style, parent TSRMLS_CC);
                    if (ret &&
-                       ret->name != xmlStringTextNoenc &&
-                       zend_hash_get_current_key_ex(Z_ARRVAL_P(data), &name, &name_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) {
-                               xmlNodeSetName(ret, BAD_CAST(name));
+                       ret->name != xmlStringTextNoenc) {
+                               xmlNodeSetName(ret, BAD_CAST(name->val));
                    }
-               }
+               } ZEND_HASH_FOREACH_END();
                return ret;
        }
        if (Z_TYPE_P(data) == IS_STRING) {
@@ -3270,13 +3176,13 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP
        return ret;
 }
 
-zval *sdl_guess_convert_zval(encodeTypePtr enc, xmlNodePtr data TSRMLS_DC)
+zval *sdl_guess_convert_zval(zval *ret, encodeTypePtr enc, xmlNodePtr data TSRMLS_DC)
 {
        sdlTypePtr type;
 
        type = enc->sdl_type;
        if (type == NULL) {
-               return guess_zval_convert(enc, data TSRMLS_CC);
+               return guess_zval_convert(ret, enc, data TSRMLS_CC);
        }
 /*FIXME: restriction support
        if (type && type->restrictions &&
@@ -3310,27 +3216,27 @@ zval *sdl_guess_convert_zval(encodeTypePtr enc, xmlNodePtr data TSRMLS_DC)
        switch (type->kind) {
                case XSD_TYPEKIND_SIMPLE:
                        if (type->encode && enc != &type->encode->details) {
-                               return master_to_zval_int(type->encode, data TSRMLS_CC);
+                               return master_to_zval_int(ret, type->encode, data TSRMLS_CC);
                        } else {
-                               return guess_zval_convert(enc, data TSRMLS_CC);
+                               return guess_zval_convert(ret, enc, data TSRMLS_CC);
                        }
                        break;
                case XSD_TYPEKIND_LIST:
-                       return to_zval_list(enc, data TSRMLS_CC);
+                       return to_zval_list(ret, enc, data TSRMLS_CC);
                case XSD_TYPEKIND_UNION:
-                       return to_zval_union(enc, data TSRMLS_CC);
+                       return to_zval_union(ret, enc, data TSRMLS_CC);
                case XSD_TYPEKIND_COMPLEX:
                case XSD_TYPEKIND_RESTRICTION:
                case XSD_TYPEKIND_EXTENSION:
                        if (type->encode &&
                            (type->encode->details.type == IS_ARRAY ||
                             type->encode->details.type == SOAP_ENC_ARRAY)) {
-                               return to_zval_array(enc, data TSRMLS_CC);
+                               return to_zval_array(ret, enc, data TSRMLS_CC);
                        }
-                       return to_zval_object(enc, data TSRMLS_CC);
+                       return to_zval_object(ret, enc, data TSRMLS_CC);
                default:
                soap_error0(E_ERROR, "Encoding: Internal Error");
-                       return guess_zval_convert(enc, data TSRMLS_CC);
+                       return guess_zval_convert(ret, enc, data TSRMLS_CC);
        }
 }
 
@@ -3462,7 +3368,7 @@ static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type)
 {
        smart_str nstype = {0};
        get_type_str(node, ns, type, &nstype);
-       set_xsi_type(node, nstype.c);
+       set_xsi_type(node, nstype.s->val);
        smart_str_free(&nstype);
 }
 
@@ -3519,7 +3425,7 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns)
                xmlChar* prefix;
         TSRMLS_FETCH();
 
-               if (zend_hash_find(&SOAP_GLOBAL(defEncNs), (char*)ns, strlen(ns) + 1, (void **)&prefix) == SUCCESS) {
+               if ((prefix = zend_hash_str_find_ptr(&SOAP_GLOBAL(defEncNs), (char*)ns, strlen(ns))) != NULL) {
                        xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), prefix);
                } else {
                        smart_str prefix = {0};
@@ -3529,16 +3435,15 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns)
                                smart_str_appendl(&prefix, "ns", 2);
                                smart_str_append_long(&prefix, num);
                                smart_str_0(&prefix);
-                               if (xmlSearchNs(node->doc, node, BAD_CAST(prefix.c)) == NULL) {
+                               if (xmlSearchNs(node->doc, node, BAD_CAST(prefix.s->val)) == NULL) {
                                        break;
                                }
                                smart_str_free(&prefix);
-                               prefix.c = NULL;
-                               prefix.len = 0;
+                               prefix.s = NULL;
                                num = ++SOAP_GLOBAL(cur_uniq_ns);
                        }
 
-                       xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), BAD_CAST(prefix.c));
+                       xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), BAD_CAST(prefix.s ? prefix.s->val : ""));
                        smart_str_free(&prefix);
                }
        }
@@ -3587,14 +3492,14 @@ void encode_finish()
 
 encodePtr get_conversion(int encode)
 {
-       encodePtr *enc = NULL;
+       encodePtr enc;
        TSRMLS_FETCH();
 
-       if (zend_hash_index_find(&SOAP_GLOBAL(defEncIndex), encode, (void **)&enc) == FAILURE) {
+       if ((enc = zend_hash_index_find_ptr(&SOAP_GLOBAL(defEncIndex), encode)) == NULL) {
                soap_error0(E_ERROR,  "Encoding: Cannot find encoding");
                return NULL;
        } else {
-               return *enc;
+               return enc;
        }
 }
 
@@ -3604,10 +3509,10 @@ static int is_map(zval *array)
 
        zend_hash_internal_pointer_reset(Z_ARRVAL_P(array));
        for (i = 0; i < count; i++) {
-               char *str_index;
+               zend_string *_str_index;
                ulong num_index;
 
-               if (zend_hash_get_current_key(Z_ARRVAL_P(array), &str_index, &num_index, 0) == HASH_KEY_IS_STRING ||
+               if (zend_hash_get_current_key(Z_ARRVAL_P(array), &_str_index, &num_index, 0) == HASH_KEY_IS_STRING ||
                    num_index != i) {
                        return TRUE;
                }
@@ -3620,7 +3525,7 @@ static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *type TS
 {
        HashTable *ht;
        int i, count, cur_type, prev_type, different;
-       zval **tmp;
+       zval *tmp;
        char *prev_stype = NULL, *cur_stype = NULL, *prev_ns = NULL, *cur_ns = NULL;
 
        if (!array || Z_TYPE_P(array) != IS_ARRAY) {
@@ -3635,35 +3540,35 @@ static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *type TS
 
        zend_hash_internal_pointer_reset(ht);
        for (i = 0;i < count;i++) {
-               zend_hash_get_current_data(ht, (void **)&tmp);
+               tmp = zend_hash_get_current_data(ht);
 
-               if (Z_TYPE_PP(tmp) == IS_OBJECT &&
-                   Z_OBJCE_PP(tmp) == soap_var_class_entry) {
-                       zval **ztype;
+               if (Z_TYPE_P(tmp) == IS_OBJECT &&
+                   Z_OBJCE_P(tmp) == soap_var_class_entry) {
+                       zval *ztype;
 
-                       if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
+                       if ((ztype = zend_hash_str_find(Z_OBJPROP_P(tmp), "enc_type", sizeof("enc_type")-1)) == NULL) {
                                soap_error0(E_ERROR,  "Encoding: SoapVar has no 'enc_type' property");
                        }
-                       cur_type = Z_LVAL_PP(ztype);
+                       cur_type = Z_LVAL_P(ztype);
 
-                       if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_stype", sizeof("enc_stype"), (void **)&ztype) == SUCCESS) {
-                               cur_stype = Z_STRVAL_PP(ztype);
+                       if ((ztype = zend_hash_str_find(Z_OBJPROP_P(tmp), "enc_stype", sizeof("enc_stype")-1)) != NULL) {
+                               cur_stype = Z_STRVAL_P(ztype);
                        } else {
                                cur_stype = NULL;
                        }
 
-                       if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_ns", sizeof("enc_ns"), (void **)&ztype) == SUCCESS) {
-                               cur_ns = Z_STRVAL_PP(ztype);
+                       if ((ztype = zend_hash_str_find(Z_OBJPROP_P(tmp), "enc_ns", sizeof("enc_ns")-1)) != NULL) {
+                               cur_ns = Z_STRVAL_P(ztype);
                        } else {
                                cur_ns = NULL;
                        }
 
-               } else if (Z_TYPE_PP(tmp) == IS_ARRAY && is_map(*tmp)) {
+               } else if (Z_TYPE_P(tmp) == IS_ARRAY && is_map(tmp)) {
                        cur_type = APACHE_MAP;
                        cur_stype = NULL;
                        cur_ns = NULL;
                } else {
-                       cur_type = Z_TYPE_PP(tmp);
+                       cur_type = Z_TYPE_P(tmp);
                        cur_stype = NULL;
                        cur_ns = NULL;
                }
@@ -3707,7 +3612,7 @@ static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *type TS
                        smart_str_appends(&array_type, cur_stype);
                        smart_str_0(&array_type);
 
-                       enc = get_encoder_ex(SOAP_GLOBAL(sdl), array_type.c, array_type.len);
+                       enc = get_encoder_ex(SOAP_GLOBAL(sdl), array_type.s->val, array_type.s->len);
                        smart_str_free(&array_type);
                        return enc;
                } else {
@@ -3743,18 +3648,14 @@ static void delete_mapping(void *data)
 {
        soapMappingPtr map = (soapMappingPtr)data;
 
-       if (map->to_xml) {
-               zval_ptr_dtor(&map->to_xml);
-       }
-       if (map->to_zval) {
-               zval_ptr_dtor(&map->to_zval);
-       }
+       zval_ptr_dtor(&map->to_xml);
+       zval_ptr_dtor(&map->to_zval);
        efree(map);
 }
 
-void delete_encoder(void *encode)
+void delete_encoder(zval *zv)
 {
-       encodePtr t = *((encodePtr*)encode);
+       encodePtr t = Z_PTR_P(zv);
        if (t->details.ns) {
                efree(t->details.ns);
        }
@@ -3767,9 +3668,9 @@ void delete_encoder(void *encode)
        efree(t);
 }
 
-void delete_encoder_persistent(void *encode)
+void delete_encoder_persistent(zval *zv)
 {
-       encodePtr t = *((encodePtr*)encode);
+       encodePtr t = Z_PTR_P(zv);
        if (t->details.ns) {
                free(t->details.ns);
        }
index 5a8186ff7471e1406a43994b270682329105d509..adcccd3612ae6c5db88652a847cc7e4022b348a3 100644 (file)
@@ -183,23 +183,23 @@ struct _encodeType {
 
 struct _encode {
        encodeType details;
-       zval *(*to_zval)(encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
+       zval *(*to_zval)(zval *ret, encodeTypePtr type, xmlNodePtr data TSRMLS_DC);
        xmlNodePtr (*to_xml)(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
 };
 
 /* Master functions all encode/decode should be called thur these functions */
 xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
-zval *master_to_zval(encodePtr encode, xmlNodePtr data TSRMLS_DC);
+zval *master_to_zval(zval *ret, encodePtr encode, xmlNodePtr data TSRMLS_DC);
 
 /* user defined mapping */
 xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr parent TSRMLS_DC);
-zval *to_zval_user(encodeTypePtr type, xmlNodePtr node TSRMLS_DC);
+zval *to_zval_user(zval *ret, encodeTypePtr type, xmlNodePtr node TSRMLS_DC);
 
 void whiteSpace_replace(xmlChar* str);
 void whiteSpace_collapse(xmlChar* str);
 
 xmlNodePtr sdl_guess_convert_xml(encodeTypePtr enc, zval* data, int style, xmlNodePtr parent TSRMLS_DC);
-zval *sdl_guess_convert_zval(encodeTypePtr enc, xmlNodePtr data TSRMLS_DC);
+zval *sdl_guess_convert_zval(zval *ret, encodeTypePtr enc, xmlNodePtr data TSRMLS_DC);
 
 void encode_finish();
 void encode_reset_ns();
@@ -207,8 +207,8 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns);
 
 encodePtr get_conversion(int encode);
 
-void delete_encoder(void *handle);
-void delete_encoder_persistent(void *handle);
+void delete_encoder(zval *zv);
+void delete_encoder_persistent(zval *zv);
 
 extern encode defaultEncoding[];
 extern int numDefaultEncodings;
index f3abe680c9cfc611b27157e2644c8eeb95382a13..a9eb2ae719ae56b6711b707d5f1c6944cb6e9026 100644 (file)
@@ -34,24 +34,23 @@ static int get_http_headers(php_stream *socketd,char **response, int *out_size T
 /* Proxy HTTP Authentication */
 int proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
 {
-       zval **login, **password;
+       zval *login, *password;
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login"), (void **)&login) == SUCCESS) {
-               unsigned char* buf;
-               int len;
+       if ((login = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login")-1)) != NULL) {
+               zend_string *buf;
                smart_str auth = {0};
 
-               smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+               smart_str_appendl(&auth, Z_STRVAL_P(login), Z_STRLEN_P(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 ((password = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_proxy_password", sizeof("_proxy_password")-1)) != NULL) {
+                       smart_str_appendl(&auth, Z_STRVAL_P(password), Z_STRLEN_P(password));
                }
                smart_str_0(&auth);
-               buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
+               buf = php_base64_encode((unsigned char*)auth.s->val, auth.s->len);
                smart_str_append_const(soap_headers, "Proxy-Authorization: Basic ");
-               smart_str_appendl(soap_headers, (char*)buflen);
+               smart_str_appendl(soap_headers, (char*)buf->val, buf->len);
                smart_str_append_const(soap_headers, "\r\n");
-               efree(buf);
+               STR_RELEASE(buf);
                smart_str_free(&auth);
                return 1;
        }
@@ -61,25 +60,24 @@ int proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
 /* HTTP Authentication */
 int basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
 {
-       zval **login, **password;
+       zval *login, *password;
 
-       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"))) {
-               unsigned char* buf;
-               int len;
+       if ((login = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login")-1)) != NULL &&
+                       !zend_hash_str_exists(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest")-1)) {
+               zend_string* buf;
                smart_str auth = {0};
 
-               smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+               smart_str_appendl(&auth, Z_STRVAL_P(login), Z_STRLEN_P(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 ((password = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password")-1)) != NULL) {
+                       smart_str_appendl(&auth, Z_STRVAL_P(password), Z_STRLEN_P(password));
                }
                smart_str_0(&auth);
-               buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
+               buf = php_base64_encode((unsigned char*)auth.s->val, auth.s->len);
                smart_str_append_const(soap_headers, "Authorization: Basic ");
-               smart_str_appendl(soap_headers, (char*)buflen);
+               smart_str_appendl(soap_headers, (char*)buf->val, buf->len);
                smart_str_append_const(soap_headers, "\r\n");
-               efree(buf);
+               STR_RELEASE(buf);
                smart_str_free(&auth);
                return 1;
        }
@@ -93,12 +91,12 @@ void http_context_headers(php_stream_context* context,
                           zend_bool has_cookies,
                           smart_str* soap_headers TSRMLS_DC)
 {
-       zval **tmp;
+       zval *tmp;
 
        if (context &&
-               php_stream_context_get_option(context, "http", "header", &tmp) == SUCCESS &&
-               Z_TYPE_PP(tmp) == IS_STRING && Z_STRLEN_PP(tmp)) {
-               char *s = Z_STRVAL_PP(tmp);
+               (tmp = php_stream_context_get_option(context, "http", "header")) != NULL &&
+               Z_TYPE_P(tmp) == IS_STRING && Z_STRLEN_P(tmp)) {
+               char *s = Z_STRVAL_P(tmp);
                char *p;
                int name_len;
 
@@ -159,7 +157,7 @@ void http_context_headers(php_stream_context* context,
 static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, php_stream_context *context, int *use_proxy TSRMLS_DC)
 {
        php_stream *stream;
-       zval **proxy_host, **proxy_port, **tmp;
+       zval *proxy_host, *proxy_port, *tmp;
        char *host;
        char *name;
        char *protocol;
@@ -169,20 +167,20 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
        struct timeval tv;
        struct timeval *timeout = NULL;
 
-       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);
+       if ((proxy_host = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host")-1)) != NULL &&
+           Z_TYPE_P(proxy_host) == IS_STRING &&
+           (proxy_port = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port")-1)) != NULL &&
+           Z_TYPE_P(proxy_port) == IS_LONG) {
+               host = Z_STRVAL_P(proxy_host);
+               port = Z_LVAL_P(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);
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_connection_timeout", sizeof("_connection_timeout")-1)) != NULL &&
+           Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) > 0) {
+         tv.tv_sec = Z_LVAL_P(tmp);
          tv.tv_usec = 0;
                timeout = &tv;
        }
@@ -192,10 +190,10 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
 
        /* Changed ternary operator to an if/else so that additional comparisons can be done on the ssl_method property */
        if (use_ssl && !*use_proxy) {
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method"), (void **) &tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_LONG) {
+               if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_LONG) {
                        /* uses constants declared in soap.c to determine ssl uri protocol */
-                       switch (Z_LVAL_PP(tmp)) {
+                       switch (Z_LVAL_P(tmp)) {
                                case SOAP_SSL_METHOD_TLS:
                                        protocol = "tls";
                                        break;
@@ -255,7 +253,7 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
                smart_str_append_const(&soap_headers, "\r\n");
                proxy_authentication(this_ptr, &soap_headers TSRMLS_CC);
                smart_str_append_const(&soap_headers, "\r\n");
-               if (php_stream_write(stream, soap_headers.c, soap_headers.len) != soap_headers.len) {
+               if (php_stream_write(stream, soap_headers.s->val, soap_headers.s->len) != soap_headers.s->len) {
                        php_stream_close(stream);
                        stream = NULL;
                }
@@ -275,9 +273,9 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
                        /* if a stream is created without encryption, check to see if SSL method parameter is specified and use
                           proper encrypyion method based on constants defined in soap.c */
                        int crypto_method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
-                       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method"), (void **) &tmp) == SUCCESS &&
-                               Z_TYPE_PP(tmp) == IS_LONG) {
-                               switch (Z_LVAL_PP(tmp)) {
+                       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method")-1)) != NULL &&
+                               Z_TYPE_P(tmp) == IS_LONG) {
+                               switch (Z_LVAL_P(tmp)) {
                                        case SOAP_SSL_METHOD_TLS:
                                                crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
                                                break;
@@ -332,8 +330,7 @@ int make_http_soap_request(zval  *this_ptr,
                            char  *location,
                            char  *soapaction,
                            int    soap_version,
-                           char **buffer,
-                           int   *buffer_len TSRMLS_DC)
+                           zval  *return_value TSRMLS_DC)
 {
        char *request;
        smart_str soap_headers = {0};
@@ -341,7 +338,7 @@ int make_http_soap_request(zval  *this_ptr,
        int request_size, err;
        php_url *phpurl = NULL;
        php_stream *stream;
-       zval **trace, **tmp;
+       zval *trace, *tmp;
        int use_proxy = 0;
        int use_ssl;
        char *http_headers, *http_body, *content_type, *http_version, *cookie_itt;
@@ -366,41 +363,37 @@ int make_http_soap_request(zval  *this_ptr,
   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 ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "compression", sizeof("compression")-1)) != NULL && Z_TYPE_P(tmp) == IS_LONG) {
+               int level = Z_LVAL_P(tmp) & 0x0f;
+               int kind  = Z_LVAL_P(tmp) & SOAP_COMPRESSION_DEFLATE;
 
                if (level > 9) {level = 9;}
                
-         if ((Z_LVAL_PP(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) {
+         if ((Z_LVAL_P(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) {
                        smart_str_append_const(&soap_headers_z,"Accept-Encoding: gzip, deflate\r\n");
          }
          if (level > 0) {
                        zval func;
                        zval retval;
-                       zval param1, param2, param3;
-                       zval *params[3];
+                       zval params[3];
                        int n;
 
-                       params[0] = &param1;
-                       INIT_PZVAL(params[0]);
-                       params[1] = &param2;
-                       INIT_PZVAL(params[1]);
-                       params[2] = &param3;
-                       INIT_PZVAL(params[2]);
-                       ZVAL_STRINGL(params[0], buf, buf_size, 0);
-                       ZVAL_LONG(params[1], level);
+                       //???ZVAL_STRINGL(params[0], buf, buf_size, 0);
+                       ZVAL_STRINGL(&params[0], buf, buf_size);
+                       ZVAL_LONG(&params[1], level);
            if (kind == SOAP_COMPRESSION_DEFLATE) {
                n = 2;
-                               ZVAL_STRING(&func, "gzcompress", 0);
+                               //???ZVAL_STRING(&func, "gzcompress", 0);
+                               ZVAL_STRING(&func, "gzcompress");
                                smart_str_append_const(&soap_headers_z,"Content-Encoding: deflate\r\n");
            } else {
              n = 3;
-                               ZVAL_STRING(&func, "gzencode", 0);
+                               //???ZVAL_STRING(&func, "gzencode", 0);
+                               ZVAL_STRING(&func, "gzencode");
                                smart_str_append_const(&soap_headers_z,"Content-Encoding: gzip\r\n");
-                               ZVAL_LONG(params[2], 0x1f);
+                               ZVAL_LONG(&params[2], 0x1f);
            }
-                       if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, n, params TSRMLS_CC) == SUCCESS &&
+                       if (call_user_function(CG(function_table), (zval*)NULL, &func, &retval, n, params TSRMLS_CC) == SUCCESS &&
                            Z_TYPE(retval) == IS_STRING) {
                                request = Z_STRVAL(retval);
                                request_size = Z_STRLEN(retval);
@@ -412,10 +405,10 @@ int make_http_soap_request(zval  *this_ptr,
          }
        }
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"), (void **)&tmp) == SUCCESS) {
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1)) != NULL) {
                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 ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1)) != NULL && Z_TYPE_P(tmp) == IS_LONG) {
+                       use_proxy = Z_LVAL_P(tmp);
                }
        } else {
                stream = NULL;
@@ -425,16 +418,16 @@ int make_http_soap_request(zval  *this_ptr,
                phpurl = php_url_parse(location);
        }
 
-       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 (NULL != (tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr),
+                       "_stream_context", sizeof("_stream_context")-1))) {
+               context = php_stream_context_from_zval(tmp, 0);
        }
 
        if (context && 
-               php_stream_context_get_option(context, "http", "max_redirects", &tmp) == SUCCESS) {
-               if (Z_TYPE_PP(tmp) != IS_STRING || !is_numeric_string(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &redirect_max, NULL, 1)) {
-                       if (Z_TYPE_PP(tmp) == IS_LONG)
-                               redirect_max = Z_LVAL_PP(tmp);
+               (tmp = php_stream_context_get_option(context, "http", "max_redirects")) != NULL) {
+               if (Z_TYPE_P(tmp) != IS_STRING || !is_numeric_string(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &redirect_max, NULL, 1)) {
+                       if (Z_TYPE_P(tmp) == IS_LONG)
+                               redirect_max = Z_LVAL_P(tmp);
                }
        }
 
@@ -476,7 +469,7 @@ 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 &&
+               if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl")-1)) != NULL &&
                    (orig = (php_url *) zend_fetch_resource(tmp TSRMLS_CC, -1, "httpurl", NULL, 1, le_url)) != NULL &&
                    ((use_proxy && !use_ssl) ||
                     (((use_ssl && orig->scheme != NULL && strcmp(orig->scheme, "https") == 0) ||
@@ -486,9 +479,9 @@ try_again:
                     orig->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"));
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl")-1);
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
                        stream = NULL;
                        use_proxy = 0;
     }
@@ -497,9 +490,9 @@ try_again:
        /* Check if keep-alive connection is still opened */
        if (stream != NULL && php_stream_eof(stream)) {
                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"));
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl")-1);
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
                stream = NULL;
                use_proxy = 0;
        }
@@ -508,7 +501,7 @@ try_again:
                stream = http_connect(this_ptr, phpurl, use_ssl, context, &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_resource(this_ptr, "httpsocket", stream->res);
                        add_property_long(this_ptr, "_use_proxy", use_proxy);
                } else {
                        php_url_free(phpurl);
@@ -522,16 +515,16 @@ try_again:
        PG(allow_url_fopen) = old_allow_url_fopen;
 
        if (stream) {
-               zval **cookies, **login, **password;
-         int ret = zend_list_insert(phpurl, le_url TSRMLS_CC);
+               zval *cookies, *login, *password;
+               zend_resource *ret = zend_register_resource(NULL, phpurl, le_url TSRMLS_CC);
 
                add_property_resource(this_ptr, "httpurl", ret);
                /*zend_list_addref(ret);*/
 
                if (context && 
-                   php_stream_context_get_option(context, "http", "protocol_version", &tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_DOUBLE &&
-                   Z_DVAL_PP(tmp) == 1.0) {
+                   (tmp = php_stream_context_get_option(context, "http", "protocol_version")) != NULL &&
+                   Z_TYPE_P(tmp) == IS_DOUBLE &&
+                   Z_DVAL_P(tmp) == 1.0) {
                        http_1_1 = 0;
                } else {
                        http_1_1 = 1;
@@ -570,27 +563,27 @@ try_again:
                        smart_str_append_unsigned(&soap_headers, phpurl->port);
                }
                if (!http_1_1 ||
-                       (zend_hash_find(Z_OBJPROP_P(this_ptr), "_keep_alive", sizeof("_keep_alive"), (void **)&tmp) == SUCCESS &&
-                        Z_LVAL_PP(tmp) == 0)) {
+                       ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_keep_alive", sizeof("_keep_alive")-1)) != NULL &&
+                        Z_LVAL_P(tmp) == 0)) {
                        smart_str_append_const(&soap_headers, "\r\n"
                                "Connection: close\r\n");
                } else {
                        smart_str_append_const(&soap_headers, "\r\n"
                                "Connection: Keep-Alive\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 ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                       if (Z_STRLEN_P(tmp) > 0) {
                                smart_str_append_const(&soap_headers, "User-Agent: ");
-                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                smart_str_append_const(&soap_headers, "\r\n");
                        }
                } else if (context && 
-                          php_stream_context_get_option(context, "http", "user_agent", &tmp) == SUCCESS &&
-                          Z_TYPE_PP(tmp) == IS_STRING) {
-                       if (Z_STRLEN_PP(tmp) > 0) {
+                          (tmp = php_stream_context_get_option(context, "http", "user_agent")) != NULL &&
+                          Z_TYPE_P(tmp) == IS_STRING) {
+                       if (Z_STRLEN_P(tmp) > 0) {
                                smart_str_append_const(&soap_headers, "User-Agent: ");
-                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                smart_str_append_const(&soap_headers, "\r\n");
                        }
                } else if (FG(user_agent)) {
@@ -624,13 +617,13 @@ 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 ((login = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login")-1)) != NULL &&
+                   Z_TYPE_P(login) == IS_STRING) {
+                       zval *digest;
 
                        has_authorization = 1;
-                       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"), (void **)&digest) == SUCCESS) {
-                               if (Z_TYPE_PP(digest) == IS_ARRAY) {
+                       if ((digest = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest")-1)) != NULL) {
+                               if (Z_TYPE_P(digest) == IS_ARRAY) {
                                        char          HA1[33], HA2[33], response[33], cnonce[33], nc[9];
                                        PHP_MD5_CTX   md5ctx;
                                        unsigned char hash[16];
@@ -641,39 +634,39 @@ 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)++;
-                                               snprintf(nc, sizeof(nc), "%08ld", Z_LVAL_PP(tmp));
+                                       if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nc", sizeof("nc")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_LONG) {
+                                               Z_LVAL_P(tmp)++;
+                                               snprintf(nc, sizeof(nc), "%08ld", Z_LVAL_P(tmp));
                                        } else {
-                                               add_assoc_long(*digest, "nc", 1);
+                                               add_assoc_long(digest, "nc", 1);
                                                strcpy(nc, "00000001");
                                        }
 
                                        PHP_MD5Init(&md5ctx);
-                                       PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+                                       PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(login), Z_STRLEN_P(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 ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "realm", sizeof("realm")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING) {
+                                               PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                        }
                                        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 ((password = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password")-1)) != NULL &&
+                                           Z_TYPE_P(password) == IS_STRING) {
+                                               PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(password), Z_STRLEN_P(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 ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "algorithm", sizeof("algorithm")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING &&
+                                           Z_STRLEN_P(tmp) == sizeof("md5-sess")-1 &&
+                                           stricmp(Z_STRVAL_P(tmp), "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 ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL &&
+                                                   Z_TYPE_P(tmp) == IS_STRING) {
+                                                       PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                                }
                                                PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
@@ -709,13 +702,13 @@ 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 ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING) {
+                                               PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                        }
                                        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 ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "qop", sizeof("qop")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING) {
                                                PHP_MD5Update(&md5ctx, (unsigned char*)nc, 8);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
                                                PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
@@ -729,16 +722,16 @@ try_again:
                                        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_appendl(&soap_headers, Z_STRVAL_P(login), Z_STRLEN_P(login));
+                                       if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "realm", sizeof("realm")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING) {
                                                smart_str_append_const(&soap_headers, "\", realm=\"");
-                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                        }
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) == IS_STRING) {
+                               if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING) {
                                                smart_str_append_const(&soap_headers, "\", nonce=\"");
-                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                        }
                                        smart_str_append_const(&soap_headers, "\", uri=\"");
                                        if (phpurl->path) {
@@ -754,8 +747,8 @@ 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 ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "qop", sizeof("qop")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING) {
                                        /* TODO: Support for qop="auth-int" */
                                                smart_str_append_const(&soap_headers, "\", qop=\"auth");
                                                smart_str_append_const(&soap_headers, "\", nc=\"");
@@ -765,35 +758,34 @@ 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 ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "opaque", sizeof("opaque")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) == IS_STRING) {
                                                smart_str_append_const(&soap_headers, "\", opaque=\"");
-                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                        }
-                                       if (zend_hash_find(Z_ARRVAL_PP(digest), "algorithm", sizeof("algorithm"), (void **)&tmp) == SUCCESS &&
-                                               Z_TYPE_PP(tmp) == IS_STRING) {
+                                       if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "algorithm", sizeof("algorithm")-1)) != NULL &&
+                                               Z_TYPE_P(tmp) == IS_STRING) {
                                                smart_str_append_const(&soap_headers, "\", algorithm=\"");
-                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                        }
                                        smart_str_append_const(&soap_headers, "\"\r\n");
                                }
                        } else {
-                               unsigned char* buf;
-                               int len;
+                               zend_string *buf;
 
                                smart_str auth = {0};
-                               smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+                               smart_str_appendl(&auth, Z_STRVAL_P(login), Z_STRLEN_P(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 ((password = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password")-1)) != NULL &&
+                                   Z_TYPE_P(password) == IS_STRING) {
+                                       smart_str_appendl(&auth, Z_STRVAL_P(password), Z_STRLEN_P(password));
                                }
                                smart_str_0(&auth);
-                               buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
+                               buf = php_base64_encode((unsigned char*)auth.s->val, auth.s->len);
                                smart_str_append_const(&soap_headers, "Authorization: Basic ");
-                               smart_str_appendl(&soap_headers, (char*)buflen);
+                               smart_str_appendl(&soap_headers, (char*)buf->val, buf->len);
                                smart_str_append_const(&soap_headers, "\r\n");
-                               efree(buf);
+                               STR_RELEASE(buf);
                                smart_str_free(&auth);
                        }
                }
@@ -804,40 +796,39 @@ try_again:
                }
 
                /* Send cookies along with request */
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
-                       zval **data;
-                       char *key;
-                       uint key_len;
+               if ((cookies = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1)) != NULL) {
+                       zval *data;
+                       zend_string *key;
                        int i, n;
 
                        has_cookies = 1;
-                       n = zend_hash_num_elements(Z_ARRVAL_PP(cookies));
+                       n = zend_hash_num_elements(Z_ARRVAL_P(cookies));
                        if (n > 0) {
-                               zend_hash_internal_pointer_reset(Z_ARRVAL_PP(cookies));
+                               zend_hash_internal_pointer_reset(Z_ARRVAL_P(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_key_ex(Z_ARRVAL_PP(cookies), &key, &key_len, NULL, 0, NULL);
-
-                                       if (Z_TYPE_PP(data) == IS_ARRAY) {
-                                         zval** value;
-
-                                               if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&value) == SUCCESS &&
-                                                   Z_TYPE_PP(value) == IS_STRING) {
-                                                 zval **tmp;
-                                                 if ((zend_hash_index_find(Z_ARRVAL_PP(data), 1, (void**)&tmp) == FAILURE ||
-                                                      strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_PP(tmp),Z_STRLEN_PP(tmp)) == 0) &&
-                                                     (zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == FAILURE ||
-                                                      in_domain(phpurl->host,Z_STRVAL_PP(tmp))) &&
-                                                     (use_ssl || zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) {
-                                                               smart_str_appendl(&soap_headers, key, key_len);
+                                       data = zend_hash_get_current_data(Z_ARRVAL_P(cookies));
+                                       zend_hash_get_current_key_ex(Z_ARRVAL_P(cookies), &key, NULL, 0, NULL);
+
+                                       if (Z_TYPE_P(data) == IS_ARRAY) {
+                                         zval *value;
+
+                                               if ((value = zend_hash_index_find(Z_ARRVAL_P(data), 0)) != NULL &&
+                                                   Z_TYPE_P(value) == IS_STRING) {
+                                                 zval *tmp;
+                                                 if (((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 1)) == NULL ||
+                                                      strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_P(tmp),Z_STRLEN_P(tmp)) == 0) &&
+                                                     ((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 2)) == NULL ||
+                                                      in_domain(phpurl->host,Z_STRVAL_P(tmp))) &&
+                                                     (use_ssl || (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 3)) == NULL)) {
+                                                               smart_str_appendl(&soap_headers, key->val, key->len);
                                                                smart_str_appendc(&soap_headers, '=');
-                                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(value), Z_STRLEN_PP(value));
+                                                               smart_str_appendl(&soap_headers, Z_STRVAL_P(value), Z_STRLEN_P(value));
                                                                smart_str_appendc(&soap_headers, ';');
                                                        }
                                                }
                                        }
-                                       zend_hash_move_forward(Z_ARRVAL_PP(cookies));
+                                       zend_hash_move_forward(Z_ARRVAL_P(cookies));
                                }
                                smart_str_append_const(&soap_headers, "\r\n");
                        }
@@ -847,20 +838,20 @@ try_again:
 
                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);
+               if ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL &&
+                   Z_LVAL_P(trace) > 0) {
+                       add_property_stringl(this_ptr, "__last_request_headers", soap_headers.s->val, soap_headers.s->len);
                }
                smart_str_appendl(&soap_headers, request, request_size);
                smart_str_0(&soap_headers);
 
-               err = php_stream_write(stream, soap_headers.c, soap_headers.len);
-               if (err != soap_headers.len) {
+               err = php_stream_write(stream, soap_headers.s->val, soap_headers.s->len);
+               if (err != soap_headers.s->len) {
                        if (request != buf) {efree(request);}
                        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"));
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl")-1);
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
                        add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL TSRMLS_CC);
                        smart_str_free(&soap_headers_z);
                        return FALSE;
@@ -872,10 +863,10 @@ try_again:
                return FALSE;
        }
 
-       if (!buffer) {
+       if (!return_value) {
                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"));
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
                smart_str_free(&soap_headers_z);
                return TRUE;
        }
@@ -885,15 +876,15 @@ 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"));
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
+                       zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
                        add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL TSRMLS_CC);
                        smart_str_free(&soap_headers_z);
                        return FALSE;
                }
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
-                   Z_LVAL_PP(trace) > 0) {
+               if ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL &&
+                   Z_LVAL_P(trace) > 0) {
                        add_property_stringl(this_ptr, "__last_response_headers", http_headers, http_header_size);
                }
 
@@ -940,13 +931,12 @@ try_again:
        while (cookie_itt) {
                char *end_pos, *cookie;
                char *eqpos, *sempos;
-               zval **cookies;
+               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 ((cookies = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1)) == NULL) {
+                       zval tmp_cookies;
+                       array_init(&tmp_cookies);
+                       cookies = zend_hash_str_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1, &tmp_cookies);
                }
 
                end_pos = strstr(cookie_itt,"\r\n");
@@ -957,7 +947,7 @@ try_again:
                if (eqpos != NULL && (sempos == NULL || sempos > eqpos)) {
                        smart_str name = {0};
                        int cookie_len;
-                       zval *zcookie;
+                       zval zcookie;
 
                        if (sempos != NULL) {
                                cookie_len = sempos-(eqpos+1);
@@ -968,9 +958,8 @@ try_again:
                        smart_str_appendl(&name, cookie, eqpos - cookie);
                        smart_str_0(&name);
 
-                       ALLOC_INIT_ZVAL(zcookie);
-                       array_init(zcookie);
-                       add_index_stringl(zcookie, 0, eqpos + 1, cookie_len);
+                       array_init(&zcookie);
+                       add_index_stringl(&zcookie, 0, eqpos + 1, cookie_len);
 
                        if (sempos != NULL) {
                                char *options = cookie + cookie_len+1;
@@ -979,12 +968,12 @@ try_again:
                                        sempos = strstr(options, ";");
                                        if (strstr(options,"path=") == options) {
                                                eqpos = options + sizeof("path=")-1;
-                                               add_index_stringl(zcookie, 1, eqpos, sempos?(sempos-eqpos):strlen(eqpos));
+                                               add_index_stringl(&zcookie, 1, eqpos, sempos?(sempos-eqpos):strlen(eqpos));
                                        } else if (strstr(options,"domain=") == options) {
                                                eqpos = options + sizeof("domain=")-1;
-                                               add_index_stringl(zcookie, 2, eqpos, sempos?(sempos-eqpos):strlen(eqpos));
+                                               add_index_stringl(&zcookie, 2, eqpos, sempos?(sempos-eqpos):strlen(eqpos));
                                        } else if (strstr(options,"secure") == options) {
-                                               add_index_bool(zcookie, 3, 1);
+                                               add_index_bool(&zcookie, 3, 1);
                                        }
                                        if (sempos != NULL) {
                                                options = sempos+1;
@@ -993,18 +982,19 @@ try_again:
                                        }
                                }
                        }
-                       if (!zend_hash_index_exists(Z_ARRVAL_P(zcookie), 1)) {
+                       if (!zend_hash_index_exists(Z_ARRVAL(zcookie), 1)) {
                                char *t = phpurl->path?phpurl->path:"/";
                                char *c = strrchr(t, '/');
                                if (c) {
-                                       add_index_stringl(zcookie, 1, t, c-t);
+                                       add_index_stringl(&zcookie, 1, t, c-t);
                                }
                        }
-                       if (!zend_hash_index_exists(Z_ARRVAL_P(zcookie), 2)) {
-                               add_index_string(zcookie, 2, phpurl->host);
+                       if (!zend_hash_index_exists(Z_ARRVAL(zcookie), 2)) {
+                               add_index_string(&zcookie, 2, phpurl->host);
                        }
 
-                       add_assoc_zval_ex(*cookies, name.c, name.len+1, zcookie);
+                       // TODO: avoid reallocation ???
+                       add_assoc_zval_ex(cookies, name.s->val, name.s->len, &zcookie);
                        smart_str_free(&name);
                }
 
@@ -1059,8 +1049,8 @@ try_again:
                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"));
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
                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);
@@ -1073,8 +1063,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"));
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
                stream = NULL;
        }
 
@@ -1127,20 +1117,21 @@ try_again:
                }
        } else if (http_status == 401) {
                /* Digest authentication */
-               zval **digest, **login, **password;
+               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) {
+                   ((digest = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest")-1)) == NULL ||
+                    Z_TYPE_P(digest) != IS_ARRAY) &&
+                   (login = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login")-1)) != NULL &&
+                   Z_TYPE_P(login) == IS_STRING &&
+                   (password = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password")-1)) != NULL &&
+                   Z_TYPE_P(password) == IS_STRING) {
                        char *s;
-                       zval *digest = NULL;
+                       zval digest;
 
+                       ZVAL_UNDEF(&digest);
                        s = auth + sizeof("Digest")-1;
                        while (*s != '\0') {
                                char *name, *val;
@@ -1169,19 +1160,18 @@ try_again:
                                                        ++s;
                                                }
                                        }
-                                       if (digest == NULL) {
-                                               ALLOC_INIT_ZVAL(digest);
-                                               array_init(digest);
+                                       if (Z_TYPE(digest) == IS_UNDEF) {
+                                               array_init(&digest);
                                        }
-                                       add_assoc_string(digest, name, val);
+                                       add_assoc_string(&digest, name, val);
                                }
                        }
 
-                       if (digest != NULL) {
+                       if (Z_TYPE(digest) != IS_UNDEF) {
                                php_url *new_url  = emalloc(sizeof(php_url));
 
-                               Z_DELREF_P(digest);
-                               add_property_zval_ex(this_ptr, "_digest", sizeof("_digest")digest TSRMLS_CC);
+                               Z_DELREF(digest);
+                               add_property_zval_ex(this_ptr, "_digest", sizeof("_digest")-1, &digest TSRMLS_CC);
 
                                *new_url = *phpurl;
                                if (phpurl->scheme) phpurl->scheme = estrdup(phpurl->scheme);
@@ -1239,22 +1229,21 @@ try_again:
        if (content_encoding) {
                zval func;
                zval retval;
-         zval param;
-               zval *params[1];
+               zval params[1];
 
                if ((strcmp(content_encoding,"gzip") == 0 ||
                     strcmp(content_encoding,"x-gzip") == 0) &&
-                    zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate"))) {
-                       ZVAL_STRING(&func, "gzinflate", 0);
-                       params[0] = &param;
-                       ZVAL_STRINGL(params[0], http_body+10, http_body_size-10, 0);
-                       INIT_PZVAL(params[0]);
+                    zend_hash_str_exists(EG(function_table), "gzinflate", sizeof("gzinflate")-1)) {
+                       //???ZVAL_STRING(&func, "gzinflate", 0);
+                       //???ZVAL_STRINGL(params[0], http_body+10, http_body_size-10, 0);
+                       ZVAL_STRING(&func, "gzinflate");
+                       ZVAL_STRINGL(&params[0], http_body+10, http_body_size-10);
                } else if (strcmp(content_encoding,"deflate") == 0 &&
-                          zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress"))) {
-                       ZVAL_STRING(&func, "gzuncompress", 0);
-                       params[0] = &param;
-                       ZVAL_STRINGL(params[0], http_body, http_body_size, 0);
-                       INIT_PZVAL(params[0]);
+                          zend_hash_str_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1)) {
+                       //???ZVAL_STRING(&func, "gzuncompress", 0);
+                       //???ZVAL_STRINGL(params[0], http_body, http_body_size, 0);
+                       ZVAL_STRING(&func, "gzuncompress");
+                       ZVAL_STRINGL(&params[0], http_body, http_body_size);
                } else {
                        efree(content_encoding);
                        efree(http_headers);
@@ -1265,11 +1254,10 @@ try_again:
                        add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL TSRMLS_CC);
                        return FALSE;
                }
-               if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS &&
+               if (call_user_function(CG(function_table), (zval*)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS &&
                    Z_TYPE(retval) == IS_STRING) {
                        efree(http_body);
-                       *buffer = Z_STRVAL(retval);
-                       *buffer_len = Z_STRLEN(retval);
+                       ZVAL_COPY_VALUE(return_value, &retval);
                } else {
                        efree(content_encoding);
                        efree(http_headers);
@@ -1282,8 +1270,11 @@ try_again:
                }
                efree(content_encoding);
        } else {
-               *buffer = http_body;
-               *buffer_len = http_body_size;
+               // TODO: avoid reallocation ???
+               //???*buffer = http_body;
+               //???*buffer_len = http_body_size;
+               ZVAL_STRINGL(return_value, http_body, http_body_size);
+               efree(http_body);
        }
 
        efree(http_headers);
@@ -1291,11 +1282,11 @@ try_again:
        if (http_status >= 400) {
                int error = 0;
 
-               if (*buffer_len == 0) {
+               if (Z_STRLEN_P(return_value) == 0) {
                        error = 1;
-               } else if (*buffer_len > 0) {
+               } else if (Z_STRLEN_P(return_value) > 0) {
                        if (!content_type_xml) {
-                               char *s = *buffer;
+                               char *s = Z_STRVAL_P(return_value);
 
                                while (*s != '\0' && *s < ' ') {
                                        s++;
@@ -1307,7 +1298,8 @@ try_again:
                }
 
                if (error) {
-                       efree(*buffer);
+                       zval_ptr_dtor(return_value);
+                       ZVAL_UNDEF(return_value);
                        add_soap_fault(this_ptr, "HTTP", http_msg, NULL, NULL TSRMLS_CC);
                        efree(http_msg);
                        return FALSE;
@@ -1515,8 +1507,8 @@ static int get_http_headers(php_stream *stream, char **response, int *out_size T
                smart_str_appends(&tmp_response, headerbuf);
        }
        smart_str_0(&tmp_response);
-       (*response) = tmp_response.c;
-       (*out_size) = tmp_response.len;
+       (*response) = tmp_response.s->val;
+       (*out_size) = tmp_response.s->len;
        return done;
 }
 /*
index d927daa37fbe57b24ebe2e3e7266ea8266ad8a96..3fcc053741919884a9cf0ce10eeef3079b316d01 100644 (file)
@@ -28,8 +28,7 @@ int make_http_soap_request(zval  *this_ptr,
                            char  *location, 
                            char  *soapaction, 
                            int    soap_version,
-                           char **response, 
-                           int   *response_len TSRMLS_DC);
+                           zval  *response TSRMLS_DC);
 
 int proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC);
 int basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC);
index 3f4553b16ae284591527083e045d6ba42be87d15..ce505b433399858bbcd68d8966f814a3d2bd8b22 100644 (file)
@@ -179,10 +179,12 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
        /* Check if <Body> contains <Fault> element */
        fault = get_node_ex(body->children,"Fault",envelope_ns);
        if (fault != NULL) {
-               char *faultcode = NULL, *faultstring = NULL, *faultactor = NULL;
-               zval *details = NULL;
+               char *faultcode = NULL;
+               zend_string *faultstring = NULL, *faultactor = NULL;
+               zval details;
                xmlNodePtr tmp;
 
+               ZVAL_UNDEF(&details);
                if (soap_version == SOAP_1_1) {
                        tmp = get_node(fault->children, "faultcode");
                        if (tmp != NULL && tmp->children != NULL) {
@@ -191,21 +193,21 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
 
                        tmp = get_node(fault->children, "faultstring");
                        if (tmp != NULL && tmp->children != NULL) {
-                               zval *zv = master_to_zval(get_conversion(IS_STRING), tmp TSRMLS_CC);
-                               faultstring = Z_STRVAL_P(zv);
-                               FREE_ZVAL(zv);
+                               zval zv; 
+                               master_to_zval(&zv, get_conversion(IS_STRING), tmp TSRMLS_CC);
+                               faultstring = Z_STR(zv);
                        }
 
                        tmp = get_node(fault->children, "faultactor");
                        if (tmp != NULL && tmp->children != NULL) {
-                               zval *zv = master_to_zval(get_conversion(IS_STRING), tmp TSRMLS_CC);
-                               faultactor = Z_STRVAL_P(zv);
-                               FREE_ZVAL(zv);
+                               zval zv;
+                               master_to_zval(&zv, get_conversion(IS_STRING), tmp TSRMLS_CC);
+                               faultactor = Z_STR(zv);
                        }
 
                        tmp = get_node(fault->children, "detail");
                        if (tmp != NULL) {
-                               details = master_to_zval(NULL, tmp TSRMLS_CC);
+                               master_to_zval(&details, NULL, tmp TSRMLS_CC);
                        }
                } else {
                        tmp = get_node(fault->children, "Code");
@@ -221,26 +223,26 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
                                /* TODO: lang attribute */
                                tmp = get_node(tmp->children,"Text");
                                if (tmp != NULL && tmp->children != NULL) {
-                                       zval *zv = master_to_zval(get_conversion(IS_STRING), tmp TSRMLS_CC);
-                                       faultstring = Z_STRVAL_P(zv);
-                                       FREE_ZVAL(zv);
+                                       zval zv;
+                                       master_to_zval(&zv, get_conversion(IS_STRING), tmp TSRMLS_CC);
+                                       faultstring = Z_STR(zv);
                                }
                        }
 
                        tmp = get_node(fault->children,"Detail");
                        if (tmp != NULL) {
-                               details = master_to_zval(NULL, tmp TSRMLS_CC);
+                               master_to_zval(&details, NULL, tmp TSRMLS_CC);
                        }
                }
-               add_soap_fault(this_ptr, faultcode, faultstring, faultactor, details TSRMLS_CC);
+               add_soap_fault(this_ptr, faultcode, faultstring->val, faultactor->val, &details TSRMLS_CC);
                if (faultstring) {
-                       efree(faultstring);
+                       STR_RELEASE(faultstring);
                }
                if (faultactor) {
-                       efree(faultactor);
+                       STR_RELEASE(faultactor);
                }
-               if (details) {
-                       Z_DELREF_P(details);
+               if (Z_REFCOUNTED(details)) {
+                       Z_DELREF(details);
                }
                xmlFreeDoc(response);
                return FALSE;
@@ -255,20 +257,18 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
        if (resp != NULL) {
                if (fn != NULL && fn->binding && fn->binding->bindingType == BINDING_SOAP) {
                  /* Function has WSDL description */
-                       sdlParamPtr *h_param, param = NULL;
+                       sdlParamPtr param = NULL;
                        xmlNodePtr val = NULL;
                        char *name, *ns = NULL;
-                       zval* tmp;
+                       zval tmp;
                        sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
                        int res_count;
 
                        hdrs = fnb->output.headers;
 
                        if (fn->responseParameters) {
-                         res_count = zend_hash_num_elements(fn->responseParameters);
-                               zend_hash_internal_pointer_reset(fn->responseParameters);
-                               while (zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) {
-                                       param = (*h_param);
+                               res_count = zend_hash_num_elements(fn->responseParameters);
+                               ZEND_HASH_FOREACH_PTR(fn->responseParameters, param) {
                                        if (fnb->style == SOAP_DOCUMENT) {
                                                if (param->element) {
                                                        name = param->element->name;
@@ -315,8 +315,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
 
                                        if (!val) {
                                                /* TODO: may be "nil" is not OK? */
-                                               MAKE_STD_ZVAL(tmp);
-                                               ZVAL_NULL(tmp);
+                                               ZVAL_NULL(&tmp);
 /*
                                                add_soap_fault(this_ptr, "Client", "Can't find response data", NULL, NULL TSRMLS_CC);
                                                xmlFreeDoc(response);
@@ -325,17 +324,15 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
                                        } else {
                                                /* Decoding value of parameter */
                                                if (param != NULL) {
-                                                       tmp = master_to_zval(param->encode, val TSRMLS_CC);
+                                                       master_to_zval(&tmp, param->encode, val TSRMLS_CC);
                                                } else {
-                                                       tmp = master_to_zval(NULL, val TSRMLS_CC);
+                                                       master_to_zval(&tmp, NULL, val TSRMLS_CC);
                                                }
                                        }
-                                       add_assoc_zval(return_value, param->paramName, tmp);
+                                       add_assoc_zval(return_value, param->paramName, &tmp);
 
                                        param_count++;
-
-                                       zend_hash_move_forward(fn->responseParameters);
-                               }
+                               } ZEND_HASH_FOREACH_END();
                        }
                } else {
                  /* Function has no WSDL description */
@@ -347,25 +344,24 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
                                }
                                if (val != NULL) {
                                        if (!node_is_equal_ex(val,"result",RPC_SOAP12_NAMESPACE)) {
-                                               zval *tmp;
-                                               zval **arr;
+                                               zval tmp;
+                                               zval *arr;
 
-                                               tmp = master_to_zval(NULL, val TSRMLS_CC);
+                                               master_to_zval(&tmp, NULL, val TSRMLS_CC);
                                                if (val->name) {
-                                                       if (zend_hash_find(Z_ARRVAL_P(return_value), (char*)val->name, strlen((char*)val->name)+1, (void**)&arr) == SUCCESS) {
-                                                               add_next_index_zval(*arr, tmp);
+                                                       if ((arr = zend_hash_str_find(Z_ARRVAL_P(return_value), (char*)val->name, strlen((char*)val->name))) != NULL) {
+                                                               add_next_index_zval(arr, &tmp);
                                                        } else if (val->next && get_node(val->next, (char*)val->name)) {
-                                                               zval *arr;
+                                                               zval arr;
 
-                                                               MAKE_STD_ZVAL(arr);
-                                                               array_init(arr);
-                                                               add_next_index_zval(arr, tmp);
-                                                               add_assoc_zval(return_value, (char*)val->name, arr);
+                                                               array_init(&arr);
+                                                               add_next_index_zval(&arr, &tmp);
+                                                               add_assoc_zval(return_value, (char*)val->name, &arr);
                                                        } else {
-                                                               add_assoc_zval(return_value, (char*)val->name, tmp);
+                                                               add_assoc_zval(return_value, (char*)val->name, &tmp);
                                                        }
                                                } else {
-                                                       add_next_index_zval(return_value, tmp);
+                                                       add_next_index_zval(return_value, &tmp);
                                                }
                                                ++param_count;
                                        }
@@ -383,12 +379,10 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
                        zval *tmp;
 
                        zend_hash_internal_pointer_reset(Z_ARRVAL_P(return_value));
-                       zend_hash_get_current_data(Z_ARRVAL_P(return_value), (void**)&tmp);
-                       tmp = *(zval**)tmp;
-                       Z_ADDREF_P(tmp);
+                       tmp = zend_hash_get_current_data(Z_ARRVAL_P(return_value));
+                       if (Z_REFCOUNTED_P(tmp)) Z_ADDREF_P(tmp);
                        zval_dtor(return_value);
-                       *return_value = *tmp;
-                       FREE_ZVAL(tmp);
+                       ZVAL_COPY_VALUE(return_value, tmp);
                }
        }
 
@@ -397,11 +391,11 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
                while (trav != NULL) {
                        if (trav->type == XML_ELEMENT_NODE) {
                                encodePtr enc = NULL;
-                               zval* val;
+                               zval val;
 
                                if (hdrs) {
                                        smart_str key = {0};
-                                       sdlSoapBindingFunctionHeaderPtr *hdr;
+                                       sdlSoapBindingFunctionHeaderPtr hdr;
 
                                        if (trav->ns) {
                                                smart_str_appends(&key, (char*)trav->ns->href);
@@ -409,13 +403,13 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
                                        }
                                        smart_str_appends(&key, (char*)trav->name);
                                        smart_str_0(&key);
-                                       if (zend_hash_find(hdrs, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
-                                               enc = (*hdr)->encode;
+                                       if ((hdr = zend_hash_find_ptr(hdrs, key.s)) != NULL) {
+                                               enc = hdr->encode;
                                        }
                                        smart_str_free(&key);
                                }
-                               val = master_to_zval(enc, trav TSRMLS_CC);
-                               add_assoc_zval(soap_headers, (char*)trav->name, val);
+                               master_to_zval(&val, enc, trav TSRMLS_CC);
+                               add_assoc_zval(soap_headers, (char*)trav->name, &val);
                        }
                        trav = trav->next;
                }
index 58037199d9a29dc1f196ca33348ef9a372e2dabc..4895bf787645c83c57a3e65fa47eeef866c00ad7 100644 (file)
@@ -49,7 +49,7 @@ static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type);
 static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
 {
        smart_str nscat = {0};
-       encodePtr enc, *enc_ptr;
+       encodePtr enc, enc_ptr;
 
        if (sdl->encoders == NULL) {
                sdl->encoders = emalloc(sizeof(HashTable));
@@ -59,8 +59,8 @@ static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *
        smart_str_appendc(&nscat, ':');
        smart_str_appends(&nscat, (char*)type);
        smart_str_0(&nscat);
-       if (zend_hash_find(sdl->encoders, nscat.c, nscat.len + 1, (void**)&enc_ptr) == SUCCESS) {
-               enc = *enc_ptr;
+       if ((enc_ptr = zend_hash_find_ptr(sdl->encoders, nscat.s)) != NULL) {
+               enc = enc_ptr;
                if (enc->details.ns) {
                        efree(enc->details.ns);
                }
@@ -80,7 +80,7 @@ static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *
        enc->to_zval = sdl_guess_convert_zval;
 
        if (enc_ptr == NULL) {
-               zend_hash_update(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL);
+               zend_hash_update_ptr(sdl->encoders, nscat.s, enc);
        }
        smart_str_free(&nscat);
        return enc;
@@ -97,7 +97,7 @@ static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlCh
 
 static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlAttrPtr tns, int import TSRMLS_DC) {
        if (location != NULL &&
-           !zend_hash_exists(&ctx->docs, (char*)location, xmlStrlen(location)+1)) {
+           !zend_hash_str_exists(&ctx->docs, (char*)location, xmlStrlen(location))) {
                xmlDocPtr doc;
                xmlNodePtr schema;
                xmlAttrPtr new_tns;
@@ -135,7 +135,7 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA
                                soap_error1(E_ERROR, "Parsing Schema: can't include schema from '%s', different 'targetNamespace'", location);
                        }
                }
-               zend_hash_add(&ctx->docs, (char*)location, xmlStrlen(location)+1, (void**)&doc, sizeof(xmlDocPtr), NULL);
+               zend_hash_str_add_ptr(&ctx->docs, (char*)location, xmlStrlen(location), doc);
                load_schema(ctx, schema TSRMLS_CC);
        }
 }
@@ -315,7 +315,7 @@ static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType,
        name = get_attribute(simpleType->properties, "name");
        if (cur_type != NULL) {
                /* Anonymous type inside <element> or <restriction> */
-               sdlTypePtr newType, *ptr;
+               sdlTypePtr newType, ptr;
 
                newType = emalloc(sizeof(sdlType));
                memset(newType, 0, sizeof(sdlType));
@@ -328,7 +328,7 @@ static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType,
                        newType->namens = estrdup(cur_type->namens);
                }
 
-               zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
+               ptr = zend_hash_next_index_insert_ptr(sdl->types,  newType);
 
                if (sdl->encoders == NULL) {
                        sdl->encoders = emalloc(sizeof(HashTable));
@@ -338,15 +338,15 @@ static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType,
                memset(cur_type->encode, 0, sizeof(encode));
                cur_type->encode->details.ns = estrdup(newType->namens);
                cur_type->encode->details.type_str = estrdup(newType->name);
-               cur_type->encode->details.sdl_type = *ptr;
+               cur_type->encode->details.sdl_type = ptr;
                cur_type->encode->to_xml = sdl_guess_convert_xml;
                cur_type->encode->to_zval = sdl_guess_convert_zval;
-               zend_hash_next_index_insert(sdl->encoders,  &cur_type->encode, sizeof(encodePtr), NULL);
+               zend_hash_next_index_insert_ptr(sdl->encoders,  cur_type->encode);
 
-               cur_type =*ptr;
+               cur_type =ptr;
 
        } else if (name != NULL) {
-               sdlTypePtr newType, *ptr;
+               sdlTypePtr newType, ptr;
 
                newType = emalloc(sizeof(sdlType));
                memset(newType, 0, sizeof(sdlType));
@@ -355,15 +355,15 @@ static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType,
                newType->namens = estrdup((char*)ns->children->content);
 
                if (cur_type == NULL) {
-                       zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
+                       ptr = zend_hash_next_index_insert_ptr(sdl->types, newType);
                } else {
                        if (cur_type->elements == NULL) {
                                cur_type->elements = emalloc(sizeof(HashTable));
                                zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
                        }
-                       zend_hash_update(cur_type->elements, newType->name, strlen(newType->name)+1, &newType, sizeof(sdlTypePtr), (void **)&ptr);
+                       ptr = zend_hash_str_update_ptr(cur_type->elements, newType->name, strlen(newType->name), newType);
                }
-               cur_type = (*ptr);
+               cur_type = ptr;
 
                create_encoder(sdl, cur_type, ns->children->content, name->children->content);
        } else {
@@ -421,7 +421,7 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP
                parse_namespace(itemType->children->content, &type, &ns);
                nsptr = xmlSearchNs(listType->doc, listType, BAD_CAST(ns));
                if (nsptr != NULL) {
-                       sdlTypePtr newType, *tmp;
+                       sdlTypePtr newType;
 
                        newType = emalloc(sizeof(sdlType));
                        memset(newType, 0, sizeof(sdlType));
@@ -435,7 +435,7 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP
                                cur_type->elements = emalloc(sizeof(HashTable));
                                zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
                        }
-                       zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
+                       zend_hash_next_index_insert_ptr(cur_type->elements, newType);
                }
                if (type) {efree(type);}
                if (ns) {efree(ns);}
@@ -447,7 +447,7 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP
                trav = trav->next;
        }
        if (trav != NULL && node_is_equal(trav,"simpleType")) {
-               sdlTypePtr newType, *tmp;
+               sdlTypePtr newType;
 
                if (itemType != NULL) {
                        soap_error0(E_ERROR, "Parsing Schema: element has both 'itemType' attribute and subtype");
@@ -462,7 +462,9 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP
                        smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
                        smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
                        smart_str_0(&anonymous);
-                       newType->name = anonymous.c;
+                       // TODO: avoid reallocation ???
+                       newType->name = estrndup(anonymous.s->val, anonymous.s->len);
+                       smart_str_free(&anonymous);
                }
                newType->namens = estrdup((char*)tns->children->content);
 
@@ -470,7 +472,7 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP
                        cur_type->elements = emalloc(sizeof(HashTable));
                        zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
                }
-               zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
+               zend_hash_next_index_insert_ptr(cur_type->elements, newType);
 
                schema_simpleType(sdl, tns, trav, newType);
 
@@ -516,7 +518,7 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp
                        parse_namespace(BAD_CAST(start), &type, &ns);
                        nsptr = xmlSearchNs(unionType->doc, unionType, BAD_CAST(ns));
                        if (nsptr != NULL) {
-                               sdlTypePtr newType, *tmp;
+                               sdlTypePtr newType;
 
                                newType = emalloc(sizeof(sdlType));
                                memset(newType, 0, sizeof(sdlType));
@@ -530,7 +532,7 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp
                                        cur_type->elements = emalloc(sizeof(HashTable));
                                        zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
                                }
-                               zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
+                               zend_hash_next_index_insert_ptr(cur_type->elements, newType);
                        }
                        if (type) {efree(type);}
                        if (ns) {efree(ns);}
@@ -547,7 +549,7 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp
        }
        while (trav != NULL) {
                if (node_is_equal(trav,"simpleType")) {
-                       sdlTypePtr newType, *tmp;
+                       sdlTypePtr newType;
 
                        newType = emalloc(sizeof(sdlType));
                        memset(newType, 0, sizeof(sdlType));
@@ -558,7 +560,9 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp
                                smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
                                smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
                                smart_str_0(&anonymous);
-                               newType->name = anonymous.c;
+                               // TODO: avoid reallocation ???
+                               newType->name = estrndup(anonymous.s->val, anonymous.s->len);
+                               smart_str_free(&anonymous);
                        }
                        newType->namens = estrdup((char*)tns->children->content);
 
@@ -566,7 +570,7 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp
                                cur_type->elements = emalloc(sizeof(HashTable));
                                zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
                        }
-                       zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
+                       zend_hash_next_index_insert_ptr(cur_type->elements, newType);
 
                        schema_simpleType(sdl, tns, trav, newType);
 
@@ -699,8 +703,8 @@ static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodeP
                                cur_type->restrictions->enumeration = emalloc(sizeof(HashTable));
                                zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, 0);
                        }
-                       if (zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL) == FAILURE) {
-                               delete_restriction_var_char(&enumval);
+                       if (zend_hash_str_add_ptr(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value), enumval) == NULL) {
+                               delete_restriction_var_char_int(enumval);
                        }
                } else {
                        break;
@@ -1022,7 +1026,7 @@ static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr all, sdlTypePtr cur
        if (model == NULL) {
                cur_type->model = newModel;
        } else {
-               zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
+               zend_hash_next_index_insert_ptr(model->u.content, newModel);
        }
 
        schema_min_max(all, newModel);
@@ -1096,7 +1100,7 @@ static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTyp
 
                        newModel = emalloc(sizeof(sdlContentModel));
                        newModel->kind = XSD_CONTENT_GROUP_REF;
-                       newModel->u.group_ref = estrdup(key.c);
+                       newModel->u.group_ref = estrndup(key.s->val, key.s->len);
 
                        if (type) {efree(type);}
                        if (ns) {efree(ns);}
@@ -1122,8 +1126,8 @@ static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTyp
                                sdl->groups = emalloc(sizeof(HashTable));
                                zend_hash_init(sdl->groups, 0, NULL, delete_type, 0);
                        }
-                       if (zend_hash_add(sdl->groups, key.c, key.len+1, (void**)&newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
-                               soap_error1(E_ERROR, "Parsing Schema: group '%s' already defined", key.c);
+                       if (zend_hash_add_ptr(sdl->groups, key.s, newType) == NULL) {
+                               soap_error1(E_ERROR, "Parsing Schema: group '%s' already defined", key.s->val);
                        }
 
                        cur_type = newType;
@@ -1133,7 +1137,7 @@ static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTyp
                if (model == NULL) {
                        cur_type->model = newModel;
                } else {
-                       zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
+                       zend_hash_next_index_insert_ptr(model->u.content, newModel);
                }
        } else {
                soap_error0(E_ERROR, "Parsing Schema: group has no 'name' nor 'ref' attributes");
@@ -1198,7 +1202,7 @@ static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlT
        if (model == NULL) {
                cur_type->model = newModel;
        } else {
-               zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
+               zend_hash_next_index_insert_ptr(model->u.content, newModel);
        }
 
        schema_min_max(choiceType, newModel);
@@ -1248,7 +1252,7 @@ static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTy
        if (model == NULL) {
                cur_type->model = newModel;
        } else {
-               zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
+               zend_hash_next_index_insert_ptr(model->u.content, newModel);
        }
 
        schema_min_max(seqType, newModel);
@@ -1298,7 +1302,7 @@ static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr anyType, sdlTypePtr
 
                schema_min_max(anyType, newModel);
 
-               zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
+               zend_hash_next_index_insert_ptr(model->u.content, newModel);
        }
        return TRUE;
 }
@@ -1368,7 +1372,7 @@ static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, s
        name = get_attribute(attrs, "name");
        if (cur_type != NULL) {
                /* Anonymous type inside <element> */
-               sdlTypePtr newType, *ptr;
+               sdlTypePtr newType, ptr;
 
                newType = emalloc(sizeof(sdlType));
                memset(newType, 0, sizeof(sdlType));
@@ -1381,7 +1385,7 @@ static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, s
                        newType->namens = estrdup(cur_type->namens);
                }
 
-               zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
+               ptr = zend_hash_next_index_insert_ptr(sdl->types, newType);
 
                if (sdl->encoders == NULL) {
                        sdl->encoders = emalloc(sizeof(HashTable));
@@ -1391,15 +1395,15 @@ static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, s
                memset(cur_type->encode, 0, sizeof(encode));
                cur_type->encode->details.ns = estrdup(newType->namens);
                cur_type->encode->details.type_str = estrdup(newType->name);
-               cur_type->encode->details.sdl_type = *ptr;
+               cur_type->encode->details.sdl_type = ptr;
                cur_type->encode->to_xml = sdl_guess_convert_xml;
                cur_type->encode->to_zval = sdl_guess_convert_zval;
-               zend_hash_next_index_insert(sdl->encoders,  &cur_type->encode, sizeof(encodePtr), NULL);
+               zend_hash_next_index_insert_ptr(sdl->encoders, cur_type->encode);
 
-               cur_type =*ptr;
+               cur_type = ptr;
 
        } else if (name) {
-               sdlTypePtr newType, *ptr;
+               sdlTypePtr newType, ptr;
 
                newType = emalloc(sizeof(sdlType));
                memset(newType, 0, sizeof(sdlType));
@@ -1407,9 +1411,9 @@ static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, s
                newType->name = estrdup((char*)name->children->content);
                newType->namens = estrdup((char*)ns->children->content);
 
-               zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
+               ptr = zend_hash_next_index_insert_ptr(sdl->types, newType);
 
-               cur_type = (*ptr);
+               cur_type = ptr;
                create_encoder(sdl, cur_type, ns->children->content, name->children->content);
        } else {
                soap_error0(E_ERROR, "Parsing Schema: complexType has no 'name' attribute");
@@ -1532,7 +1536,7 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp
                        smart_str_0(&nscat);
                        if (type) {efree(type);}
                        if (ns) {efree(ns);}
-                       newType->ref = estrdup(nscat.c);
+                       newType->ref = estrndup(nscat.s->val, nscat.s->len);
                        smart_str_free(&nscat);
                } else {
                        newType->name = estrdup((char*)name->children->content);
@@ -1560,11 +1564,11 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp
                }
 
                smart_str_0(&key);
-               if (zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
+               if (zend_hash_add_ptr(addHash, key.s, newType) == NULL) {
                        if (cur_type == NULL) {
-                               soap_error1(E_ERROR, "Parsing Schema: element '%s' already defined", key.c);
+                               soap_error1(E_ERROR, "Parsing Schema: element '%s' already defined", key.s->val);
                        } else {
-                               zend_hash_next_index_insert(addHash, &newType, sizeof(sdlTypePtr), NULL);
+                               zend_hash_next_index_insert_ptr(addHash, newType);
                        }
                }
                smart_str_free(&key);
@@ -1578,7 +1582,7 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp
                        schema_min_max(element, newModel);
 
 
-                       zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
+                       zend_hash_next_index_insert_ptr(model->u.content, newModel);
                }
                cur_type = newType;
        } else {
@@ -1763,7 +1767,7 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl
                        smart_str_appendc(&key, ':');
                        smart_str_appends(&key, attr_name);
                        smart_str_0(&key);
-                       newAttr->ref = estrdup(key.c);
+                       newAttr->ref = estrndup(key.s->val, key.s->len);
                        if (attr_name) {efree(attr_name);}
                        if (ns) {efree(ns);}
                } else {
@@ -1792,8 +1796,8 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl
                        addHash = cur_type->attributes;
                }
 
-               if (zend_hash_add(addHash, key.c, key.len + 1, &newAttr, sizeof(sdlAttributePtr), NULL) != SUCCESS) {
-                       soap_error1(E_ERROR, "Parsing Schema: attribute '%s' already defined", key.c);
+               if (zend_hash_add_ptr(addHash, key.s, newAttr) == NULL) {
+                       soap_error1(E_ERROR, "Parsing Schema: attribute '%s' already defined", key.s->val);
                }
                smart_str_free(&key);
        } else{
@@ -1881,7 +1885,7 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl
                                smart_str_appendc(&key2, ':');
                                smart_str_appends(&key2, (char*)attr->name);
                                smart_str_0(&key2);
-                               zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &ext, sizeof(sdlExtraAttributePtr), NULL);
+                               zend_hash_add_ptr(newAttr->extraAttributes, key2.s, ext);
                                smart_str_free(&key2);
                        }
                }
@@ -1914,6 +1918,8 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl
        if (trav != NULL) {
                if (node_is_equal(trav,"simpleType")) {
                        sdlTypePtr dummy_type;
+                       zval zv;
+
                        if (ref != NULL) {
                                soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' attribute and subtype");
                        } else if (type != NULL) {
@@ -1927,12 +1933,15 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl
                                smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
                                smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
                                smart_str_0(&anonymous);
-                               dummy_type->name = anonymous.c;
+                               // TODO: avoid reallocation ???
+                               dummy_type->name = estrndup(anonymous.s->val, anonymous.s->len);
+                               smart_str_free(&anonymous);
                        }
                        dummy_type->namens = estrdup((char*)tns->children->content);
                        schema_simpleType(sdl, tns, trav, dummy_type);
                        newAttr->encode = dummy_type->encode;
-                       delete_type(&dummy_type);
+                       ZVAL_PTR(&zv, dummy_type);
+                       delete_type(&zv);
                        trav = trav->next;
                }
        }
@@ -1972,8 +1981,8 @@ static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGrou
                        smart_str_appends(&key, newType->name);
                        smart_str_0(&key);
 
-                       if (zend_hash_add(ctx->attributeGroups, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
-                               soap_error1(E_ERROR, "Parsing Schema: attributeGroup '%s' already defined", key.c);
+                       if (zend_hash_add_ptr(ctx->attributeGroups, key.s, newType) == NULL) {
+                               soap_error1(E_ERROR, "Parsing Schema: attributeGroup '%s' already defined", key.s->val);
                        }
                        cur_type = newType;
                        smart_str_free(&key);
@@ -1998,12 +2007,12 @@ static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGrou
                        smart_str_appendc(&key, ':');
                        smart_str_appends(&key, group_name);
                        smart_str_0(&key);
-                       newAttr->ref = estrdup(key.c);
+                       newAttr->ref = estrndup(key.s->val, key.s->len);
                        if (group_name) {efree(group_name);}
                        if (ns) {efree(ns);}
                        smart_str_free(&key);
 
-                       zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
+                       zend_hash_next_index_insert_ptr(cur_type->attributes, newAttr);
                        cur_type = NULL;
                }
        } else{
@@ -2044,14 +2053,13 @@ static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGrou
        return TRUE;
 }
 
-static void copy_extra_attribute(void *attribute)
+static void copy_extra_attribute(zval *zv)
 {
-       sdlExtraAttributePtr *attr = (sdlExtraAttributePtr*)attribute;
        sdlExtraAttributePtr new_attr;
 
        new_attr = emalloc(sizeof(sdlExtraAttribute));
-       memcpy(new_attr, *attr, sizeof(sdlExtraAttribute));
-       *attr = new_attr;
+       memcpy(new_attr, Z_PTR_P(zv), sizeof(sdlExtraAttribute));
+       Z_PTR_P(zv) = new_attr;
        if (new_attr->ns) {
                new_attr->ns = estrdup(new_attr->ns);
        }
@@ -2062,14 +2070,14 @@ static void copy_extra_attribute(void *attribute)
 
 static void* schema_find_by_ref(HashTable *ht, char *ref)
 {
-       void **tmp;
+       void *tmp;
 
-       if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
+       if ((tmp = zend_hash_str_find_ptr(ht, ref, strlen(ref))) != NULL) {
                return tmp;
        } else {
                ref = strrchr(ref, ':');
                if (ref) {
-                       if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
+                       if ((tmp = zend_hash_str_find_ptr(ht, ref, strlen(ref))) != NULL) {
                                return tmp;
                        }
                }
@@ -2079,39 +2087,37 @@ static void* schema_find_by_ref(HashTable *ht, char *ref)
 
 static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
 {
-       sdlAttributePtr *tmp;
+       sdlAttributePtr tmp;
 
        if (attr->ref != NULL) {
                if (ctx->attributes != NULL) {
-                       tmp = (sdlAttributePtr*)schema_find_by_ref(ctx->attributes, attr->ref);
+                       tmp = (sdlAttributePtr)schema_find_by_ref(ctx->attributes, attr->ref);
                        if (tmp) {
-                               schema_attribute_fixup(ctx, *tmp);
-                               if ((*tmp)->name != NULL && attr->name == NULL) {
-                                       attr->name = estrdup((*tmp)->name);
+                               schema_attribute_fixup(ctx, tmp);
+                               if (tmp->name != NULL && attr->name == NULL) {
+                                       attr->name = estrdup(tmp->name);
                                }
-                               if ((*tmp)->namens != NULL && attr->namens == NULL) {
-                                       attr->namens = estrdup((*tmp)->namens);
+                               if (tmp->namens != NULL && attr->namens == NULL) {
+                                       attr->namens = estrdup(tmp->namens);
                                }
-                               if ((*tmp)->def != NULL && attr->def == NULL) {
-                                       attr->def = estrdup((*tmp)->def);
+                               if (tmp->def != NULL && attr->def == NULL) {
+                                       attr->def = estrdup(tmp->def);
                                }
-                               if ((*tmp)->fixed != NULL && attr->fixed == NULL) {
-                                       attr->fixed = estrdup((*tmp)->fixed);
+                               if (tmp->fixed != NULL && attr->fixed == NULL) {
+                                       attr->fixed = estrdup(tmp->fixed);
                                }
                                if (attr->form == XSD_FORM_DEFAULT) {
-                                       attr->form = (*tmp)->form;
+                                       attr->form = tmp->form;
                                }
                                if (attr->use == XSD_USE_DEFAULT) {
-                                       attr->use  = (*tmp)->use;
+                                       attr->use  = tmp->use;
                                }
-                               if ((*tmp)->extraAttributes != NULL) {
-                                 xmlNodePtr node;
-
+                               if (tmp->extraAttributes != NULL) {
                                        attr->extraAttributes = emalloc(sizeof(HashTable));
-                                       zend_hash_init(attr->extraAttributes, zend_hash_num_elements((*tmp)->extraAttributes), NULL, delete_extra_attribute, 0);
-                                       zend_hash_copy(attr->extraAttributes, (*tmp)->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
+                                       zend_hash_init(attr->extraAttributes, zend_hash_num_elements(tmp->extraAttributes), NULL, delete_extra_attribute, 0);
+                                       zend_hash_copy(attr->extraAttributes, tmp->extraAttributes, copy_extra_attribute);
                                }
-                               attr->encode = (*tmp)->encode;
+                               attr->encode = tmp->encode;
                        }
                }
                if (attr->name == NULL && attr->ref != NULL) {
@@ -2129,47 +2135,45 @@ static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
 
 static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashTable *ht)
 {
-       sdlTypePtr *tmp;
-       sdlAttributePtr *tmp_attr;
+       sdlTypePtr tmp;
+       sdlAttributePtr tmp_attr;
 
        if (attr->ref != NULL) {
                if (ctx->attributeGroups != NULL) {
-                       tmp = (sdlTypePtr*)schema_find_by_ref(ctx->attributeGroups, attr->ref);
+                       tmp = (sdlTypePtr)schema_find_by_ref(ctx->attributeGroups, attr->ref);
                        if (tmp) {
-                               if ((*tmp)->attributes) {
-                                       zend_hash_internal_pointer_reset((*tmp)->attributes);
-                                       while (zend_hash_get_current_data((*tmp)->attributes,(void**)&tmp_attr) == SUCCESS) {
-                                               if (zend_hash_get_current_key_type((*tmp)->attributes) == HASH_KEY_IS_STRING) {
-                                                       char* key;
-                                                       uint key_len;
+                               if (tmp->attributes) {
+                                       zend_hash_internal_pointer_reset(tmp->attributes);
+                                       while ((tmp_attr = zend_hash_get_current_data_ptr(tmp->attributes)) != NULL) {
+                                               if (zend_hash_get_current_key_type(tmp->attributes) == HASH_KEY_IS_STRING) {
+                                                       zend_string* _key;
                                                        sdlAttributePtr newAttr;
 
-                                                       schema_attribute_fixup(ctx,*tmp_attr);
+                                                       schema_attribute_fixup(ctx, tmp_attr);
 
                                                        newAttr = emalloc(sizeof(sdlAttribute));
-                                                       memcpy(newAttr, *tmp_attr, sizeof(sdlAttribute));
+                                                       memcpy(newAttr, tmp_attr, sizeof(sdlAttribute));
                                                        if (newAttr->def) {newAttr->def = estrdup(newAttr->def);}
                                                        if (newAttr->fixed) {newAttr->fixed = estrdup(newAttr->fixed);}
                                                        if (newAttr->namens) {newAttr->namens = estrdup(newAttr->namens);}
                                                        if (newAttr->name) {newAttr->name = estrdup(newAttr->name);}
                                                        if (newAttr->extraAttributes) {
-                                                         xmlNodePtr node;
                                                                HashTable *ht = emalloc(sizeof(HashTable));
                                                                zend_hash_init(ht, zend_hash_num_elements(newAttr->extraAttributes), NULL, delete_extra_attribute, 0);
-                                                               zend_hash_copy(ht, newAttr->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
+                                                               zend_hash_copy(ht, newAttr->extraAttributes, copy_extra_attribute);
                                                                newAttr->extraAttributes = ht;
                                                        }
 
-                                                       zend_hash_get_current_key_ex((*tmp)->attributes, &key, &key_len, NULL, 0, NULL);
-                                                       zend_hash_add(ht, key, key_len, &newAttr, sizeof(sdlAttributePtr), NULL);
+                                                       zend_hash_get_current_key_ex(tmp->attributes, &_key, NULL, 0, &tmp->attributes->nInternalPointer);
+                                                       zend_hash_add_ptr(ht, _key, &newAttr);
 
-                                                       zend_hash_move_forward((*tmp)->attributes);
+                                                       zend_hash_move_forward(tmp->attributes);
                                                } else {
                                                        ulong index;
 
-                                                       schema_attributegroup_fixup(ctx,*tmp_attr, ht);
-                                                       zend_hash_get_current_key((*tmp)->attributes, NULL, &index, 0);
-                                                       zend_hash_index_del((*tmp)->attributes, index);
+                                                       schema_attributegroup_fixup(ctx, tmp_attr, ht);
+                                                       zend_hash_get_current_key(tmp->attributes, NULL, &index, 0);
+                                                       zend_hash_index_del(tmp->attributes, index);
                                                }
                                        }
                                }
@@ -2184,13 +2188,13 @@ static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
 {
        switch (model->kind) {
                case XSD_CONTENT_GROUP_REF: {
-                       sdlTypePtr *tmp;
+                       sdlTypePtr tmp;
 
-                       if (ctx->sdl->groups && zend_hash_find(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref)+1, (void**)&tmp) == SUCCESS) {
-                               schema_type_fixup(ctx,*tmp);
+                       if (ctx->sdl->groups && (tmp = zend_hash_str_find_ptr(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref))) != NULL) {
+                               schema_type_fixup(ctx, tmp);
                                efree(model->u.group_ref);
                                model->kind = XSD_CONTENT_GROUP;
-                               model->u.group = (*tmp);
+                               model->u.group = tmp;
                        } else {
                                soap_error1(E_ERROR, "Parsing Schema: unresolved group 'ref' attribute '%s'", model->u.group_ref);
                        }
@@ -2198,15 +2202,12 @@ static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
                }
                case XSD_CONTENT_CHOICE: {
                        if (model->max_occurs != 1) {
-                               HashPosition pos;
-                               sdlContentModelPtr *tmp;
-
-                               zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
-                               while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
-                                       (*tmp)->min_occurs = 0;
-                                       (*tmp)->max_occurs = model->max_occurs;
-                                       zend_hash_move_forward_ex(model->u.content, &pos);
-                               }
+                               sdlContentModelPtr tmp;
+
+                               ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                                       tmp->min_occurs = 0;
+                                       tmp->max_occurs = model->max_occurs;
+                               } ZEND_HASH_FOREACH_END();
 
                                model->kind = XSD_CONTENT_ALL;
                                model->min_occurs = 1;
@@ -2215,13 +2216,11 @@ static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
                }
                case XSD_CONTENT_SEQUENCE:
                case XSD_CONTENT_ALL: {
-                       sdlContentModelPtr *tmp;
+                       sdlContentModelPtr tmp;
 
-                       zend_hash_internal_pointer_reset(model->u.content);
-                       while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
-                               schema_content_model_fixup(ctx, *tmp);
-                               zend_hash_move_forward(model->u.content);
-                       }
+                       ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                               schema_content_model_fixup(ctx, tmp);
+                       } ZEND_HASH_FOREACH_END();
                        break;
                }
                default:
@@ -2231,25 +2230,25 @@ static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
 
 static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
 {
-       sdlTypePtr *tmp;
-       sdlAttributePtr *attr;
+       sdlTypePtr tmp;
+       sdlAttributePtr attr;
 
        if (type->ref != NULL) {
                if (ctx->sdl->elements != NULL) {
-                       tmp = (sdlTypePtr*)schema_find_by_ref(ctx->sdl->elements, type->ref);
+                       tmp = (sdlTypePtr)schema_find_by_ref(ctx->sdl->elements, type->ref);
                        if (tmp) {
-                               type->kind = (*tmp)->kind;
-                               type->encode = (*tmp)->encode;
-                               if ((*tmp)->nillable) {
+                               type->kind = tmp->kind;
+                               type->encode = tmp->encode;
+                               if (tmp->nillable) {
                                  type->nillable = 1;
                                }
-                               if ((*tmp)->fixed) {
-                                 type->fixed = estrdup((*tmp)->fixed);
+                               if (tmp->fixed) {
+                                 type->fixed = estrdup(tmp->fixed);
                                }
-                               if ((*tmp)->def) {
-                                 type->def = estrdup((*tmp)->def);
+                               if (tmp->def) {
+                                 type->def = estrdup(tmp->def);
                                }
-                               type->form = (*tmp)->form;
+                               type->form = tmp->form;
                        } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) {
                                type->encode = get_conversion(XSD_ANYXML);
                        } else {
@@ -2260,72 +2259,59 @@ static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
                type->ref = NULL;
        }
        if (type->elements) {
-               zend_hash_internal_pointer_reset(type->elements);
-               while (zend_hash_get_current_data(type->elements,(void**)&tmp) == SUCCESS) {
-                       schema_type_fixup(ctx,*tmp);
-                       zend_hash_move_forward(type->elements);
-               }
+               ZEND_HASH_FOREACH_PTR(type->elements, tmp) {
+                       schema_type_fixup(ctx, tmp);
+               } ZEND_HASH_FOREACH_END();
        }
        if (type->model) {
                schema_content_model_fixup(ctx, type->model);
        }
        if (type->attributes) {
-               zend_hash_internal_pointer_reset(type->attributes);
-               while (zend_hash_get_current_data(type->attributes,(void**)&attr) == SUCCESS) {
-                       if (zend_hash_get_current_key_type(type->attributes) == HASH_KEY_IS_STRING) {
-                               schema_attribute_fixup(ctx,*attr);
+               zend_string *str_key;
+               ulong index;
+
+               ZEND_HASH_FOREACH_KEY_PTR(type->attributes, index, str_key, attr) {
+                       if (str_key) {
+                               schema_attribute_fixup(ctx, attr);
                                zend_hash_move_forward(type->attributes);
                        } else {
-                               ulong index;
-
-                               schema_attributegroup_fixup(ctx,*attr,type->attributes);
-                               zend_hash_get_current_key(type->attributes, NULL, &index, 0);
+                               schema_attributegroup_fixup(ctx, attr, type->attributes);
                                zend_hash_index_del(type->attributes, index);
                        }
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 }
 
 void schema_pass2(sdlCtx *ctx)
 {
        sdlPtr sdl = ctx->sdl;
-       sdlAttributePtr *attr;
-       sdlTypePtr *type;
+       sdlAttributePtr attr;
+       sdlTypePtr type;
 
        if (ctx->attributes) {
-               zend_hash_internal_pointer_reset(ctx->attributes);
-               while (zend_hash_get_current_data(ctx->attributes,(void**)&attr) == SUCCESS) {
-                       schema_attribute_fixup(ctx,*attr);
-                       zend_hash_move_forward(ctx->attributes);
-               }
+               ZEND_HASH_FOREACH_PTR(ctx->attributes, attr) {
+                       schema_attribute_fixup(ctx, attr);
+               } ZEND_HASH_FOREACH_END();
        }
        if (ctx->attributeGroups) {
-               zend_hash_internal_pointer_reset(ctx->attributeGroups);
-               while (zend_hash_get_current_data(ctx->attributeGroups,(void**)&type) == SUCCESS) {
-                       schema_type_fixup(ctx,*type);
-                       zend_hash_move_forward(ctx->attributeGroups);
-               }
+               ZEND_HASH_FOREACH_PTR(ctx->attributeGroups, type) {
+                       schema_type_fixup(ctx, type);
+               } ZEND_HASH_FOREACH_END();
        }
        if (sdl->elements) {
-               zend_hash_internal_pointer_reset(sdl->elements);
-               while (zend_hash_get_current_data(sdl->elements,(void**)&type) == SUCCESS) {
-                       schema_type_fixup(ctx,*type);
-                       zend_hash_move_forward(sdl->elements);
-               }
+               ZEND_HASH_FOREACH_PTR(sdl->elements, type) {
+                       schema_type_fixup(ctx, type);
+               } ZEND_HASH_FOREACH_END();
        }
        if (sdl->groups) {
-               zend_hash_internal_pointer_reset(sdl->groups);
-               while (zend_hash_get_current_data(sdl->groups,(void**)&type) == SUCCESS) {
-                       schema_type_fixup(ctx,*type);
-                       zend_hash_move_forward(sdl->groups);
-               }
+               ZEND_HASH_FOREACH_PTR(sdl->groups, type) {
+                       schema_type_fixup(ctx, type);
+               } ZEND_HASH_FOREACH_END();
        }
        if (sdl->types) {
-               zend_hash_internal_pointer_reset(sdl->types);
-               while (zend_hash_get_current_data(sdl->types,(void**)&type) == SUCCESS) {
-                       schema_type_fixup(ctx,*type);
-                       zend_hash_move_forward(sdl->types);
-               }
+               ZEND_HASH_FOREACH_PTR(sdl->types, type) {
+                       schema_type_fixup(ctx, type);
+               } ZEND_HASH_FOREACH_END();
        }
        if (ctx->attributes) {
                zend_hash_destroy(ctx->attributes);
@@ -2337,9 +2323,9 @@ void schema_pass2(sdlCtx *ctx)
        }
 }
 
-void delete_model(void *handle)
+void delete_model(zval *zv)
 {
-       sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
+       sdlContentModelPtr tmp = Z_PTR_P(zv);
        switch (tmp->kind) {
                case XSD_CONTENT_ELEMENT:
                case XSD_CONTENT_GROUP:
@@ -2359,9 +2345,8 @@ void delete_model(void *handle)
        efree(tmp);
 }
 
-void delete_model_persistent(void *handle)
+static void delete_model_persistent_int(sdlContentModelPtr tmp)
 {
-       sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
        switch (tmp->kind) {
                case XSD_CONTENT_ELEMENT:
                case XSD_CONTENT_GROUP:
@@ -2381,9 +2366,14 @@ void delete_model_persistent(void *handle)
        free(tmp);
 }
 
-void delete_type(void *data)
+void delete_model_persistent(zval *zv)
+{
+       delete_model_persistent_int(Z_PTR_P(zv));       
+}
+
+void delete_type(zval *zv)
 {
-       sdlTypePtr type = *((sdlTypePtr*)data);
+       sdlTypePtr type = Z_PTR_P(zv);
 
        if (type->name) {
                efree(type->name);
@@ -2406,20 +2396,22 @@ void delete_type(void *data)
                efree(type->attributes);
        }
        if (type->model) {
-               delete_model((void**)&type->model);
+               zval zv;
+               ZVAL_PTR(&zv, type->model);
+               delete_model(&zv);
        }
        if (type->restrictions) {
-               delete_restriction_var_int(&type->restrictions->minExclusive);
-               delete_restriction_var_int(&type->restrictions->minInclusive);
-               delete_restriction_var_int(&type->restrictions->maxExclusive);
-               delete_restriction_var_int(&type->restrictions->maxInclusive);
-               delete_restriction_var_int(&type->restrictions->totalDigits);
-               delete_restriction_var_int(&type->restrictions->fractionDigits);
-               delete_restriction_var_int(&type->restrictions->length);
-               delete_restriction_var_int(&type->restrictions->minLength);
-               delete_restriction_var_int(&type->restrictions->maxLength);
-               delete_restriction_var_char(&type->restrictions->whiteSpace);
-               delete_restriction_var_char(&type->restrictions->pattern);
+               delete_restriction_var_int(type->restrictions->minExclusive);
+               delete_restriction_var_int(type->restrictions->minInclusive);
+               delete_restriction_var_int(type->restrictions->maxExclusive);
+               delete_restriction_var_int(type->restrictions->maxInclusive);
+               delete_restriction_var_int(type->restrictions->totalDigits);
+               delete_restriction_var_int(type->restrictions->fractionDigits);
+               delete_restriction_var_int(type->restrictions->length);
+               delete_restriction_var_int(type->restrictions->minLength);
+               delete_restriction_var_int(type->restrictions->maxLength);
+               delete_restriction_var_char_int(type->restrictions->whiteSpace);
+               delete_restriction_var_char_int(type->restrictions->pattern);
                if (type->restrictions->enumeration) {
                        zend_hash_destroy(type->restrictions->enumeration);
                        efree(type->restrictions->enumeration);
@@ -2429,9 +2421,9 @@ void delete_type(void *data)
        efree(type);
 }
 
-void delete_type_persistent(void *data)
+void delete_type_persistent(zval *zv)
 {
-       sdlTypePtr type = *((sdlTypePtr*)data);
+       sdlTypePtr type = Z_PTR_P(zv);
        if (type->name) {
                free(type->name);
        }
@@ -2453,20 +2445,20 @@ void delete_type_persistent(void *data)
                free(type->attributes);
        }
        if (type->model) {
-               delete_model_persistent((void**)&type->model);
+               delete_model_persistent_int(type->model);
        }
        if (type->restrictions) {
-               delete_restriction_var_int_persistent(&type->restrictions->minExclusive);
-               delete_restriction_var_int_persistent(&type->restrictions->minInclusive);
-               delete_restriction_var_int_persistent(&type->restrictions->maxExclusive);
-               delete_restriction_var_int_persistent(&type->restrictions->maxInclusive);
-               delete_restriction_var_int_persistent(&type->restrictions->totalDigits);
-               delete_restriction_var_int_persistent(&type->restrictions->fractionDigits);
-               delete_restriction_var_int_persistent(&type->restrictions->length);
-               delete_restriction_var_int_persistent(&type->restrictions->minLength);
-               delete_restriction_var_int_persistent(&type->restrictions->maxLength);
-               delete_restriction_var_char_persistent(&type->restrictions->whiteSpace);
-               delete_restriction_var_char_persistent(&type->restrictions->pattern);
+               delete_restriction_var_int_persistent(type->restrictions->minExclusive);
+               delete_restriction_var_int_persistent(type->restrictions->minInclusive);
+               delete_restriction_var_int_persistent(type->restrictions->maxExclusive);
+               delete_restriction_var_int_persistent(type->restrictions->maxInclusive);
+               delete_restriction_var_int_persistent(type->restrictions->totalDigits);
+               delete_restriction_var_int_persistent(type->restrictions->fractionDigits);
+               delete_restriction_var_int_persistent(type->restrictions->length);
+               delete_restriction_var_int_persistent(type->restrictions->minLength);
+               delete_restriction_var_int_persistent(type->restrictions->maxLength);
+               delete_restriction_var_char_persistent_int(type->restrictions->whiteSpace);
+               delete_restriction_var_char_persistent_int(type->restrictions->pattern);
                if (type->restrictions->enumeration) {
                        zend_hash_destroy(type->restrictions->enumeration);
                        free(type->restrictions->enumeration);
@@ -2476,9 +2468,9 @@ void delete_type_persistent(void *data)
        free(type);
 }
 
-void delete_extra_attribute(void *attribute)
+void delete_extra_attribute(zval *zv)
 {
-       sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
+       sdlExtraAttributePtr attr = Z_PTR_P(zv);
 
        if (attr->ns) {
                efree(attr->ns);
@@ -2489,9 +2481,9 @@ void delete_extra_attribute(void *attribute)
        efree(attr);
 }
 
-void delete_extra_attribute_persistent(void *attribute)
+void delete_extra_attribute_persistent(zval *zv)
 {
-       sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
+       sdlExtraAttributePtr attr = Z_PTR_P(zv);
 
        if (attr->ns) {
                free(attr->ns);
@@ -2502,9 +2494,9 @@ void delete_extra_attribute_persistent(void *attribute)
        free(attr);
 }
 
-void delete_attribute(void *attribute)
+void delete_attribute(zval *zv)
 {
-       sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
+       sdlAttributePtr attr = Z_PTR_P(zv);
 
        if (attr->def) {
                efree(attr->def);
@@ -2528,9 +2520,9 @@ void delete_attribute(void *attribute)
        efree(attr);
 }
 
-void delete_attribute_persistent(void *attribute)
+void delete_attribute_persistent(zval *zv)
 {
-       sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
+       sdlAttributePtr attr = Z_PTR_P(zv);
 
        if (attr->def) {
                free(attr->def);
@@ -2554,25 +2546,22 @@ void delete_attribute_persistent(void *attribute)
        free(attr);
 }
 
-void delete_restriction_var_int(void *rvi)
+void delete_restriction_var_int(sdlRestrictionIntPtr ptr)
 {
-       sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
        if (ptr) {
                efree(ptr);
        }
 }
 
-void delete_restriction_var_int_persistent(void *rvi)
+void delete_restriction_var_int_persistent(sdlRestrictionIntPtr ptr)
 {
-       sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
        if (ptr) {
                free(ptr);
        }
 }
 
-void delete_restriction_var_char(void *srvc)
+void delete_restriction_var_char_int(sdlRestrictionCharPtr ptr)
 {
-       sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
        if (ptr) {
                if (ptr->value) {
                        efree(ptr->value);
@@ -2581,9 +2570,13 @@ void delete_restriction_var_char(void *srvc)
        }
 }
 
-void delete_restriction_var_char_persistent(void *srvc)
+void delete_restriction_var_char(zval *zv)
+{
+       delete_restriction_var_char_int(Z_PTR_P(zv));
+}
+
+void delete_restriction_var_char_persistent_int(sdlRestrictionCharPtr ptr)
 {
-       sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
        if (ptr) {
                if (ptr->value) {
                        free(ptr->value);
@@ -2591,3 +2584,8 @@ void delete_restriction_var_char_persistent(void *srvc)
                free(ptr);
        }
 }
+
+void delete_restriction_var_char_persistent(zval *zv)
+{
+       delete_restriction_var_char_persistent_int(Z_PTR_P(zv));        
+}
index 62075b9531ed03818070c8f70fdfda2eb3ca6480..d68db88edcaaf41ed47eafbd1cf7efac17a29d2f 100644 (file)
 int load_schema(sdlCtx *ctx, xmlNodePtr schema TSRMLS_DC);
 void schema_pass2(sdlCtx *ctx);
 
-void delete_model(void *handle);
-void delete_model_persistent(void *handle);
-void delete_type(void *data);
-void delete_type_persistent(void *data);
-void delete_extra_attribute(void *attribute);
-void delete_extra_attribute_persistent(void *attribute);
-void delete_attribute(void *attribute);
-void delete_attribute_persistent(void *attribute);
-void delete_restriction_var_int(void *rvi);
-void delete_restriction_var_int_persistent(void *rvi);
-void delete_restriction_var_char(void *srvc);
-void delete_restriction_var_char_persistent(void *srvc);
+void delete_model(zval *zv);
+void delete_model_persistent(zval *zv);
+void delete_type(zval *zv);
+void delete_type_persistent(zval *zv);
+void delete_extra_attribute(zval *zv);
+void delete_extra_attribute_persistent(zval *zv);
+void delete_attribute(zval *zv);
+void delete_attribute_persistent(zval *zv);
+void delete_restriction_var_int(sdlRestrictionIntPtr ptr);
+void delete_restriction_var_int_persistent(sdlRestrictionIntPtr ptr);
+void delete_restriction_var_char(zval *zv);
+void delete_restriction_var_char_int(sdlRestrictionCharPtr ptr);
+void delete_restriction_var_char_persistent(zval *zv);
+void delete_restriction_var_char_persistent_int(sdlRestrictionCharPtr ptr);
 #endif
index cde4ca144b106ccd577fcef05f5d97bebcbfa604..ff98fae6965e55f035407b6e23af7b5b92934972 100644 (file)
 # define O_BINARY 0
 #endif
 
-static void delete_fault(void *fault);
-static void delete_fault_persistent(void *fault);
-static void delete_binding(void *binding);
-static void delete_binding_persistent(void *binding);
-static void delete_function(void *function);
-static void delete_function_persistent(void *function);
-static void delete_parameter(void *parameter);
-static void delete_parameter_persistent(void *parameter);
-static void delete_header(void *header);
-static void delete_header_persistent(void *header);
-static void delete_document(void *doc_ptr);
+static void delete_fault(zval *zv);
+static void delete_fault_persistent(zval *zv);
+static void delete_binding(zval *zv);
+static void delete_binding_persistent(zval *zv);
+static void delete_function(zval *zv);
+static void delete_function_persistent(zval *zv);
+static void delete_parameter(zval *zv);
+static void delete_parameter_persistent(zval *zv);
+static void delete_header(zval *header);
+static void delete_header_int(sdlSoapBindingFunctionHeaderPtr hdr);
+static void delete_header_persistent(zval *zv);
+static void delete_document(zval *zv);
 
 encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
 {
@@ -74,7 +75,7 @@ static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
        if (sdl->elements) {
                xmlNsPtr nsptr;
                char *ns, *cptype;
-               sdlTypePtr *sdl_type;
+               sdlTypePtr sdl_type;
 
                parse_namespace(type, &cptype, &ns);
                nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns));
@@ -89,15 +90,15 @@ static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
                        memcpy(nscat+ns_len+1, cptype, type_len);
                        nscat[len] = '\0';
 
-                       if (zend_hash_find(sdl->elements, nscat, len + 1, (void **)&sdl_type) == SUCCESS) {
-                               ret = *sdl_type;
-                       } else if (zend_hash_find(sdl->elements, (char*)type, type_len + 1, (void **)&sdl_type) == SUCCESS) {
-                               ret = *sdl_type;
+                       if ((sdl_type = zend_hash_str_find_ptr(sdl->elements, nscat, len)) != NULL) {
+                               ret = sdl_type;
+                       } else if ((sdl_type = zend_hash_str_find_ptr(sdl->elements, (char*)type, type_len)) != NULL) {
+                               ret = sdl_type;
                        }
                        efree(nscat);
                } else {
-                       if (zend_hash_find(sdl->elements, (char*)type, xmlStrlen(type) + 1, (void **)&sdl_type) == SUCCESS) {
-                               ret = *sdl_type;
+                       if ((sdl_type = zend_hash_str_find_ptr(sdl->elements, (char*)type, xmlStrlen(type))) != NULL) {
+                               ret = sdl_type;
                        }
                }
 
@@ -156,7 +157,7 @@ encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
                                sdl->encoders = pemalloc(sizeof(HashTable), sdl->is_persistent);
                                zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, sdl->is_persistent);
                        }
-                       zend_hash_update(sdl->encoders, nscat, len + 1, &new_enc, sizeof(encodePtr), NULL);
+                       zend_hash_str_update_ptr(sdl->encoders, nscat, len, new_enc);
                        enc = new_enc;
                }
        }
@@ -166,38 +167,36 @@ encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
 
 encodePtr get_encoder_ex(sdlPtr sdl, const char *nscat, int len)
 {
-       encodePtr *enc;
+       encodePtr enc;
        TSRMLS_FETCH();
 
-       if (zend_hash_find(&SOAP_GLOBAL(defEnc), (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
-               return (*enc);
-       } else if (sdl && sdl->encoders && zend_hash_find(sdl->encoders, (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
-               return (*enc);
+       if ((enc = zend_hash_str_find_ptr(&SOAP_GLOBAL(defEnc), (char*)nscat, len)) != NULL) {
+               return enc;
+       } else if (sdl && sdl->encoders && (enc = zend_hash_str_find_ptr(sdl->encoders, (char*)nscat, len)) != NULL) {
+               return enc;
        }
        return NULL;
 }
 
 sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type)
 {
-       sdlBindingPtr *binding;
+       sdlBindingPtr binding;
 
        if (sdl == NULL) {
                return NULL;
        }
 
-       for (zend_hash_internal_pointer_reset(sdl->bindings);
-               zend_hash_get_current_data(sdl->bindings, (void **) &binding) == SUCCESS;
-               zend_hash_move_forward(sdl->bindings)) {
-               if ((*binding)->bindingType == type) {
-                       return *binding;
+       ZEND_HASH_FOREACH_PTR(sdl->bindings, binding) {
+               if (binding->bindingType == type) {
+                       return binding;
                }
-       }
+       } ZEND_HASH_FOREACH_END();
        return NULL;
 }
 
 sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns)
 {
-       sdlBindingPtr binding = NULL;
+       sdlBindingPtr binding;
        smart_str key = {0};
 
        smart_str_appends(&key, ns);
@@ -205,7 +204,7 @@ sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns)
        smart_str_appends(&key, name);
        smart_str_0(&key);
 
-       zend_hash_find(sdl->bindings, key.c, key.len, (void **)&binding);
+       binding = zend_hash_find_ptr(sdl->bindings, key.s);
 
        smart_str_free(&key);
        return binding;
@@ -230,8 +229,8 @@ void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC)
 {
        char *s;
        int l1, l2;
-       zval *context = NULL;
-       zval **header = NULL;
+       zval context;
+       zval *header = NULL;
 
        /* check if we load xsd from the same server */
        s = strstr(ctx->sdl->source, "://");
@@ -278,27 +277,25 @@ void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC)
        }
        if (l1 != l2 || memcmp(ctx->sdl->source, uri, l1) != 0) {
                /* another server. clear authentication credentals */
-               context = php_libxml_switch_context(NULL TSRMLS_CC);
-               php_libxml_switch_context(context TSRMLS_CC);
-               if (context) {
-                       ctx->context = php_stream_context_from_zval(context, 1);
+               php_libxml_switch_context(NULL, &context TSRMLS_CC);
+               php_libxml_switch_context(&context, NULL TSRMLS_CC);
+               if (Z_TYPE(context) != IS_UNDEF) {
+                       zval *context_ptr = &context;
+                       ctx->context = php_stream_context_from_zval(context_ptr, 1);
 
                        if (ctx->context &&
-                           php_stream_context_get_option(ctx->context, "http", "header", &header) == SUCCESS) {
-                               s = strstr(Z_STRVAL_PP(header), "Authorization: Basic");
-                               if (s && (s == Z_STRVAL_PP(header) || *(s-1) == '\n' || *(s-1) == '\r')) {
+                           (header = php_stream_context_get_option(ctx->context, "http", "header")) != NULL) {
+                               s = strstr(Z_STRVAL_P(header), "Authorization: Basic");
+                               if (s && (s == Z_STRVAL_P(header) || *(s-1) == '\n' || *(s-1) == '\r')) {
                                        char *rest = strstr(s, "\r\n");
                                        if (rest) {
                                                zval new_header;
                                        
                                                rest += 2;
-                                               Z_TYPE(new_header) = IS_STRING;
-                                               Z_STRLEN(new_header) = Z_STRLEN_PP(header) - (rest - s);
-                                               Z_STRVAL(new_header) = emalloc(Z_STRLEN_PP(header) + 1);
-                                               memcpy(Z_STRVAL(new_header), Z_STRVAL_PP(header), s - Z_STRVAL_PP(header));
-                                               memcpy(Z_STRVAL(new_header) + (s - Z_STRVAL_PP(header)), rest, Z_STRLEN_PP(header) - (rest - Z_STRVAL_PP(header)) + 1);
-                                               ctx->old_header = *header;
-                                               Z_ADDREF_P(ctx->old_header);
+                                               ZVAL_STR(&new_header, STR_ALLOC(Z_STRLEN_P(header) - (rest - s), 0));
+                                               memcpy(Z_STRVAL(new_header), Z_STRVAL_P(header), s - Z_STRVAL_P(header));
+                                               memcpy(Z_STRVAL(new_header) + (s - Z_STRVAL_P(header)), rest, Z_STRLEN_P(header) - (rest - Z_STRVAL_P(header)) + 1);
+                                               ZVAL_COPY(&ctx->old_header, header);
                                                php_stream_context_set_option(ctx->context, "http", "header", &new_header);
                                                zval_dtor(&new_header);
                                        }
@@ -310,10 +307,10 @@ void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC)
 
 void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC)
 {
-       if (ctx->old_header) {
-           php_stream_context_set_option(ctx->context, "http", "header", ctx->old_header);
+       if (Z_TYPE(ctx->old_header) != IS_UNDEF) {
+           php_stream_context_set_option(ctx->context, "http", "header", &ctx->old_header);
            zval_ptr_dtor(&ctx->old_header);
-               ctx->old_header = NULL;
+               ZVAL_UNDEF(&ctx->old_header);
        }
        ctx->context = NULL;
 }
@@ -325,7 +322,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
        xmlNodePtr root, definitions, trav;
        xmlAttrPtr targetNamespace;
 
-       if (zend_hash_exists(&ctx->docs, struri, strlen(struri)+1)) {
+       if (zend_hash_str_exists(&ctx->docs, struri, strlen(struri))) {
                return;
        }
        
@@ -343,7 +340,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
                }
        }
 
-       zend_hash_add(&ctx->docs, struri, strlen(struri)+1, (void**)&wsdl, sizeof(xmlDocPtr), NULL);
+       zend_hash_str_add_ptr(&ctx->docs, struri, strlen(struri), wsdl);
 
        root = wsdl->children;
        definitions = get_node_ex(root, "definitions", WSDL_NAMESPACE);
@@ -403,7 +400,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
                } else if (node_is_equal(trav,"message")) {
                        xmlAttrPtr name = get_attribute(trav->properties, "name");
                        if (name && name->children && name->children->content) {
-                               if (zend_hash_add(&ctx->messages, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
+                               if (zend_hash_str_add_ptr(&ctx->messages, (char*)name->children->content, xmlStrlen(name->children->content), trav) == NULL) {
                                        soap_error1(E_ERROR, "Parsing WSDL: <message> '%s' already defined", name->children->content);
                                }
                        } else {
@@ -413,7 +410,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
                } else if (node_is_equal(trav,"portType")) {
                        xmlAttrPtr name = get_attribute(trav->properties, "name");
                        if (name && name->children && name->children->content) {
-                               if (zend_hash_add(&ctx->portTypes, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
+                               if (zend_hash_str_add_ptr(&ctx->portTypes, (char*)name->children->content, xmlStrlen(name->children->content), trav) == NULL) {
                                        soap_error1(E_ERROR, "Parsing WSDL: <portType> '%s' already defined", name->children->content);
                                }
                        } else {
@@ -423,7 +420,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
                } else if (node_is_equal(trav,"binding")) {
                        xmlAttrPtr name = get_attribute(trav->properties, "name");
                        if (name && name->children && name->children->content) {
-                               if (zend_hash_add(&ctx->bindings, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
+                               if (zend_hash_str_add_ptr(&ctx->bindings, (char*)name->children->content, xmlStrlen(name->children->content), trav) == NULL) {
                                        soap_error1(E_ERROR, "Parsing WSDL: <binding> '%s' already defined", name->children->content);
                                }
                        } else {
@@ -433,7 +430,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
                } else if (node_is_equal(trav,"service")) {
                        xmlAttrPtr name = get_attribute(trav->properties, "name");
                        if (name && name->children && name->children->content) {
-                               if (zend_hash_add(&ctx->services, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
+                               if (zend_hash_str_add_ptr(&ctx->services, (char*)name->children->content, xmlStrlen(name->children->content), trav) == NULL) {
                                        soap_error1(E_ERROR, "Parsing WSDL: <service> '%s' already defined", name->children->content);
                                }
                        } else {
@@ -464,7 +461,7 @@ static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xml
        } else {
                ++ctype;
        }
-       if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&message) != SUCCESS) {
+       if ((message = zend_hash_str_find_ptr(&ctx->messages, ctype, strlen(ctype))) == NULL) {
                soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", tmp->children->content);
        }
 
@@ -545,8 +542,8 @@ static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xml
                                }
                                smart_str_appends(&key,hf->name);
                                smart_str_0(&key);
-                               if (zend_hash_add(h->headerfaults, key.c, key.len+1, (void**)&hf, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
-                                       delete_header((void**)&hf);
+                               if (zend_hash_add_ptr(h->headerfaults, key.s, hf) == NULL) {
+                                       delete_header_int(hf);
                                }
                                smart_str_free(&key);
                        } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
@@ -588,8 +585,7 @@ static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap
                                /* Delete all parts those are not in the "parts" attribute */
                                zend_hash_init(&ht, 0, NULL, delete_parameter, 0);
                                while (*parts) {
-                                       HashPosition pos;
-                                       sdlParamPtr *param;
+                                       sdlParamPtr param;
                                        int found = 0;
                                        char *end;
 
@@ -597,20 +593,18 @@ static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap
                                        if (*parts == '\0') break;
                                        end = strchr(parts, ' ');
                                        if (end) *end = '\0';
-                                       zend_hash_internal_pointer_reset_ex(params, &pos);
-                                       while (zend_hash_get_current_data_ex(params, (void **)&param, &pos) != FAILURE) {
-                                               if ((*param)->paramName &&
-                                                   strcmp(parts, (*param)->paramName) == 0) {
+                                       ZEND_HASH_FOREACH_PTR(params, param) {
+                                               if (param->paramName &&
+                                                   strcmp(parts, param->paramName) == 0) {
                                                sdlParamPtr x_param;
                                                x_param = emalloc(sizeof(sdlParam));
-                                               *x_param = **param;
-                                               (*param)->paramName = NULL;
-                                               zend_hash_next_index_insert(&ht, &x_param, sizeof(sdlParamPtr), NULL);
+                                               *x_param = *param;
+                                               param->paramName = NULL;
+                                               zend_hash_next_index_insert_ptr(&ht, x_param);
                                                found = 1;
                                                break;
                                                }
-                                               zend_hash_move_forward_ex(params, &pos);
-                                       }
+                                       } ZEND_HASH_FOREACH_END();
                                        if (!found) {
                                                soap_error1(E_ERROR, "Parsing WSDL: Missing part '%s' in <message>", parts);
                                        }
@@ -650,8 +644,8 @@ static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap
                        }
                        smart_str_appends(&key,h->name);
                        smart_str_0(&key);
-                       if (zend_hash_add(binding->headers, key.c, key.len+1, (void**)&h, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
-                               delete_header((void**)&h);
+                       if (zend_hash_add_ptr(binding->headers, key.s, h) == NULL) {
+                               delete_header_int(h);
                        }
                        smart_str_free(&key);
                } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
@@ -663,7 +657,7 @@ static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap
 
 static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
 {
-       xmlNodePtr trav, part, message = NULL, *tmp;
+       xmlNodePtr trav, part, message = NULL, tmp;
        HashTable* parameters = NULL;
        char *ctype;
 
@@ -673,10 +667,10 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
        } else {
                ++ctype;
        }
-       if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
+       if ((tmp = zend_hash_str_find_ptr(&ctx->messages, ctype, strlen(ctype))) == NULL) {
                soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", message_name);
        }
-       message = *tmp;
+       message = tmp;
 
        parameters = emalloc(sizeof(HashTable));
        zend_hash_init(parameters, 0, NULL, delete_parameter, 0);
@@ -721,7 +715,7 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
                        }
                }
 
-               zend_hash_next_index_insert(parameters, &param, sizeof(sdlParamPtr), NULL);
+               zend_hash_next_index_insert_ptr(parameters, param);
 
                trav = trav->next;
        }
@@ -752,12 +746,11 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
        if (n > 0) {
                zend_hash_internal_pointer_reset(&ctx.services);
                for (i = 0; i < n; i++) {
-                       xmlNodePtr *tmp, service;
+                       xmlNodePtr service, tmp;
                        xmlNodePtr trav, port;
                        int has_soap_port = 0;
 
-                       zend_hash_get_current_data(&ctx.services, (void **)&tmp);
-                       service = *tmp;
+                       service = tmp = zend_hash_get_current_data_ptr(&ctx.services);
 
                        trav = service->children;
                        while (trav != NULL) {
@@ -840,10 +833,10 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
                                } else {
                                        ++ctype;
                                }
-                               if (zend_hash_find(&ctx.bindings, ctype, strlen(ctype)+1, (void*)&tmp) != SUCCESS) {
+                               if ((tmp = zend_hash_str_find_ptr(&ctx.bindings, ctype, strlen(ctype))) == NULL) {
                                        soap_error1(E_ERROR, "Parsing WSDL: No <binding> element with name '%s'", ctype);
                                }
-                               binding = *tmp;
+                               binding = tmp;
 
                                if (tmpbinding->bindingType == BINDING_SOAP) {
                                        sdlSoapBindingPtr soapBinding;
@@ -895,10 +888,10 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
                                } else {
                                        ++ctype;
                                }
-                               if (zend_hash_find(&ctx.portTypes, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
+                               if ((tmp = zend_hash_str_find_ptr(&ctx.portTypes, ctype, strlen(ctype))) == NULL) {
                                        soap_error1(E_ERROR, "Parsing WSDL: Missing <portType> with name '%s'", name->children->content);
                                }
-                               portType = *tmp;
+                               portType = tmp;
 
                                trav2 = binding->children;
                                while (trav2 != NULL) {
@@ -1121,7 +1114,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
                                                                function->faults = emalloc(sizeof(HashTable));
                                                                zend_hash_init(function->faults, 0, NULL, delete_fault, 0);
                                                        }
-                                                       if (zend_hash_add(function->faults, f->name, strlen(f->name)+1, (void**)&f, sizeof(sdlFaultPtr), NULL) != SUCCESS) {
+                                                       if (zend_hash_str_add_ptr(function->faults, f->name, strlen(f->name), f) == NULL) {
                                                                soap_error2(E_ERROR, "Parsing WSDL: <fault> with name '%s' already defined in '%s'", f->name, op_name->children->content);
                                                        }
                                                }
@@ -1134,8 +1127,8 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
                                                char *tmp = estrdup(function->functionName);
                                                int  len = strlen(tmp);
 
-                                               if (zend_hash_add(&ctx.sdl->functions, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL) != SUCCESS) {
-                                                       zend_hash_next_index_insert(&ctx.sdl->functions, &function, sizeof(sdlFunctionPtr), NULL);
+                                               if (zend_hash_str_add_ptr(&ctx.sdl->functions, php_strtolower(tmp, len), len, function) == NULL) {
+                                                       zend_hash_next_index_insert_ptr(&ctx.sdl->functions, function);
                                                }
                                                efree(tmp);
                                                if (function->requestName != NULL && strcmp(function->requestName,function->functionName) != 0) {
@@ -1145,7 +1138,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
                                                        }
                                                        tmp = estrdup(function->requestName);
                                                        len = strlen(tmp);
-                                                       zend_hash_add(ctx.sdl->requests, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL);
+                                                       zend_hash_str_add_ptr(ctx.sdl->requests, php_strtolower(tmp, len), len, function);
                                                        efree(tmp);
                                                }
                                        }
@@ -1157,7 +1150,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
                                        zend_hash_init(ctx.sdl->bindings, 0, NULL, delete_binding, 0);
                                }
 
-                               zend_hash_add(ctx.sdl->bindings, tmpbinding->name, strlen(tmpbinding->name), &tmpbinding, sizeof(sdlBindingPtr), NULL);
+                               zend_hash_str_add_ptr(ctx.sdl->bindings, tmpbinding->name, strlen(tmpbinding->name), tmpbinding);
                                trav= trav->next;
                        }
 
@@ -1217,9 +1210,9 @@ static void sdl_deserialize_key(HashTable* ht, void* data, char **in)
 
        WSDL_CACHE_GET_INT(len, in);
        if (len == 0) {
-               zend_hash_next_index_insert(ht, &data, sizeof(void*), NULL);
+               zend_hash_next_index_insert_ptr(ht, data);
        } else {
-               zend_hash_add(ht, *in, len, &data, sizeof(void*), NULL);
+               zend_hash_str_add_ptr(ht, *in, len, data);
                WSDL_CACHE_SKIP(len, in);
        }
 }
@@ -1300,7 +1293,7 @@ static sdlContentModelPtr sdl_deserialize_model(sdlTypePtr *types, sdlTypePtr *e
                        zend_hash_init(model->u.content, i, NULL, delete_model, 0);
                        while (i > 0) {
                                sdlContentModelPtr x = sdl_deserialize_model(types, elements, in);
-                               zend_hash_next_index_insert(model->u.content,&x,sizeof(sdlContentModelPtr),NULL);
+                               zend_hash_next_index_insert_ptr(model->u.content, x);
                                i--;
                        }
                        break;
@@ -1797,15 +1790,12 @@ static void sdl_serialize_string(const char *str, smart_str *out)
        }
 }
 
-static void sdl_serialize_key(HashTable *ht, smart_str *out)
+// TODO: refactor it
+static void sdl_serialize_key(zend_string *key, smart_str *out)
 {
-       char *key;
-       uint  key_len;
-       ulong index;
-
-       if (zend_hash_get_current_key_ex(ht, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-               WSDL_CACHE_PUT_INT(key_len, out);
-               WSDL_CACHE_PUT_N(key, key_len, out);
+       if (key) {
+               WSDL_CACHE_PUT_INT(key->len, out);
+               WSDL_CACHE_PUT_N(key->val, key->len, out);
        } else {
                WSDL_CACHE_PUT_INT(0, out);
        }
@@ -1813,9 +1803,9 @@ static void sdl_serialize_key(HashTable *ht, smart_str *out)
 
 static void sdl_serialize_encoder_ref(encodePtr enc, HashTable *tmp_encoders, smart_str *out) {
        if (enc) {
-               int *encoder_num;
-               if (zend_hash_find(tmp_encoders, (char*)&enc, sizeof(enc), (void**)&encoder_num) == SUCCESS) {
-                       WSDL_CACHE_PUT_INT(*encoder_num, out);
+               zval *encoder_num;
+               if ((encoder_num = zend_hash_str_find(tmp_encoders, (char*)&enc, sizeof(enc))) != 0) {
+                       WSDL_CACHE_PUT_INT(Z_LVAL_P(encoder_num), out);
                } else {
                        WSDL_CACHE_PUT_INT(0, out);
                }
@@ -1826,9 +1816,9 @@ static void sdl_serialize_encoder_ref(encodePtr enc, HashTable *tmp_encoders, sm
 
 static void sdl_serialize_type_ref(sdlTypePtr type, HashTable *tmp_types, smart_str *out) {
        if (type) {
-               int *type_num;
-               if (zend_hash_find(tmp_types, (char*)&type, sizeof(type), (void**)&type_num) == SUCCESS) {
-                       WSDL_CACHE_PUT_INT(*type_num, out);
+               zval *type_num;
+               if ((type_num = zend_hash_str_find(tmp_types, (char*)&type, sizeof(type))) != NULL) {
+                       WSDL_CACHE_PUT_INT(Z_LVAL_P(type_num), out);
                } else {
                        WSDL_CACHE_PUT_INT(0, out);
                }
@@ -1856,14 +1846,14 @@ static void sdl_serialize_attribute(sdlAttributePtr attr, HashTable *tmp_encoder
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlExtraAttributePtr *tmp;
-               zend_hash_internal_pointer_reset(attr->extraAttributes);
-               while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(attr->extraAttributes, out);
-                       sdl_serialize_string((*tmp)->ns, out);
-                       sdl_serialize_string((*tmp)->val, out);
-                       zend_hash_move_forward(attr->extraAttributes);
-               }
+               sdlExtraAttributePtr tmp;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(attr->extraAttributes, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_string(tmp->ns, out);
+                       sdl_serialize_string(tmp->val, out);
+               } ZEND_HASH_FOREACH_END();
        }
 }
 
@@ -1879,15 +1869,13 @@ static void sdl_serialize_model(sdlContentModelPtr model, HashTable *tmp_types,
                case XSD_CONTENT_SEQUENCE:
                case XSD_CONTENT_ALL:
                case XSD_CONTENT_CHOICE: {
-                               sdlContentModelPtr *tmp;
+                               sdlContentModelPtr tmp;
                                int i = zend_hash_num_elements(model->u.content);
 
                                WSDL_CACHE_PUT_INT(i, out);
-                               zend_hash_internal_pointer_reset(model->u.content);
-                               while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
-                                       sdl_serialize_model(*tmp, tmp_types, tmp_elements, out);
-                                       zend_hash_move_forward(model->u.content);
-                               }
+                               ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                                       sdl_serialize_model(tmp, tmp_types, tmp_elements, out);
+                               } ZEND_HASH_FOREACH_END();
                        }
                        break;
                case XSD_CONTENT_GROUP_REF:
@@ -1958,14 +1946,13 @@ static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTab
                }
                WSDL_CACHE_PUT_INT(i, out);
                if (i > 0) {
-                       sdlRestrictionCharPtr *tmp;
+                       sdlRestrictionCharPtr tmp;
+                       zend_string *key;
 
-                       zend_hash_internal_pointer_reset(type->restrictions->enumeration);
-                       while (zend_hash_get_current_data(type->restrictions->enumeration, (void**)&tmp) == SUCCESS) {
-                               sdl_serialize_resriction_char(*tmp, out);
-                               sdl_serialize_key(type->restrictions->enumeration, out);
-                               zend_hash_move_forward(type->restrictions->enumeration);
-                       }
+                       ZEND_HASH_FOREACH_STR_KEY_PTR(type->restrictions->enumeration, key, tmp) {
+                               sdl_serialize_resriction_char(tmp, out);
+                               sdl_serialize_key(key, out);
+                       } ZEND_HASH_FOREACH_END();
                }
        } else {
                WSDL_CACHE_PUT_1(0, out);
@@ -1977,19 +1964,20 @@ static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTab
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlTypePtr *tmp;
+               sdlTypePtr tmp;
+               zend_string *key;
+               zval zv;
 
                tmp_elements = emalloc(sizeof(HashTable));
                zend_hash_init(tmp_elements, i, NULL, NULL, 0);
 
-               zend_hash_internal_pointer_reset(type->elements);
-               while (zend_hash_get_current_data(type->elements, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(type->elements, out);
-                       sdl_serialize_type(*tmp, tmp_encoders, tmp_types, out);
-                       zend_hash_add(tmp_elements, (char*)tmp, sizeof(*tmp), &i, sizeof(int), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(type->elements, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_type(tmp, tmp_encoders, tmp_types, out);
+                       ZVAL_LONG(&zv, i);
+                       zend_hash_str_add(tmp_elements, (char*)&tmp, sizeof(tmp), &zv);
                        i--;
-                       zend_hash_move_forward(type->elements);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (type->attributes) {
@@ -1999,13 +1987,13 @@ static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTab
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlAttributePtr *tmp;
-               zend_hash_internal_pointer_reset(type->attributes);
-               while (zend_hash_get_current_data(type->attributes, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(type->attributes, out);
-                       sdl_serialize_attribute(*tmp, tmp_encoders, out);
-                       zend_hash_move_forward(type->attributes);
-               }
+               sdlAttributePtr tmp;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(type->attributes, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_attribute(tmp, tmp_encoders, out);
+               } ZEND_HASH_FOREACH_END();
        }
        if (type->model) {
                WSDL_CACHE_PUT_1(1, out);
@@ -2038,17 +2026,16 @@ static void sdl_serialize_parameters(HashTable *ht, HashTable *tmp_encoders, Has
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlParamPtr *tmp;
+               sdlParamPtr tmp;
+               zend_string *key;
 
-               zend_hash_internal_pointer_reset(ht);
-               while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(ht, out);
-                       sdl_serialize_string((*tmp)->paramName, out);
-                       WSDL_CACHE_PUT_INT((*tmp)->order, out);
-                       sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
-                       sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
-                       zend_hash_move_forward(ht);
-               }
+               ZEND_HASH_FOREACH_STR_KEY_PTR(ht, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_string(tmp->paramName, out);
+                       WSDL_CACHE_PUT_INT(tmp->order, out);
+                       sdl_serialize_encoder_ref(tmp->encode, tmp_encoders, out);
+                       sdl_serialize_type_ref(tmp->element, tmp_types, out);
+               } ZEND_HASH_FOREACH_END();
        }
 }
 
@@ -2068,42 +2055,42 @@ static void sdl_serialize_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTabl
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlSoapBindingFunctionHeaderPtr *tmp;
-               zend_hash_internal_pointer_reset(body->headers);
-               while (zend_hash_get_current_data(body->headers, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(body->headers, out);
-                       WSDL_CACHE_PUT_1((*tmp)->use, out);
-                       if ((*tmp)->use == SOAP_ENCODED) {
-                               WSDL_CACHE_PUT_1((*tmp)->encodingStyle, out);
-                       }
-                       sdl_serialize_string((*tmp)->name, out);
-                       sdl_serialize_string((*tmp)->ns, out);
-                       sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
-                       sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
-                       if ((*tmp)->headerfaults) {
-                               j = zend_hash_num_elements((*tmp)->headerfaults);
+               sdlSoapBindingFunctionHeaderPtr tmp;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(body->headers, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       WSDL_CACHE_PUT_1(tmp->use, out);
+                       if (tmp->use == SOAP_ENCODED) {
+                               WSDL_CACHE_PUT_1(tmp->encodingStyle, out);
+                       }
+                       sdl_serialize_string(tmp->name, out);
+                       sdl_serialize_string(tmp->ns, out);
+                       sdl_serialize_encoder_ref(tmp->encode, tmp_encoders, out);
+                       sdl_serialize_type_ref(tmp->element, tmp_types, out);
+                       if (tmp->headerfaults) {
+                               j = zend_hash_num_elements(tmp->headerfaults);
                        } else {
                                j = 0;
                        }
                        WSDL_CACHE_PUT_INT(j, out);
                        if (j > 0) {
-                               sdlSoapBindingFunctionHeaderPtr *tmp2;
-                               zend_hash_internal_pointer_reset((*tmp)->headerfaults);
-                               while (zend_hash_get_current_data((*tmp)->headerfaults, (void**)&tmp2) == SUCCESS) {
-                                       sdl_serialize_key((*tmp)->headerfaults, out);
-                                       WSDL_CACHE_PUT_1((*tmp2)->use, out);
-                                       if ((*tmp2)->use == SOAP_ENCODED) {
-                                               WSDL_CACHE_PUT_1((*tmp2)->encodingStyle, out);
+                               sdlSoapBindingFunctionHeaderPtr tmp2;
+                               zend_string *key;
+
+                               ZEND_HASH_FOREACH_STR_KEY_PTR(body->headers, key, tmp2) {
+                                       sdl_serialize_key(key, out);
+                                       WSDL_CACHE_PUT_1(tmp2->use, out);
+                                       if (tmp2->use == SOAP_ENCODED) {
+                                               WSDL_CACHE_PUT_1(tmp2->encodingStyle, out);
                                        }
-                                       sdl_serialize_string((*tmp2)->name, out);
-                                       sdl_serialize_string((*tmp2)->ns, out);
-                                       sdl_serialize_encoder_ref((*tmp2)->encode, tmp_encoders, out);
-                                       sdl_serialize_type_ref((*tmp2)->element, tmp_types, out);
-                                       zend_hash_move_forward((*tmp)->headerfaults);
-                               }
+                                       sdl_serialize_string(tmp2->name, out);
+                                       sdl_serialize_string(tmp2->ns, out);
+                                       sdl_serialize_encoder_ref(tmp2->encode, tmp_encoders, out);
+                                       sdl_serialize_type_ref(tmp2->element, tmp_types, out);
+                               } ZEND_HASH_FOREACH_END();
                        }
-                       zend_hash_move_forward(body->headers);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 }
 
@@ -2149,14 +2136,14 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlTypePtr *tmp;
+               sdlTypePtr tmp;
+               zval zv;
 
-               zend_hash_internal_pointer_reset(sdl->groups);
-               while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
-                       zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
+               ZEND_HASH_FOREACH_PTR(sdl->groups, tmp) {
+                       ZVAL_LONG(&zv, type_num);
+                       zend_hash_str_add(&tmp_types, (char*)&tmp, sizeof(tmp), &zv);
                        ++type_num;
-                       zend_hash_move_forward(sdl->groups);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->types) {
@@ -2166,14 +2153,14 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlTypePtr *tmp;
+               sdlTypePtr tmp;
+               zval zv;
 
-               zend_hash_internal_pointer_reset(sdl->types);
-               while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
-                       zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
+               ZEND_HASH_FOREACH_PTR(sdl->types, tmp) {
+                       ZVAL_LONG(&zv,  type_num);
+                       zend_hash_str_add(&tmp_types, (char*)&tmp, sizeof(tmp), &zv);
                        ++type_num;
-                       zend_hash_move_forward(sdl->types);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->elements) {
@@ -2183,14 +2170,14 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlTypePtr *tmp;
+               sdlTypePtr tmp;
+               zval zv;
 
-               zend_hash_internal_pointer_reset(sdl->elements);
-               while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
-                       zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
+               ZEND_HASH_FOREACH_PTR(sdl->elements, tmp) {
+                       ZVAL_LONG(&zv, type_num);
+                       zend_hash_str_add(&tmp_types, (char*)&tmp, sizeof(tmp), &zv);
                        ++type_num;
-                       zend_hash_move_forward(sdl->elements);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->encoders) {
@@ -2200,60 +2187,63 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               encodePtr *tmp;
+               encodePtr tmp;
+               zval zv;
 
-               zend_hash_internal_pointer_reset(sdl->encoders);
-               while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
-                       zend_hash_add(&tmp_encoders, (char*)tmp, sizeof(*tmp), (void**)&encoder_num, sizeof(encoder_num), NULL);
+               ZEND_HASH_FOREACH_PTR(sdl->encoders, tmp) {
+                       ZVAL_LONG(&zv, encoder_num);
+                       zend_hash_str_add(&tmp_encoders, (char*)&tmp, sizeof(tmp), &zv);
                        ++encoder_num;
-                       zend_hash_move_forward(sdl->encoders);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
        enc = defaultEncoding;
        while (enc->details.type != END_KNOWN_TYPES) {
-               zend_hash_add(&tmp_encoders, (char*)&enc, sizeof(encodePtr), (void**)&encoder_num, sizeof(encoder_num), NULL);
+               zval zv;
+
+               ZVAL_LONG(&zv, encoder_num);
+               zend_hash_str_add(&tmp_encoders, (char*)&enc, sizeof(encodePtr), &zv);
                enc++;
                ++encoder_num;
        }
 
        if (sdl->groups) {
-               sdlTypePtr *tmp;
-               zend_hash_internal_pointer_reset(sdl->groups);
-               while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(sdl->groups, out);
-                       sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
-                       zend_hash_move_forward(sdl->groups);
-               }
+               sdlTypePtr tmp;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->groups, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_type(tmp, &tmp_encoders, &tmp_types, out);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->types) {
-               sdlTypePtr *tmp;
-               zend_hash_internal_pointer_reset(sdl->types);
-               while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(sdl->types, out);
-                       sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
-                       zend_hash_move_forward(sdl->types);
-               }
+               sdlTypePtr tmp;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->types, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_type(tmp, &tmp_encoders, &tmp_types, out);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->elements) {
-               sdlTypePtr *tmp;
-               zend_hash_internal_pointer_reset(sdl->elements);
-               while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(sdl->elements, out);
-                       sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
-                       zend_hash_move_forward(sdl->elements);
-               }
+               sdlTypePtr tmp;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->elements, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_type(tmp, &tmp_encoders, &tmp_types, out);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->encoders) {
-               encodePtr *tmp;
-               zend_hash_internal_pointer_reset(sdl->encoders);
-               while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(sdl->encoders, out);
-                       sdl_serialize_encoder(*tmp, &tmp_types, out);
-                       zend_hash_move_forward(sdl->encoders);
-               }
+               encodePtr tmp;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->encoders, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_encoder(tmp, &tmp_types, out);
+               } ZEND_HASH_FOREACH_END();
        }
 
        /* serialize bindings */
@@ -2264,74 +2254,77 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlBindingPtr *tmp;
+               sdlBindingPtr tmp;
                int binding_num = 1;
-
-               zend_hash_internal_pointer_reset(sdl->bindings);
-               while (zend_hash_get_current_data(sdl->bindings, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(sdl->bindings, out);
-                       sdl_serialize_string((*tmp)->name, out);
-                       sdl_serialize_string((*tmp)->location, out);
-                       WSDL_CACHE_PUT_1((*tmp)->bindingType,out);
-                       if ((*tmp)->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
-                               sdlSoapBindingPtr binding = (sdlSoapBindingPtr)(*tmp)->bindingAttributes;
+               zval zv;
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->bindings, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_string(tmp->name, out);
+                       sdl_serialize_string(tmp->location, out);
+                       WSDL_CACHE_PUT_1(tmp->bindingType,out);
+                       if (tmp->bindingType == BINDING_SOAP && tmp->bindingAttributes != NULL) {
+                               sdlSoapBindingPtr binding = (sdlSoapBindingPtr)tmp->bindingAttributes;
                                WSDL_CACHE_PUT_1(binding->style, out);
                                WSDL_CACHE_PUT_1(binding->transport, out);
                        } else {
                                WSDL_CACHE_PUT_1(0,out);
                        }
 
-                       zend_hash_add(&tmp_bindings, (char*)tmp, sizeof(*tmp), (void**)&binding_num, sizeof(binding_num), NULL);
+                       ZVAL_LONG(&zv, binding_num);
+                       zend_hash_str_add(&tmp_bindings, (char*)&tmp, sizeof(tmp), &zv);
                        binding_num++;
-                       zend_hash_move_forward(sdl->bindings);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        /* serialize functions */
        i = zend_hash_num_elements(&sdl->functions);
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlFunctionPtr *tmp;
-               int *binding_num;
+               sdlFunctionPtr tmp;
+               zval *binding_num, zv;
                int function_num = 1;
-
-               zend_hash_internal_pointer_reset(&sdl->functions);
-               while (zend_hash_get_current_data(&sdl->functions, (void**)&tmp) == SUCCESS) {
-                       sdl_serialize_key(&sdl->functions, out);
-                       sdl_serialize_string((*tmp)->functionName, out);
-                       sdl_serialize_string((*tmp)->requestName, out);
-                       sdl_serialize_string((*tmp)->responseName, out);
-
-                       if ((*tmp)->binding == NULL ||
-                           zend_hash_find(&tmp_bindings,(char*)&(*tmp)->binding,sizeof((*tmp)->binding), (void**)&binding_num) != SUCCESS) {
-                       }
-                       WSDL_CACHE_PUT_INT(*binding_num, out);
-                       if (*binding_num >= 0) {
-                               if ((*tmp)->binding->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
-                                       sdlSoapBindingFunctionPtr binding = (sdlSoapBindingFunctionPtr)(*tmp)->bindingAttributes;
-                                       WSDL_CACHE_PUT_1(binding->style, out);
-                                       sdl_serialize_string(binding->soapAction, out);
-                                       sdl_serialize_soap_body(&binding->input, &tmp_encoders, &tmp_types, out);
-                                       sdl_serialize_soap_body(&binding->output, &tmp_encoders, &tmp_types, out);
-                               } else {
-                                       WSDL_CACHE_PUT_1(0,out);
+               zend_string *key;
+
+               ZEND_HASH_FOREACH_STR_KEY_PTR(&sdl->functions, key, tmp) {
+                       sdl_serialize_key(key, out);
+                       sdl_serialize_string(tmp->functionName, out);
+                       sdl_serialize_string(tmp->requestName, out);
+                       sdl_serialize_string(tmp->responseName, out);
+
+                       if (tmp->binding) {
+                               binding_num = zend_hash_str_find(&tmp_bindings,(char*)&tmp->binding, sizeof(tmp->binding));
+                               if (binding_num) {
+                                       WSDL_CACHE_PUT_INT(Z_LVAL_P(binding_num), out);
+                                       if (Z_LVAL_P(binding_num) >= 0) {
+                                               if (tmp->binding->bindingType == BINDING_SOAP && tmp->bindingAttributes != NULL) {
+                                                       sdlSoapBindingFunctionPtr binding = (sdlSoapBindingFunctionPtr)tmp->bindingAttributes;
+                                                       WSDL_CACHE_PUT_1(binding->style, out);
+                                                       sdl_serialize_string(binding->soapAction, out);
+                                                       sdl_serialize_soap_body(&binding->input, &tmp_encoders, &tmp_types, out);
+                                                       sdl_serialize_soap_body(&binding->output, &tmp_encoders, &tmp_types, out);
+                                               } else {
+                                                       WSDL_CACHE_PUT_1(0,out);
+                                               }
+                                       }
                                }
                        }
-                       sdl_serialize_parameters((*tmp)->requestParameters, &tmp_encoders, &tmp_types, out);
-                       sdl_serialize_parameters((*tmp)->responseParameters, &tmp_encoders, &tmp_types, out);
+                       sdl_serialize_parameters(tmp->requestParameters, &tmp_encoders, &tmp_types, out);
+                       sdl_serialize_parameters(tmp->responseParameters, &tmp_encoders, &tmp_types, out);
 
-                       if ((*tmp)->faults) {
-                               sdlFaultPtr *fault;
+                       if (tmp->faults) {
+                               sdlFaultPtr fault;
+                               zend_string *key;
 
-                               WSDL_CACHE_PUT_INT(zend_hash_num_elements((*tmp)->faults), out);
+                               WSDL_CACHE_PUT_INT(zend_hash_num_elements(tmp->faults), out);
 
-                               zend_hash_internal_pointer_reset((*tmp)->faults);
-                               while (zend_hash_get_current_data((*tmp)->faults, (void**)&fault) == SUCCESS) {
-                                       sdl_serialize_key((*tmp)->faults, out);
-                                       sdl_serialize_string((*fault)->name, out);
-                                       sdl_serialize_parameters((*fault)->details, &tmp_encoders, &tmp_types, out);
-                                       if ((*tmp)->binding->bindingType == BINDING_SOAP && (*fault)->bindingAttributes != NULL) {
-                                               sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)(*fault)->bindingAttributes;
+                               ZEND_HASH_FOREACH_STR_KEY_PTR(tmp->faults, key, fault) {
+                                       sdl_serialize_key(key, out);
+                                       sdl_serialize_string(fault->name, out);
+                                       sdl_serialize_parameters(fault->details, &tmp_encoders, &tmp_types, out);
+                                       if (tmp->binding->bindingType == BINDING_SOAP && fault->bindingAttributes != NULL) {
+                                               sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
                                                WSDL_CACHE_PUT_1(binding->use, out);
                                                if (binding->use == SOAP_ENCODED) {
                                                        WSDL_CACHE_PUT_1(binding->encodingStyle, out);
@@ -2340,16 +2333,15 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
                                        } else {
                                                WSDL_CACHE_PUT_1(0, out);
                                        }
-                                       zend_hash_move_forward((*tmp)->faults);
-                               }
+                               } ZEND_HASH_FOREACH_END();
                        } else {
                                WSDL_CACHE_PUT_INT(0, out);
                        }
 
-                       zend_hash_add(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num, sizeof(function_num), NULL);
+                       ZVAL_LONG(&zv, function_num);
+                       zend_hash_str_add(&tmp_functions, (char*)&tmp, sizeof(tmp), &zv);
                        function_num++;
-                       zend_hash_move_forward(&sdl->functions);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        /* serialize requests */
@@ -2360,20 +2352,18 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
        }
        WSDL_CACHE_PUT_INT(i, out);
        if (i > 0) {
-               sdlFunctionPtr *tmp;
-               int *function_num;
+               sdlFunctionPtr tmp;
+               zval *function_num;
+               zend_string *key;
 
-               zend_hash_internal_pointer_reset(sdl->requests);
-               while (zend_hash_get_current_data(sdl->requests, (void**)&tmp) == SUCCESS) {
-                       if (zend_hash_find(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num) != SUCCESS) {
-                       }
-                       WSDL_CACHE_PUT_INT(*function_num, out);
-                       sdl_serialize_key(sdl->requests, out);
-                       zend_hash_move_forward(sdl->requests);
-               }
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->requests, key, tmp) {
+                       function_num = zend_hash_str_find(&tmp_functions, (char*)&tmp, sizeof(tmp));
+                       WSDL_CACHE_PUT_INT(Z_LVAL_P(function_num), out);
+                       sdl_serialize_key(key, out);
+               } ZEND_HASH_FOREACH_END();
        }
 
-       php_ignore_value(write(f, buf.c, buf.len));
+       php_ignore_value(write(f, buf.s->val, buf.s->len));
        close(f);
        smart_str_free(&buf);
        zend_hash_destroy(&tmp_functions);
@@ -2394,9 +2384,8 @@ static void make_persistent_restriction_int(void *data)
 }
 
 
-static void make_persistent_restriction_char(void *data)
+static void make_persistent_restriction_char_int(sdlRestrictionCharPtr *rest)
 {
-       sdlRestrictionCharPtr *rest = (sdlRestrictionCharPtr *)data;
        sdlRestrictionCharPtr prest = NULL;
 
        prest = malloc(sizeof(sdlRestrictionChar));
@@ -2407,31 +2396,37 @@ static void make_persistent_restriction_char(void *data)
 }
 
 
+static void make_persistent_restriction_char(zval *zv)
+{
+       make_persistent_restriction_char_int((sdlRestrictionCharPtr*)&Z_PTR_P(zv));
+}
+
+
 static void make_persistent_sdl_type_ref(sdlTypePtr *type, HashTable *ptr_map, HashTable *bp_types)
 {
-       sdlTypePtr *tmp;
+       sdlTypePtr tmp;
 
-       if (zend_hash_find(ptr_map, (char *)type, sizeof(sdlTypePtr), (void**)&tmp) == SUCCESS) {
-               *type = *tmp;
+       if ((tmp = zend_hash_str_find_ptr(ptr_map, (char *)type, sizeof(sdlTypePtr))) != NULL) {
+               *type = tmp;
        } else {
-               zend_hash_next_index_insert(bp_types, (void*)&type, sizeof(sdlTypePtr*), NULL);
+               zend_hash_next_index_insert_ptr(bp_types, *type);
        }
 }
 
 
 static void make_persistent_sdl_encoder_ref(encodePtr *enc, HashTable *ptr_map, HashTable *bp_encoders)
 {
-       encodePtr *tmp;
+       encodePtr tmp;
 
        /* do not process defaultEncoding's here */
        if ((*enc) >= defaultEncoding && (*enc) < defaultEncoding + numDefaultEncodings) {
                return;
        }
 
-       if (zend_hash_find(ptr_map, (char *)enc, sizeof(encodePtr), (void**)&tmp) == SUCCESS) {
-               *enc = *tmp;
+       if ((tmp = zend_hash_str_find_ptr(ptr_map, (char *)enc, sizeof(encodePtr))) != NULL) {
+               *enc = tmp;
        } else {
-               zend_hash_next_index_insert(bp_encoders, (void*)&enc, sizeof(encodePtr*), NULL);
+               zend_hash_next_index_insert_ptr(bp_encoders, *enc);
        }
 }
 
@@ -2439,21 +2434,18 @@ static void make_persistent_sdl_encoder_ref(encodePtr *enc, HashTable *ptr_map,
 static HashTable* make_persistent_sdl_function_headers(HashTable *headers, HashTable *ptr_map)
 {
        HashTable *pheaders;
-       sdlSoapBindingFunctionHeaderPtr *tmp, pheader;
-       encodePtr *penc;
-       sdlTypePtr *ptype;
-       ulong index;
-       char *key;
-       uint key_len;
+       sdlSoapBindingFunctionHeaderPtr tmp, pheader;
+       encodePtr penc;
+       sdlTypePtr ptype;
+       zend_string *key;
 
        pheaders = malloc(sizeof(HashTable));
        zend_hash_init(pheaders, zend_hash_num_elements(headers), NULL, delete_header_persistent, 1);
 
-       zend_hash_internal_pointer_reset(headers);
-       while (zend_hash_get_current_data(headers, (void**)&tmp) == SUCCESS) {
+       ZEND_HASH_FOREACH_STR_KEY_PTR(headers, key, tmp) {
                pheader = malloc(sizeof(sdlSoapBindingFunctionHeader));
                memset(pheader, 0, sizeof(sdlSoapBindingFunctionHeader));
-               *pheader = **tmp;
+               *pheader = *tmp;
 
                if (pheader->name) {
                        pheader->name = strdup(pheader->name);
@@ -2463,30 +2455,28 @@ static HashTable* make_persistent_sdl_function_headers(HashTable *headers, HashT
                }
 
                if (pheader->encode->details.sdl_type) {
-                       if (zend_hash_find(ptr_map, (char*)&pheader->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
+                       if ((penc = zend_hash_str_find_ptr(ptr_map, (char*)&pheader->encode, sizeof(encodePtr))) == NULL) {
                                assert(0);
                        }
-                       pheader->encode = *penc;
+                       pheader->encode = penc;
                }
                if (pheader->element) {
-                       if (zend_hash_find(ptr_map, (char*)&pheader->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
+                       if ((ptype = zend_hash_str_find_ptr(ptr_map, (char*)&pheader->element, sizeof(sdlTypePtr))) == NULL) {
                                assert(0);
                        }
-                       pheader->element = *ptype;
+                       pheader->element = ptype;
                }
 
                if (pheader->headerfaults) {
                        pheader->headerfaults = make_persistent_sdl_function_headers(pheader->headerfaults, ptr_map);
                }
 
-               if (zend_hash_get_current_key_ex(headers, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                       zend_hash_add(pheaders, key, key_len, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
+               if (key) {
+                       zend_hash_add_ptr(pheaders, key, pheader);
                } else {
-                       zend_hash_next_index_insert(pheaders, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
+                       zend_hash_next_index_insert_ptr(pheaders, pheader);
                }
-
-               zend_hash_move_forward(headers);
-       }
+       } ZEND_HASH_FOREACH_END();
 
        return pheaders;
 }
@@ -2507,48 +2497,42 @@ static void make_persistent_sdl_soap_body(sdlSoapBindingFunctionBodyPtr body, Ha
 static HashTable* make_persistent_sdl_parameters(HashTable *params, HashTable *ptr_map)
 {
        HashTable *pparams;
-       sdlParamPtr *tmp, pparam;
-       sdlTypePtr *ptype;
-       encodePtr *penc;
-       ulong index;
-       char *key;
-       uint key_len;
+       sdlParamPtr tmp, pparam;
+       sdlTypePtr ptype;
+       encodePtr penc;
+       zend_string *key;
 
        pparams = malloc(sizeof(HashTable));
        zend_hash_init(pparams, zend_hash_num_elements(params), NULL, delete_parameter_persistent, 1);
 
-       zend_hash_internal_pointer_reset(params);
-       while (zend_hash_get_current_data(params, (void**)&tmp) == SUCCESS) {
+       ZEND_HASH_FOREACH_STR_KEY_PTR(params, key, tmp) {
                pparam = malloc(sizeof(sdlParam));
                memset(pparam, 0, sizeof(sdlParam));
-               *pparam = **tmp;
+               *pparam = *tmp;
 
                if (pparam->paramName) {
                        pparam->paramName = strdup(pparam->paramName);
                }
 
                if (pparam->encode && pparam->encode->details.sdl_type) {
-                       if (zend_hash_find(ptr_map, (char*)&pparam->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
+                       if ((penc = zend_hash_str_find_ptr(ptr_map, (char*)&pparam->encode, sizeof(encodePtr))) == NULL) {
                                assert(0);
                        }
-                       pparam->encode = *penc;
+                       pparam->encode = penc;
                }
                if (pparam->element) {
-                       if (zend_hash_find(ptr_map, (char*)&pparam->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
+                       if ((ptype = zend_hash_str_find_ptr(ptr_map, (char*)&pparam->element, sizeof(sdlTypePtr))) == NULL) {
                                assert(0);
                        }
-                       pparam->element = *ptype;
+                       pparam->element = ptype;
                }
 
-               if (zend_hash_get_current_key_ex(params, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                       zend_hash_add(pparams, key, key_len, (void*)&pparam, sizeof(sdlParamPtr), NULL);
+               if (key) {
+                       zend_hash_add_ptr(pparams, key, pparam);
                } else {
-                       zend_hash_next_index_insert(pparams, (void*)&pparam, sizeof(sdlParamPtr), NULL);
+                       zend_hash_next_index_insert_ptr(pparams, pparam);
                }
-
-               zend_hash_move_forward(params);
-       }
-
+       } ZEND_HASH_FOREACH_END();
 
        return pparams;
 }
@@ -2556,19 +2540,16 @@ static HashTable* make_persistent_sdl_parameters(HashTable *params, HashTable *p
 static HashTable* make_persistent_sdl_function_faults(sdlFunctionPtr func, HashTable *faults, HashTable *ptr_map)
 {
        HashTable *pfaults;
-       sdlFaultPtr  *tmp, pfault;
-       ulong index;
-       char *key;
-       uint key_len;
+       sdlFaultPtr tmp, pfault;
+       zend_string *key;
 
        pfaults = malloc(sizeof(HashTable));
        zend_hash_init(pfaults, zend_hash_num_elements(faults), NULL, delete_fault_persistent, 1);
 
-       zend_hash_internal_pointer_reset(faults);
-       while (zend_hash_get_current_data(faults, (void**)&tmp) == SUCCESS) {
+       ZEND_HASH_FOREACH_STR_KEY_PTR(faults, key, tmp) {
                pfault = malloc(sizeof(sdlFault));
                memset(pfault, 0, sizeof(sdlFault));
-               *pfault = **tmp;
+               *pfault = *tmp;
 
                if (pfault->name) {
                        pfault->name = strdup(pfault->name);
@@ -2589,15 +2570,13 @@ static HashTable* make_persistent_sdl_function_faults(sdlFunctionPtr func, HashT
                        pfault->bindingAttributes = soap_binding;
                }
 
-               if (zend_hash_get_current_key_ex(faults, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                       zend_hash_add(pfaults, key, key_len, (void*)&pfault, sizeof(sdlParamPtr), NULL);
+               if (key) {
+                       zend_hash_add_ptr(pfaults, key, pfault);
                } else {
-                       zend_hash_next_index_insert(pfaults, (void*)&pfault, sizeof(sdlParamPtr), NULL);
+                       zend_hash_next_index_insert_ptr(pfaults, pfault);
                }
 
-               zend_hash_move_forward(faults);
-       }
-
+       } ZEND_HASH_FOREACH_END();
 
        return pfaults;
 }
@@ -2606,9 +2585,7 @@ static HashTable* make_persistent_sdl_function_faults(sdlFunctionPtr func, HashT
 static sdlAttributePtr make_persistent_sdl_attribute(sdlAttributePtr attr, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
 {
        sdlAttributePtr pattr;
-       ulong index;
-       char *key;
-       uint key_len;
+       zend_string *key;
 
        pattr = malloc(sizeof(sdlAttribute));
        memset(pattr, 0, sizeof(sdlAttribute));
@@ -2637,29 +2614,26 @@ static sdlAttributePtr make_persistent_sdl_attribute(sdlAttributePtr attr, HashT
        }
 
        if (pattr->extraAttributes) {
-               sdlExtraAttributePtr *tmp, pextra;
+               sdlExtraAttributePtr tmp, pextra;
 
                pattr->extraAttributes = malloc(sizeof(HashTable));
                zend_hash_init(pattr->extraAttributes, zend_hash_num_elements(attr->extraAttributes), NULL, delete_extra_attribute_persistent, 1);
 
-               zend_hash_internal_pointer_reset(pattr->extraAttributes);
-               while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
-                       if (zend_hash_get_current_key_ex(attr->extraAttributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {                       
+               ZEND_HASH_FOREACH_STR_KEY_PTR(pattr->extraAttributes, key, tmp) {
+                       if (key) {
                                pextra = malloc(sizeof(sdlExtraAttribute));
                                memset(pextra, 0, sizeof(sdlExtraAttribute));
 
-                               if ((*tmp)->ns) {
-                                       pextra->ns = strdup((*tmp)->ns);
+                               if (tmp->ns) {
+                                       pextra->ns = strdup(tmp->ns);
                                }
-                               if ((*tmp)->val) {
-                                       pextra->val = strdup((*tmp)->val);
+                               if (tmp->val) {
+                                       pextra->val = strdup(tmp->val);
                                }
                        
-                               zend_hash_add(pattr->extraAttributes, key, key_len, (void*)&pextra, sizeof(sdlExtraAttributePtr), NULL);
+                               zend_hash_add_ptr(pattr->extraAttributes, key, pextra);
                        }
-
-                       zend_hash_move_forward(attr->extraAttributes);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        return pattr;
@@ -2669,7 +2643,7 @@ static sdlAttributePtr make_persistent_sdl_attribute(sdlAttributePtr attr, HashT
 static sdlContentModelPtr make_persistent_sdl_model(sdlContentModelPtr model, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
 {
        sdlContentModelPtr pmodel;
-       sdlContentModelPtr *tmp, pcontent;
+       sdlContentModelPtr tmp, pcontent;
 
        pmodel = malloc(sizeof(sdlContentModel));
        memset(pmodel, 0, sizeof(sdlContentModel));
@@ -2688,12 +2662,10 @@ static sdlContentModelPtr make_persistent_sdl_model(sdlContentModelPtr model, Ha
                        pmodel->u.content = malloc(sizeof(HashTable));
                        zend_hash_init(pmodel->u.content, zend_hash_num_elements(model->u.content), NULL, delete_model_persistent, 1);
 
-                       zend_hash_internal_pointer_reset(model->u.content);
-                       while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
-                               pcontent = make_persistent_sdl_model(*tmp, ptr_map, bp_types, bp_encoders);
-                               zend_hash_next_index_insert(pmodel->u.content, (void*)&pcontent, sizeof(sdlContentModelPtr), NULL);
-                               zend_hash_move_forward(model->u.content);
-                       }
+                       ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                               pcontent = make_persistent_sdl_model(tmp, ptr_map, bp_types, bp_encoders);
+                               zend_hash_next_index_insert_ptr(pmodel->u.content, pcontent);
+                       } ZEND_HASH_FOREACH_END();
                        break;
 
                case XSD_CONTENT_GROUP_REF:
@@ -2718,9 +2690,7 @@ static sdlContentModelPtr make_persistent_sdl_model(sdlContentModelPtr model, Ha
 
 static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
 {
-       ulong index;
-       char *key;
-       uint key_len;
+       zend_string *key;
        sdlTypePtr ptype = NULL;
 
        ptype = malloc(sizeof(sdlType));
@@ -2782,56 +2752,50 @@ static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map,
                        make_persistent_restriction_int(&ptype->restrictions->maxLength);
                }
                if (ptype->restrictions->whiteSpace) {
-                       make_persistent_restriction_char(&ptype->restrictions->whiteSpace);
+                       make_persistent_restriction_char_int(&ptype->restrictions->whiteSpace);
                }
                if (ptype->restrictions->pattern) {
-                       make_persistent_restriction_char(&ptype->restrictions->pattern);
+                       make_persistent_restriction_char_int(&ptype->restrictions->pattern);
                }
 
                if (type->restrictions->enumeration) {
-                       sdlRestrictionCharPtr tmp;
-
                        ptype->restrictions->enumeration = malloc(sizeof(HashTable));
                        zend_hash_init(ptype->restrictions->enumeration, zend_hash_num_elements(type->restrictions->enumeration), NULL, delete_restriction_var_char_persistent, 1);
-                       zend_hash_copy(ptype->restrictions->enumeration, type->restrictions->enumeration, make_persistent_restriction_char, (void*)&tmp, sizeof(sdlRestrictionCharPtr));
+                       zend_hash_copy(ptype->restrictions->enumeration, type->restrictions->enumeration, make_persistent_restriction_char);
                }
        }
 
        if (ptype->elements) {
-               sdlTypePtr *tmp, pelem;
+               sdlTypePtr tmp, pelem;
 
                ptype->elements = malloc(sizeof(HashTable));
                zend_hash_init(ptype->elements, zend_hash_num_elements(type->elements), NULL, delete_type_persistent, 1);
 
-               zend_hash_internal_pointer_reset(type->elements);
-               while (zend_hash_get_current_data(type->elements, (void **)&tmp) == SUCCESS) {
-                       pelem = make_persistent_sdl_type(*tmp, ptr_map, bp_types, bp_encoders);
-                       if (zend_hash_get_current_key_ex(type->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(ptype->elements, key, key_len, (void*)&pelem, sizeof(sdlTypePtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(type->elements, key, tmp) {
+                       pelem = make_persistent_sdl_type(tmp, ptr_map, bp_types, bp_encoders);
+                       if (key) {
+                               zend_hash_add_ptr(ptype->elements, key, pelem);
                        } else {
-                               zend_hash_next_index_insert(ptype->elements, (void*)&pelem, sizeof(sdlTypePtr), NULL);
+                               zend_hash_next_index_insert_ptr(ptype->elements, pelem);
                        }
-                       zend_hash_add(ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pelem, sizeof(sdlTypePtr), NULL);
-                       zend_hash_move_forward(type->elements);
-               }
+                       zend_hash_str_add_ptr(ptr_map, (char*)&tmp, sizeof(tmp), pelem);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (ptype->attributes) {
-               sdlAttributePtr *tmp, pattr;
+               sdlAttributePtr tmp, pattr;
 
                ptype->attributes = malloc(sizeof(HashTable));
                zend_hash_init(ptype->attributes, zend_hash_num_elements(type->attributes), NULL, delete_attribute_persistent, 1);
 
-               zend_hash_internal_pointer_reset(type->attributes);
-               while (zend_hash_get_current_data(type->attributes, (void **)&tmp) == SUCCESS) {
-                       pattr = make_persistent_sdl_attribute(*tmp, ptr_map, bp_types, bp_encoders);
-                       if (zend_hash_get_current_key_ex(type->attributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(ptype->attributes, key, key_len, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(type->attributes, key, tmp) {
+                       pattr = make_persistent_sdl_attribute(tmp, ptr_map, bp_types, bp_encoders);
+                       if (key) {
+                               zend_hash_add_ptr(ptype->attributes, key, pattr);
                        } else {
-                               zend_hash_next_index_insert(ptype->attributes, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
+                               zend_hash_next_index_insert_ptr(ptype->attributes, pattr);
                        }
-                       zend_hash_move_forward(type->attributes);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (type->model) {
@@ -2912,12 +2876,12 @@ static sdlFunctionPtr make_persistent_sdl_function(sdlFunctionPtr func, HashTabl
        }
 
        if (pfunc->binding) {
-               sdlBindingPtr *tmp;
+               sdlBindingPtr tmp;
 
-               if (zend_hash_find(ptr_map, (char*)&pfunc->binding, sizeof(pfunc->binding), (void**)&tmp) == FAILURE) {
+               if ((tmp = zend_hash_str_find_ptr(ptr_map, (char*)&pfunc->binding, sizeof(pfunc->binding))) == NULL) {
                        assert(0);
                }
-               pfunc->binding = *tmp;
+               pfunc->binding = tmp;
                
                if (pfunc->binding->bindingType == BINDING_SOAP && pfunc->bindingAttributes) {
                        sdlSoapBindingFunctionPtr soap_binding;
@@ -2952,9 +2916,7 @@ static sdlPtr make_persistent_sdl(sdlPtr sdl TSRMLS_DC)
        sdlPtr psdl = NULL;
        HashTable ptr_map;
        HashTable bp_types, bp_encoders;
-       ulong index;
-       char *key;
-       uint key_len;
+       zend_string *key;
 
        zend_hash_init(&bp_types, 0, NULL, NULL, 0);
        zend_hash_init(&bp_encoders, 0, NULL, NULL, 0);
@@ -2971,168 +2933,153 @@ static sdlPtr make_persistent_sdl(sdlPtr sdl TSRMLS_DC)
        }
 
        if (sdl->groups) {
-               sdlTypePtr *tmp;
+               sdlTypePtr tmp;
                sdlTypePtr ptype;
 
                psdl->groups = malloc(sizeof(HashTable));
                zend_hash_init(psdl->groups, zend_hash_num_elements(sdl->groups), NULL, delete_type_persistent, 1);
 
-               zend_hash_internal_pointer_reset(sdl->groups);
-               while (zend_hash_get_current_data(sdl->groups, (void **)&tmp) == SUCCESS) {
-                       ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
-                       if (zend_hash_get_current_key_ex(sdl->groups, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(psdl->groups, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->groups, key, tmp) {
+                       ptype = make_persistent_sdl_type(tmp, &ptr_map, &bp_types, &bp_encoders);
+                       if (key) {
+                               zend_hash_add_ptr(psdl->groups, key, ptype);
                        } else {
-                               zend_hash_next_index_insert(psdl->groups, (void*)&ptype, sizeof(sdlTypePtr), NULL);
+                               zend_hash_next_index_insert_ptr(psdl->groups, ptype);
                        }
-                       zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
-                       zend_hash_move_forward(sdl->groups);
-               }
+                       zend_hash_str_add_ptr(&ptr_map, (char*)&tmp, sizeof(tmp), ptype);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->types) {
-               sdlTypePtr *tmp;
+               sdlTypePtr tmp;
                sdlTypePtr ptype;
 
                psdl->types = malloc(sizeof(HashTable));
                zend_hash_init(psdl->types, zend_hash_num_elements(sdl->types), NULL, delete_type_persistent, 1);
 
-               zend_hash_internal_pointer_reset(sdl->types);
-               while (zend_hash_get_current_data(sdl->types, (void **)&tmp) == SUCCESS) {
-                       ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
-                       if (zend_hash_get_current_key_ex(sdl->types, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(psdl->types, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->types, key, tmp) {
+                       ptype = make_persistent_sdl_type(tmp, &ptr_map, &bp_types, &bp_encoders);
+                       if (key) {
+                               zend_hash_add_ptr(psdl->types, key, ptype);
                        } else {
-                               zend_hash_next_index_insert(psdl->types, (void*)&ptype, sizeof(sdlTypePtr), NULL);
+                               zend_hash_next_index_insert_ptr(psdl->types, ptype);
                        }
-                       zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
-                       zend_hash_move_forward(sdl->types);
-               }
+                       zend_hash_str_add_ptr(&ptr_map, (char*)&tmp, sizeof(tmp), ptype);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->elements) {
-               sdlTypePtr *tmp;
+               sdlTypePtr tmp;
                sdlTypePtr ptype;
 
                psdl->elements = malloc(sizeof(HashTable));
                zend_hash_init(psdl->elements, zend_hash_num_elements(sdl->elements), NULL, delete_type_persistent, 1);
 
-               zend_hash_internal_pointer_reset(sdl->elements);
-               while (zend_hash_get_current_data(sdl->elements, (void **)&tmp) == SUCCESS) {
-                       ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
-                       if (zend_hash_get_current_key_ex(sdl->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(psdl->elements, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->elements, key, tmp) {
+                       ptype = make_persistent_sdl_type(tmp, &ptr_map, &bp_types, &bp_encoders);
+                       if (key) {
+                               zend_hash_add_ptr(psdl->elements, key, ptype);
                        } else {
-                               zend_hash_next_index_insert(psdl->elements, (void*)&ptype, sizeof(sdlTypePtr), NULL);
+                               zend_hash_next_index_insert_ptr(psdl->elements, ptype);
                        }
-                       zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
-                       zend_hash_move_forward(sdl->elements);
-               }
+                       zend_hash_str_add_ptr(&ptr_map, (char*)&tmp, sizeof(tmp), ptype);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->encoders) {
-               encodePtr *tmp;
+               encodePtr tmp;
                encodePtr penc;
 
                psdl->encoders = malloc(sizeof(HashTable));
                zend_hash_init(psdl->encoders, zend_hash_num_elements(sdl->encoders), NULL, delete_encoder_persistent, 1);
 
-               zend_hash_internal_pointer_reset(sdl->encoders);
-               while (zend_hash_get_current_data(sdl->encoders, (void **)&tmp) == SUCCESS) {
-                       penc = make_persistent_sdl_encoder(*tmp, &ptr_map, &bp_types, &bp_encoders);
-                       if (zend_hash_get_current_key_ex(sdl->encoders, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(psdl->encoders, key, key_len, (void*)&penc, sizeof(encodePtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->encoders, key, tmp) {
+                       penc = make_persistent_sdl_encoder(tmp, &ptr_map, &bp_types, &bp_encoders);
+                       if (key) {
+                               zend_hash_add_ptr(psdl->encoders, key, penc);
                        } else {
-                               zend_hash_next_index_insert(psdl->encoders, (void*)&penc, sizeof(encodePtr), NULL);
+                               zend_hash_next_index_insert_ptr(psdl->encoders, penc);
                        }
-                       zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&penc, sizeof(encodePtr), NULL);
-                       zend_hash_move_forward(sdl->encoders);
-               }
+                       zend_hash_str_add_ptr(&ptr_map, (char*)&tmp, sizeof(tmp), penc);
+               } ZEND_HASH_FOREACH_END();
        }
 
        /* do backpatching here */
        if (zend_hash_num_elements(&bp_types)) {
-               sdlTypePtr **tmp, *ptype = NULL;
+               sdlTypePtr *tmp, ptype = NULL;
 
-               zend_hash_internal_pointer_reset(&bp_types);
-               while (zend_hash_get_current_data(&bp_types, (void**)&tmp) == SUCCESS) {
-                       if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&ptype) == FAILURE) {
+               ZEND_HASH_FOREACH_PTR(&bp_types, tmp) {
+                       if ((ptype = zend_hash_str_find_ptr(&ptr_map, (char*)tmp, sizeof(*tmp))) == NULL) {
                                assert(0);
                        }
-                       **tmp = *ptype;
-                       zend_hash_move_forward(&bp_types);
-               }
+                       *tmp = ptype;
+               } ZEND_HASH_FOREACH_END();
        }
        if (zend_hash_num_elements(&bp_encoders)) {
-               encodePtr **tmp, *penc = NULL;
+               encodePtr *tmp, penc = NULL;
 
-               zend_hash_internal_pointer_reset(&bp_encoders);
-               while (zend_hash_get_current_data(&bp_encoders, (void**)&tmp) == SUCCESS) {
-                       if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&penc) == FAILURE) {
+               ZEND_HASH_FOREACH_PTR(&bp_encoders, tmp) {
+                       if ((penc = zend_hash_str_find_ptr(&ptr_map, (char*)tmp, sizeof(*tmp))) == NULL) {
                                assert(0);
                        }
-                       **tmp = *penc;
-                       zend_hash_move_forward(&bp_encoders);
-               }
+                       *tmp = penc;
+               } ZEND_HASH_FOREACH_END();
        }
 
 
        if (sdl->bindings) {
-               sdlBindingPtr *tmp;
+               sdlBindingPtr tmp;
                sdlBindingPtr pbind;
 
                psdl->bindings = malloc(sizeof(HashTable));
                zend_hash_init(psdl->bindings, zend_hash_num_elements(sdl->bindings), NULL, delete_binding_persistent, 1);
 
-               zend_hash_internal_pointer_reset(sdl->bindings);
-               while (zend_hash_get_current_data(sdl->bindings, (void **)&tmp) == SUCCESS) {
-                       pbind = make_persistent_sdl_binding(*tmp, &ptr_map);
-                       if (zend_hash_get_current_key_ex(sdl->bindings, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(psdl->bindings, key, key_len, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(sdl->bindings, key, tmp) {
+                       pbind = make_persistent_sdl_binding(tmp, &ptr_map);
+                       if (key) {
+                               zend_hash_add_ptr(psdl->bindings, key, pbind);
                        } else {
-                               zend_hash_next_index_insert(psdl->bindings, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
+                               zend_hash_next_index_insert_ptr(psdl->bindings, pbind);
                        }
-                       zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pbind, sizeof(sdlBindingPtr), NULL);
-                       zend_hash_move_forward(sdl->bindings);
-               }
+                       zend_hash_str_add_ptr(&ptr_map, (char*)&tmp, sizeof(tmp), pbind);
+               } ZEND_HASH_FOREACH_END();
        }
 
        zend_hash_init(&psdl->functions, zend_hash_num_elements(&sdl->functions), NULL, delete_function_persistent, 1);
        if (zend_hash_num_elements(&sdl->functions)) {
-               sdlFunctionPtr *tmp;
+               sdlFunctionPtr tmp;
                sdlFunctionPtr pfunc;
 
-               zend_hash_internal_pointer_reset(&sdl->functions);
-               while (zend_hash_get_current_data(&sdl->functions, (void **)&tmp) == SUCCESS) {
-                       pfunc = make_persistent_sdl_function(*tmp, &ptr_map);
-                       if (zend_hash_get_current_key_ex(&sdl->functions, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(&psdl->functions, key, key_len, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
+               ZEND_HASH_FOREACH_STR_KEY_PTR(&sdl->functions, key, tmp) {
+                       pfunc = make_persistent_sdl_function(tmp, &ptr_map);
+                       if (key) {
+                               zend_hash_add_ptr(&psdl->functions, key, pfunc);
                        } else {
-                               zend_hash_next_index_insert(&psdl->functions, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
+                               zend_hash_next_index_insert_ptr(&psdl->functions, pfunc);
                        }
-                       zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
-                       zend_hash_move_forward(&sdl->functions);
-               }
+                       zend_hash_str_add_ptr(&ptr_map, (char*)&tmp, sizeof(tmp), pfunc);
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (sdl->requests) {
-               sdlFunctionPtr *tmp;
-               sdlFunctionPtr *preq;
+               zval *zv;
+               sdlFunctionPtr tmp;
+               sdlFunctionPtr preq;
 
                psdl->requests = malloc(sizeof(HashTable));
                zend_hash_init(psdl->requests, zend_hash_num_elements(sdl->requests), NULL, NULL, 1);
 
-               zend_hash_internal_pointer_reset(sdl->requests);
-               while (zend_hash_get_current_data(sdl->requests, (void **)&tmp) == SUCCESS) {
-                       if (zend_hash_find(&ptr_map, (char*)tmp, sizeof(*tmp), (void**)&preq) == FAILURE) {
+               ZEND_HASH_FOREACH_STR_KEY_VAL(sdl->requests, key, zv) {
+                       tmp = Z_PTR_P(zv);
+                       if ((preq = zend_hash_str_find_ptr(&ptr_map, (char*)&tmp, sizeof(tmp))) == NULL) {
                                assert(0);
                        }
-                       *tmp = *preq;
-                       if (zend_hash_get_current_key_ex(sdl->requests, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
-                               zend_hash_add(psdl->requests, key, key_len, (void*)&preq, sizeof(sdlFunctionPtr), NULL);
+                       //???
+                       Z_PTR_P(zv) = preq;
+                       if (key) {
+                               zend_hash_add_ptr(psdl->requests, key, preq);
                        }
-                       zend_hash_move_forward(sdl->requests);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        zend_hash_destroy(&ptr_map);
@@ -3147,9 +3094,8 @@ typedef struct _sdl_cache_bucket {
        time_t time;
 } sdl_cache_bucket;
 
-static void delete_psdl(void *data)
+static void delete_psdl_int(sdl_cache_bucket *p)
 {
-       sdl_cache_bucket *p = (sdl_cache_bucket*)data;
        sdlPtr tmp = p->sdl;
 
        zend_hash_destroy(&tmp->functions);
@@ -3186,6 +3132,11 @@ static void delete_psdl(void *data)
        free(tmp);
 }
 
+static void delete_psdl(zval *zv)
+{
+       delete_psdl_int(Z_PTR_P(zv));
+}
+
 sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
 {
        char  fn[MAXPATHLEN];
@@ -3193,13 +3144,15 @@ 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 *tmp, *proxy_host, *proxy_port, orig_context, new_context;
        smart_str headers = {0};
        char* key = NULL;
        time_t t = time(0);
        zend_bool has_proxy_authorization = 0;
        zend_bool has_authorization = 0;
 
+       ZVAL_UNDEF(&orig_context);
+       ZVAL_UNDEF(&new_context);
        if (strchr(uri,':') != NULL || IS_ABSOLUTE_PATH(uri, uri_len)) {
                uri_len = strlen(uri);
        } else if (VCWD_REALPATH(uri, fn) == NULL) {
@@ -3212,10 +3165,10 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
        if ((cache_wsdl & WSDL_CACHE_MEMORY) && SOAP_GLOBAL(mem_cache)) {
                sdl_cache_bucket *p;
 
-               if (SUCCESS == zend_hash_find(SOAP_GLOBAL(mem_cache), uri, uri_len+1, (void*)&p)) {
+               if (NULL != (p = zend_hash_str_find_ptr(SOAP_GLOBAL(mem_cache), uri, uri_len))) {
                        if (p->time < t - SOAP_GLOBAL(cache_ttl)) {
                                /* in-memory cache entry is expired */
-                               zend_hash_del(&EG(persistent_list), uri, uri_len+1);
+                               zend_hash_str_del(&EG(persistent_list), uri, uri_len);
                        } else {
                                return p->sdl;
                        }
@@ -3255,51 +3208,47 @@ 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 (NULL != (tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr),
+                       "_stream_context", sizeof("_stream_context")-1))) {
+               context = php_stream_context_from_zval(tmp, 0);
        } else {
                context = php_stream_context_alloc(TSRMLS_C);
        }
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent"), (void **) &tmp) == SUCCESS &&
-           Z_TYPE_PP(tmp) == IS_STRING && Z_STRLEN_PP(tmp) > 0) {      
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent")-1)) != NULL &&
+           Z_TYPE_P(tmp) == IS_STRING && Z_STRLEN_P(tmp) > 0) {        
                smart_str_appends(&headers, "User-Agent: ");
-               smart_str_appends(&headers, Z_STRVAL_PP(tmp));
+               smart_str_appends(&headers, Z_STRVAL_P(tmp));
                smart_str_appends(&headers, "\r\n");
        }
 
-       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;
+       if ((proxy_host = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host")-1)) != NULL &&
+           Z_TYPE_P(proxy_host) == IS_STRING &&
+           (proxy_port = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port")-1)) != NULL &&
+           Z_TYPE_P(proxy_port) == IS_LONG) {
+               zval str_port, str_proxy;
                smart_str proxy = {0};
-               str_port = **proxy_port;
-               zval_copy_ctor(&str_port);
+               ZVAL_DUP(&str_port, proxy_port);
                convert_to_string(&str_port);
                smart_str_appends(&proxy,"tcp://");
-               smart_str_appends(&proxy,Z_STRVAL_PP(proxy_host));
+               smart_str_appends(&proxy,Z_STRVAL_P(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);
+               ZVAL_STR(&str_proxy, STR_COPY(proxy.s));
                smart_str_free(&proxy);
                
                if (!context) {
                        context = php_stream_context_alloc(TSRMLS_C);
                }
-               php_stream_context_set_option(context, "http", "proxy", str_proxy);
+               php_stream_context_set_option(context, "http", "proxy", &str_proxy);
                zval_ptr_dtor(&str_proxy);
 
                if (uri_len < sizeof("https://")-1 ||
                    strncasecmp(uri, "https://", sizeof("https://")-1) != 0) {
-                       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);
+                       ZVAL_TRUE(&str_proxy);
+                       php_stream_context_set_option(context, "http", "request_fulluri", &str_proxy);
                }
 
                has_proxy_authorization = proxy_authentication(this_ptr, &headers TSRMLS_CC);
@@ -3308,17 +3257,16 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
        has_authorization = basic_authentication(this_ptr, &headers TSRMLS_CC);
 
        /* Use HTTP/1.1 with "Connection: close" by default */
-       if (php_stream_context_get_option(context, "http", "protocol_version", &tmp) == FAILURE) {
-       zval *http_version;
-               MAKE_STD_ZVAL(http_version);
-               ZVAL_DOUBLE(http_version, 1.1);
-               php_stream_context_set_option(context, "http", "protocol_version", http_version);
-               zval_ptr_dtor(&http_version);
+       if ((tmp = php_stream_context_get_option(context, "http", "protocol_version")) == NULL) {
+       zval http_version;
+
+               ZVAL_DOUBLE(&http_version, 1.1);
+               php_stream_context_set_option(context, "http", "protocol_version", &http_version);
                smart_str_appendl(&headers, "Connection: close\r\n", sizeof("Connection: close\r\n")-1);
        }
 
-       if (headers.len > 0) {
-               zval *str_headers;
+       if (headers.s && headers.s->len > 0) {
+               zval str_headers;
 
                if (!context) {
                        context = php_stream_context_alloc(TSRMLS_C);
@@ -3327,17 +3275,15 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
                }
 
                smart_str_0(&headers);
-               MAKE_STD_ZVAL(str_headers);
-               ZVAL_STRING(str_headers, headers.c, 1);
-               php_stream_context_set_option(context, "http", "header", str_headers);
+               ZVAL_STR(&str_headers, STR_COPY(headers.s));
+               php_stream_context_set_option(context, "http", "header", &str_headers);
                smart_str_free(&headers);
                zval_ptr_dtor(&str_headers);
        }
 
        if (context) {
-               MAKE_STD_ZVAL(new_context);
-               php_stream_context_to_zval(context, new_context);
-               orig_context = php_libxml_switch_context(new_context TSRMLS_CC);
+               php_stream_context_to_zval(context, &new_context);
+               php_libxml_switch_context(&new_context, &orig_context TSRMLS_CC);
        }
 
        SOAP_GLOBAL(error_code) = "WSDL";
@@ -3350,7 +3296,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
        SOAP_GLOBAL(error_code) = old_error_code;
 
        if (context) {
-               php_libxml_switch_context(orig_context TSRMLS_CC);
+               php_libxml_switch_context(&orig_context, NULL TSRMLS_CC);
                zval_ptr_dtor(&new_context);
        }
 
@@ -3374,22 +3320,17 @@ cache_in_memory:
                                   SOAP_GLOBAL(cache_limit) <= zend_hash_num_elements(SOAP_GLOBAL(mem_cache))) {
                                /* in-memory cache overflow */
                                sdl_cache_bucket *q;
-                               HashPosition pos;
                                time_t latest = t;
-                               char *key = NULL;
-                               uint key_len;
-                               ulong idx;
+                               zend_string *latest_key = NULL, *key;
 
-                               for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(mem_cache), &pos);
-                                        zend_hash_get_current_data_ex(SOAP_GLOBAL(mem_cache), (void **) &q, &pos) == SUCCESS;
-                                        zend_hash_move_forward_ex(SOAP_GLOBAL(mem_cache), &pos)) {
+                               ZEND_HASH_FOREACH_STR_KEY_PTR(SOAP_GLOBAL(mem_cache), key, q) {
                                        if (q->time < latest) {
                                                latest = q->time;
-                                               zend_hash_get_current_key_ex(SOAP_GLOBAL(mem_cache), &key, &key_len, &idx, 0, &pos);
+                                               latest_key = key;
                                        }
-                               }
-                               if (key) {
-                                       zend_hash_del(SOAP_GLOBAL(mem_cache), key, key_len);
+                               } ZEND_HASH_FOREACH_END();
+                               if (latest_key) {
+                                       zend_hash_del(SOAP_GLOBAL(mem_cache), latest_key);
                                } else {
                                        return sdl;
                                }
@@ -3400,8 +3341,8 @@ cache_in_memory:
                        p.time = t;
                        p.sdl = psdl;
 
-                       if (SUCCESS == zend_hash_update(SOAP_GLOBAL(mem_cache), uri,
-                                                                                       uri_len+1, (void*)&p, sizeof(sdl_cache_bucket), NULL)) {
+                       if (NULL != zend_hash_str_update_mem(SOAP_GLOBAL(mem_cache), uri,
+                                                                                       uri_len, &p, sizeof(sdl_cache_bucket))) {
                                /* remove non-persitent sdl structure */
                                delete_sdl_impl(sdl);
                                /* and replace it with persistent one */
@@ -3409,7 +3350,7 @@ cache_in_memory:
                        } else {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent entry");
                                /* clean up persistent sdl */
-                               delete_psdl(&p);
+                               delete_psdl_int(&p);
                                /* keep non-persistent sdl and return it */
                        }
                }
@@ -3466,9 +3407,9 @@ void delete_sdl(void *handle)
        }
 }
 
-static void delete_binding(void *data)
+static void delete_binding(zval *zv)
 {
-       sdlBindingPtr binding = *((sdlBindingPtr*)data);
+       sdlBindingPtr binding = Z_PTR_P(zv);
 
        if (binding->location) {
                efree(binding->location);
@@ -3486,9 +3427,9 @@ static void delete_binding(void *data)
        efree(binding);
 }
 
-static void delete_binding_persistent(void *data)
+static void delete_binding_persistent(zval *zv)
 {
-       sdlBindingPtr binding = *((sdlBindingPtr*)data);
+       sdlBindingPtr binding = Z_PTR_P(zv);
 
        if (binding->location) {
                free(binding->location);
@@ -3528,9 +3469,9 @@ static void delete_sdl_soap_binding_function_body_persistent(sdlSoapBindingFunct
        }
 }
 
-static void delete_function(void *data)
+static void delete_function(zval *zv)
 {
-       sdlFunctionPtr function = *((sdlFunctionPtr*)data);
+       sdlFunctionPtr function = Z_PTR_P(zv);
 
        if (function->functionName) {
                efree(function->functionName);
@@ -3567,9 +3508,9 @@ static void delete_function(void *data)
        efree(function);
 }
 
-static void delete_function_persistent(void *data)
+static void delete_function_persistent(zval *zv)
 {
-       sdlFunctionPtr function = *((sdlFunctionPtr*)data);
+       sdlFunctionPtr function = Z_PTR_P(zv);
 
        if (function->functionName) {
                free(function->functionName);
@@ -3606,27 +3547,26 @@ static void delete_function_persistent(void *data)
        free(function);
 }
 
-static void delete_parameter(void *data)
+static void delete_parameter(zval *zv)
 {
-       sdlParamPtr param = *((sdlParamPtr*)data);
+       sdlParamPtr param = Z_PTR_P(zv);
        if (param->paramName) {
                efree(param->paramName);
        }
        efree(param);
 }
 
-static void delete_parameter_persistent(void *data)
+static void delete_parameter_persistent(zval *zv)
 {
-       sdlParamPtr param = *((sdlParamPtr*)data);
+       sdlParamPtr param = Z_PTR_P(zv);
        if (param->paramName) {
                free(param->paramName);
        }
        free(param);
 }
 
-static void delete_header(void *data)
+static void delete_header_int(sdlSoapBindingFunctionHeaderPtr hdr)
 {
-       sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
        if (hdr->name) {
                efree(hdr->name);
        }
@@ -3640,9 +3580,14 @@ static void delete_header(void *data)
        efree(hdr);
 }
 
-static void delete_header_persistent(void *data)
+static void delete_header(zval *zv)
+{
+       delete_header_int(Z_PTR_P(zv));
+}
+
+static void delete_header_persistent(zval *zv)
 {
-       sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
+       sdlSoapBindingFunctionHeaderPtr hdr = Z_PTR_P(zv);
        if (hdr->name) {
                free(hdr->name);
        }
@@ -3656,9 +3601,9 @@ static void delete_header_persistent(void *data)
        free(hdr);
 }
 
-static void delete_fault(void *data)
+static void delete_fault(zval *zv)
 {
-       sdlFaultPtr fault = *((sdlFaultPtr*)data);
+       sdlFaultPtr fault = Z_PTR_P(zv);
        if (fault->name) {
                efree(fault->name);
        }
@@ -3677,9 +3622,9 @@ static void delete_fault(void *data)
        efree(fault);
 }
 
-static void delete_fault_persistent(void *data)
+static void delete_fault_persistent(zval *zv)
 {
-       sdlFaultPtr fault = *((sdlFaultPtr*)data);
+       sdlFaultPtr fault = Z_PTR_P(zv);
        if (fault->name) {
                free(fault->name);
        }
@@ -3698,9 +3643,9 @@ static void delete_fault_persistent(void *data)
        free(fault);
 }
 
-static void delete_document(void *doc_ptr)
+static void delete_document(zval *zv)
 {
-       xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
+       xmlDocPtr doc = Z_PTR_P(zv);
        xmlFreeDoc(doc);
 }
 
index fd2d78db9e84d847af14fc5addcf5fc78806693b..2856ed1c4777b5e8fc32fa0c9bc3b06a5b133ff1 100644 (file)
@@ -77,7 +77,7 @@ typedef struct sdlCtx {
        HashTable *attributes;       /* array of sdlAttributePtr */
        HashTable *attributeGroups;  /* array of sdlTypesPtr */
        php_stream_context *context;
-       zval               *old_header;
+       zval               old_header;
 } sdlCtx;
 
 struct _sdlBinding {
index fb8d1d60fbf751e87fd3476380048b922d9e5cc9..9b9a7efbd5b631216ebf2e00cc78a7abf451dc06 100644 (file)
@@ -74,8 +74,8 @@ typedef struct _soapService soapService, *soapServicePtr;
 #include "php_packet_soap.h"
 
 struct _soapMapping {
-       zval *to_xml;
-       zval *to_zval;
+       zval to_xml;
+       zval to_zval;
 };
 
 struct _soapHeader;
@@ -90,12 +90,12 @@ struct _soapService {
 
        struct _soap_class {
                zend_class_entry *ce;
-               zval **argv;
+               zval *argv;
                int argc;
                int persistance;
        } soap_class;
 
-       zval *soap_object;
+       zval soap_object;
 
        HashTable *typemap;
        int        version;
index 9f3b5e14bfb21d8ac0319159c84ea949dd606139..0c1521282a391e71d5df3de0d0d1f61d91180550 100644 (file)
@@ -39,7 +39,7 @@ typedef struct _soapHeader {
        zval                              function_name;
        int                               mustUnderstand;
        int                               num_params;
-       zval                            **parameters;
+       zval                             *parameters;
        zval                              retval;
        sdlSoapBindingFunctionHeaderPtr   hdr;
        struct _soapHeader               *next;
@@ -58,9 +58,9 @@ static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int inde
 static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name);
 static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr node);
 
-static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters[], int *version, soapHeader **headers TSRMLS_DC);
+static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters, int *version, soapHeader **headers TSRMLS_DC);
 static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function_name,char *uri,zval *ret, soapHeader *headers, int version TSRMLS_DC);
-static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count, int version, HashTable *soap_headers TSRMLS_DC);
+static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval *arguments, int arg_count, int version, HashTable *soap_headers TSRMLS_DC);
 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);
 
@@ -77,7 +77,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const
        int _old_soap_version = SOAP_GLOBAL(soap_version);\
        SOAP_GLOBAL(use_soap_error_handler) = 1;\
        SOAP_GLOBAL(error_code) = "Server";\
-       SOAP_GLOBAL(error_object) = this_ptr;
+       SOAP_GLOBAL(error_object) = getThis();
 
 #define SOAP_SERVER_END_CODE() \
        SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
@@ -93,11 +93,11 @@ static void soap_error_handler(int error_num, const char *error_filename, const
        zend_bool _old_in_compilation = CG(in_compilation); \
        zend_bool _old_in_execution = EG(in_execution); \
        zend_execute_data *_old_current_execute_data = EG(current_execute_data); \
-       void **_old_stack_top = EG(argument_stack)->top; \
+       zval *_old_stack_top = EG(argument_stack)->top; \
        int _bailout = 0;\
        SOAP_GLOBAL(use_soap_error_handler) = 1;\
        SOAP_GLOBAL(error_code) = "Client";\
-       SOAP_GLOBAL(error_object) = this_ptr;\
+       SOAP_GLOBAL(error_object) = getThis();\
        zend_try {
 
 #define SOAP_CLIENT_END_CODE() \
@@ -106,8 +106,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const
                EG(in_execution) = _old_in_execution; \
                EG(current_execute_data) = _old_current_execute_data; \
                if (EG(exception) == NULL || \
-                   Z_TYPE_P(EG(exception)) != IS_OBJECT || \
-                   !instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {\
+                   !instanceof_function(zend_get_class_entry(EG(exception) TSRMLS_CC), soap_fault_class_entry TSRMLS_CC)) {\
                        _bailout = 1;\
                }\
                if (_old_stack_top != EG(argument_stack)->top) { \
@@ -131,24 +130,24 @@ static void soap_error_handler(int error_num, const char *error_filename, const
 
 #define FETCH_THIS_SDL(ss) \
        { \
-               zval **__tmp; \
-               if(FIND_SDL_PROPERTY(this_ptr,__tmp) != FAILURE) { \
+               zval *__tmp; \
+               if(FIND_SDL_PROPERTY(getThis(), __tmp) != NULL) { \
                        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 FIND_SDL_PROPERTY(ss,tmp) (tmp = zend_hash_str_find(Z_OBJPROP_P(ss), "sdl", sizeof("sdl")-1))
 #define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource(tmp TSRMLS_CC, -1, "sdl", NULL, 1, le_sdl)
 
-#define FIND_TYPEMAP_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "typemap", sizeof("typemap"), (void **)&tmp)
+#define FIND_TYPEMAP_PROPERTY(ss,tmp) (tmp = zend_hash_str_find(Z_OBJPROP_P(ss), "typemap", sizeof("typemap")-1))
 #define FETCH_TYPEMAP_RES(ss,tmp) ss = (HashTable*) zend_fetch_resource(tmp TSRMLS_CC, -1, "typemap", NULL, 1, le_typemap)
 
 #define FETCH_THIS_SERVICE(ss) \
        { \
-               zval **tmp; \
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr),"service", sizeof("service"), (void **)&tmp) != FAILURE) { \
+               zval *tmp; \
+               if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()),"service", sizeof("service")-1)) != NULL) { \
                        ss = (soapServicePtr)zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service); \
                } else { \
                        ss = NULL; \
@@ -532,7 +531,7 @@ static void php_soap_prepare_globals()
        zend_hash_init(&defEnc, 0, NULL, NULL, 1);
        zend_hash_init(&defEncIndex, 0, NULL, NULL, 1);
        zend_hash_init(&defEncNs, 0, NULL, NULL, 1);
-       defEncNs.flags |= HASH_FLAG_BIG_DATA;   
+//???  defEncNs.flags |= HASH_FLAG_BIG_DATA;   
 
        i = 0;
        do {
@@ -543,26 +542,27 @@ static void php_soap_prepare_globals()
                        if (defaultEncoding[i].details.ns != NULL) {
                                char *ns_type;
                                spprintf(&ns_type, 0, "%s:%s", defaultEncoding[i].details.ns, defaultEncoding[i].details.type_str);
-                               zend_hash_add(&defEnc, ns_type, strlen(ns_type) + 1, &enc, sizeof(encodePtr), NULL);
+                               zend_hash_str_add_ptr(&defEnc, ns_type, strlen(ns_type), enc);
                                efree(ns_type);
                        } else {
-                               zend_hash_add(&defEnc, defaultEncoding[i].details.type_str, strlen(defaultEncoding[i].details.type_str) + 1, &enc, sizeof(encodePtr), NULL);
+                               zend_hash_str_add_ptr(&defEnc, defaultEncoding[i].details.type_str, strlen(defaultEncoding[i].details.type_str), enc);
                        }
                }
                /* Index everything by number */
                if (!zend_hash_index_exists(&defEncIndex, defaultEncoding[i].details.type)) {
-                       zend_hash_index_update(&defEncIndex, defaultEncoding[i].details.type, &enc, sizeof(encodePtr), NULL);
+                       zend_hash_index_update_ptr(&defEncIndex, defaultEncoding[i].details.type, enc);
                }
                i++;
        } while (defaultEncoding[i].details.type != END_KNOWN_TYPES);
 
        /* hash by namespace */
-       zend_hash_add(&defEncNs, XSD_1999_NAMESPACE, sizeof(XSD_1999_NAMESPACE), XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX), NULL);
-       zend_hash_add(&defEncNs, XSD_NAMESPACE, sizeof(XSD_NAMESPACE), XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX), NULL);
-       zend_hash_add(&defEncNs, XSI_NAMESPACE, sizeof(XSI_NAMESPACE), XSI_NS_PREFIX, sizeof(XSI_NS_PREFIX), NULL);
-       zend_hash_add(&defEncNs, XML_NAMESPACE, sizeof(XML_NAMESPACE), XML_NS_PREFIX, sizeof(XML_NS_PREFIX), NULL);
-       zend_hash_add(&defEncNs, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE), SOAP_1_1_ENC_NS_PREFIX, sizeof(SOAP_1_1_ENC_NS_PREFIX), NULL);
-       zend_hash_add(&defEncNs, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE), SOAP_1_2_ENC_NS_PREFIX, sizeof(SOAP_1_2_ENC_NS_PREFIX), NULL);
+//??? change _mem into _ptr
+       zend_hash_str_add_mem(&defEncNs, XSD_1999_NAMESPACE, sizeof(XSD_1999_NAMESPACE)-1, XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX));
+       zend_hash_str_add_mem(&defEncNs, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1, XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX));
+       zend_hash_str_add_mem(&defEncNs, XSI_NAMESPACE, sizeof(XSI_NAMESPACE)-1, XSI_NS_PREFIX, sizeof(XSI_NS_PREFIX));
+       zend_hash_str_add_mem(&defEncNs, XML_NAMESPACE, sizeof(XML_NAMESPACE)-1, XML_NS_PREFIX, sizeof(XML_NS_PREFIX));
+       zend_hash_str_add_mem(&defEncNs, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1, SOAP_1_1_ENC_NS_PREFIX, sizeof(SOAP_1_1_ENC_NS_PREFIX));
+       zend_hash_str_add_mem(&defEncNs, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1, SOAP_1_2_ENC_NS_PREFIX, sizeof(SOAP_1_2_ENC_NS_PREFIX));
 }
 
 static void php_soap_init_globals(zend_soap_globals *soap_globals TSRMLS_DC)
@@ -609,6 +609,26 @@ PHP_RINIT_FUNCTION(soap)
        return SUCCESS;
 }
 
+static void delete_sdl_res(zend_resource *res)
+{
+       delete_sdl(res->ptr);
+}
+
+static void delete_url_res(zend_resource *res)
+{
+       delete_url(res->ptr);
+}
+
+static void delete_service_res(zend_resource *res)
+{
+       delete_service(res->ptr);
+}
+
+static void delete_hashtable_res(zend_resource *res)
+{
+       delete_hashtable(res->ptr);
+}
+
 PHP_MINIT_FUNCTION(soap)
 {
        zend_class_entry ce;
@@ -657,10 +677,10 @@ 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);
-       le_typemap = register_list_destructors(delete_hashtable, NULL);
+       le_sdl = register_list_destructors(delete_sdl_res, NULL);
+       le_url = register_list_destructors(delete_url_res, NULL);
+       le_service = register_list_destructors(delete_service_res, NULL);
+       le_typemap = register_list_destructors(delete_hashtable_res, 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);
@@ -783,6 +803,7 @@ PHP_METHOD(SoapParam, SoapParam)
        zval *data;
        char *name;
        int name_length;
+       zval *this_ptr;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &data, &name, &name_length) == FAILURE) {
                return;
@@ -792,6 +813,7 @@ PHP_METHOD(SoapParam, SoapParam)
                return;
        }
 
+       this_ptr = getThis();
        add_property_stringl(this_ptr, "param_name", name, name_length);
        add_property_zval(this_ptr, "param_data", data);
 }
@@ -806,6 +828,7 @@ PHP_METHOD(SoapHeader, SoapHeader)
        char *name, *ns;
        int name_len, ns_len;
        zend_bool must_understand = 0;
+       zval *this_ptr;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|zbz", &ns, &ns_len, &name, &name_len, &data, &must_understand, &actor) == FAILURE) {
                return;
@@ -819,6 +842,7 @@ PHP_METHOD(SoapHeader, SoapHeader)
                return;
        }
 
+       this_ptr = getThis();
        add_property_stringl(this_ptr, "namespace", ns, ns_len);
        add_property_stringl(this_ptr, "name", name, name_len);
        if (data) {
@@ -844,7 +868,7 @@ PHP_METHOD(SoapFault, SoapFault)
 {
        char *fault_string = NULL, *fault_code = NULL, *fault_actor = NULL, *name = NULL, *fault_code_ns = NULL;
        int fault_string_len, fault_actor_len = 0, name_len = 0, fault_code_len = 0;
-       zval *code = NULL, *details = NULL, *headerfault = NULL;
+       zval *code = NULL, *details = NULL, *headerfault = NULL, *this_ptr;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|s!z!s!z",
                &code,
@@ -859,16 +883,16 @@ PHP_METHOD(SoapFault, SoapFault)
                fault_code = Z_STRVAL_P(code);
                fault_code_len = Z_STRLEN_P(code);
        } else if (Z_TYPE_P(code) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(code)) == 2) {
-               zval **t_ns, **t_code;
+               zval *t_ns, *t_code;
 
                zend_hash_internal_pointer_reset(Z_ARRVAL_P(code));
-               zend_hash_get_current_data(Z_ARRVAL_P(code), (void**)&t_ns);
+               t_ns = zend_hash_get_current_data(Z_ARRVAL_P(code));
                zend_hash_move_forward(Z_ARRVAL_P(code));
-               zend_hash_get_current_data(Z_ARRVAL_P(code), (void**)&t_code);
-               if (Z_TYPE_PP(t_ns) == IS_STRING && Z_TYPE_PP(t_code) == IS_STRING) {
-                 fault_code_ns = Z_STRVAL_PP(t_ns);
-                 fault_code = Z_STRVAL_PP(t_code);
-                 fault_code_len = Z_STRLEN_PP(t_code);
+               t_code = zend_hash_get_current_data(Z_ARRVAL_P(code));
+               if (Z_TYPE_P(t_ns) == IS_STRING && Z_TYPE_P(t_code) == IS_STRING) {
+                 fault_code_ns = Z_STRVAL_P(t_ns);
+                 fault_code = Z_STRVAL_P(t_code);
+                 fault_code_len = Z_STRLEN_P(t_code);
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid fault code");
                        return;
@@ -885,6 +909,7 @@ PHP_METHOD(SoapFault, SoapFault)
                name = NULL;
        }
 
+       this_ptr = getThis();
        set_soap_fault(this_ptr, fault_code_ns, fault_code, fault_string, fault_actor, details, name TSRMLS_CC);
        if (headerfault != NULL) {
                add_property_zval(this_ptr, "headerfault", headerfault);
@@ -897,42 +922,45 @@ PHP_METHOD(SoapFault, SoapFault)
    SoapFault constructor */
 PHP_METHOD(SoapFault, __toString)
 {
-       zval *faultcode, *faultstring, *file, *line, *trace;
+       zval *faultcode, *faultstring, *file, *line, trace;
        char *str;
        int len;
        zend_fcall_info fci;
-       zval fname;
+       zval *this_ptr;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
+       this_ptr = getThis();
        faultcode   = zend_read_property(soap_fault_class_entry, this_ptr, "faultcode", sizeof("faultcode")-1, 1 TSRMLS_CC);
        faultstring = zend_read_property(soap_fault_class_entry, this_ptr, "faultstring", sizeof("faultstring")-1, 1 TSRMLS_CC);
        file = zend_read_property(soap_fault_class_entry, this_ptr, "file", sizeof("file")-1, 1 TSRMLS_CC);
        line = zend_read_property(soap_fault_class_entry, this_ptr, "line", sizeof("line")-1, 1 TSRMLS_CC);
 
-       ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 0);
-
        fci.size = sizeof(fci);
        fci.function_table = &Z_OBJCE_P(getThis())->function_table;
-       fci.function_name = &fname;
+       ZVAL_STRINGL(&fci.function_name, "gettraceasstring", sizeof("gettraceasstring")-1);
        fci.symbol_table = NULL;
-       fci.object_ptr = getThis();
-       fci.retval_ptr_ptr = &trace;
+       fci.object = Z_OBJ(EG(This));
+       fci.retval = &trace;
        fci.param_count = 0;
        fci.params = NULL;
        fci.no_separation = 1;
 
        zend_call_function(&fci, NULL TSRMLS_CC);
 
+       zval_ptr_dtor(&fci.function_name);
+
        len = spprintf(&str, 0, "SoapFault exception: [%s] %s in %s:%ld\nStack trace:\n%s",
                       Z_STRVAL_P(faultcode), Z_STRVAL_P(faultstring), Z_STRVAL_P(file), Z_LVAL_P(line),
-                      Z_STRLEN_P(trace) ? Z_STRVAL_P(trace) : "#0 {main}\n");
+                      Z_STRLEN(trace) ? Z_STRVAL(trace) : "#0 {main}\n");
 
        zval_ptr_dtor(&trace);
 
-       RETURN_STRINGL(str, len, 0);
+       // TODO: avoid reallocation ???
+       RETVAL_STRINGL(str, len);
+       efree(str);
 }
 /* }}} */
 
@@ -940,7 +968,7 @@ PHP_METHOD(SoapFault, __toString)
    SoapVar constructor */
 PHP_METHOD(SoapVar, SoapVar)
 {
-       zval *data, *type;
+       zval *data, *type, *this_ptr;
        char *stype = NULL, *ns = NULL, *name = NULL, *namens = NULL;
        int stype_len = 0, ns_len = 0, name_len = 0, namens_len = 0;
 
@@ -948,6 +976,7 @@ PHP_METHOD(SoapVar, SoapVar)
                return;
        }
 
+       this_ptr = getThis();
        if (Z_TYPE_P(type) == IS_NULL) {
                add_property_long(this_ptr, "enc_type", UNKNOWN_TYPE);
        } else {
@@ -978,58 +1007,49 @@ PHP_METHOD(SoapVar, SoapVar)
 }
 /* }}} */
 
-
 static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC)
 {
-       zval **tmp;
+       zval *tmp;
        HashTable *ht2;
-       HashPosition pos1, pos2;
        HashTable *typemap = NULL;
        
-       zend_hash_internal_pointer_reset_ex(ht, &pos1);
-       while (zend_hash_get_current_data_ex(ht, (void**)&tmp, &pos1) == SUCCESS) {
+       ZEND_HASH_FOREACH_VAL(ht, tmp) {
                char *type_name = NULL;
                char *type_ns = NULL;
                zval *to_xml = NULL;
                zval *to_zval = NULL;
                encodePtr enc, new_enc;
+               zend_string *name;
 
-               if (Z_TYPE_PP(tmp) != IS_ARRAY) {
+               if (Z_TYPE_P(tmp) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong 'typemap' option");
                        return NULL;
                }
-               ht2 = Z_ARRVAL_PP(tmp);
+               ht2 = Z_ARRVAL_P(tmp);
 
-               zend_hash_internal_pointer_reset_ex(ht2, &pos2);
-               while (zend_hash_get_current_data_ex(ht2, (void**)&tmp, &pos2) == SUCCESS) {
-                       char *name = NULL;
-                       unsigned int name_len;
-                       ulong index;
-
-                       zend_hash_get_current_key_ex(ht2, &name, &name_len, &index, 0, &pos2);
+               ZEND_HASH_FOREACH_STR_KEY_VAL(ht2, name, tmp) {
                        if (name) {
-                               if (name_len == sizeof("type_name") &&
-                                   strncmp(name, "type_name", sizeof("type_name")-1) == 0) {
-                                       if (Z_TYPE_PP(tmp) == IS_STRING) {
-                                               type_name = Z_STRVAL_PP(tmp);
-                                       } else if (Z_TYPE_PP(tmp) != IS_NULL) {
+                               if (name->len == sizeof("type_name") &&
+                                   strncmp(name->val, "type_name", sizeof("type_name")-1) == 0) {
+                                       if (Z_TYPE_P(tmp) == IS_STRING) {
+                                               type_name = Z_STRVAL_P(tmp);
+                                       } else if (Z_TYPE_P(tmp) != IS_NULL) {
                                        }
-                               } else if (name_len == sizeof("type_ns") &&
-                                   strncmp(name, "type_ns", sizeof("type_ns")-1) == 0) {
-                                       if (Z_TYPE_PP(tmp) == IS_STRING) {
-                                               type_ns = Z_STRVAL_PP(tmp);
-                                       } else if (Z_TYPE_PP(tmp) != IS_NULL) {
+                               } else if (name->len == sizeof("type_ns") &&
+                                   strncmp(name->val, "type_ns", sizeof("type_ns")-1) == 0) {
+                                       if (Z_TYPE_P(tmp) == IS_STRING) {
+                                               type_ns = Z_STRVAL_P(tmp);
+                                       } else if (Z_TYPE_P(tmp) != IS_NULL) {
                                        }
-                               } else if (name_len == sizeof("to_xml") &&
-                                   strncmp(name, "to_xml", sizeof("to_xml")-1) == 0) {
-                                       to_xml = *tmp;
-                               } else if (name_len == sizeof("from_xml") &&
-                                   strncmp(name, "from_xml", sizeof("from_xml")-1) == 0) {
-                                       to_zval = *tmp;
+                               } else if (name->len == sizeof("to_xml") &&
+                                   strncmp(name->val, "to_xml", sizeof("to_xml")-1) == 0) {
+                                       to_xml = tmp;
+                               } else if (name->len == sizeof("from_xml") &&
+                                   strncmp(name->val, "from_xml", sizeof("from_xml")-1) == 0) {
+                                       to_zval = tmp;
                                }
                        }
-                       zend_hash_move_forward_ex(ht2, &pos2);
-               }               
+               } ZEND_HASH_FOREACH_END();              
 
                if (type_name) {
                        smart_str nscat = {0};
@@ -1061,20 +1081,16 @@ static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC)
                        new_enc->details.map = emalloc(sizeof(soapMapping));
                        memset(new_enc->details.map, 0, sizeof(soapMapping));                   
                        if (to_xml) {
-                               zval_add_ref(&to_xml);
-                               new_enc->details.map->to_xml = to_xml;
+                               ZVAL_COPY(&new_enc->details.map->to_xml, to_xml);
                                new_enc->to_xml = to_xml_user;
-                       } else if (enc->details.map && enc->details.map->to_xml) {
-                               zval_add_ref(&enc->details.map->to_xml);
-                               new_enc->details.map->to_xml = enc->details.map->to_xml;
+                       } else if (enc->details.map && Z_TYPE(enc->details.map->to_xml) != IS_UNDEF) {
+                               ZVAL_COPY(&new_enc->details.map->to_xml, &enc->details.map->to_xml);
                        }
                        if (to_zval) {
-                               zval_add_ref(&to_zval);
-                               new_enc->details.map->to_zval = to_zval;
+                               ZVAL_COPY(&new_enc->details.map->to_zval, to_zval);
                                new_enc->to_zval = to_zval_user;
-                       } else if (enc->details.map && enc->details.map->to_zval) {
-                               zval_add_ref(&enc->details.map->to_zval);
-                               new_enc->details.map->to_zval = enc->details.map->to_zval;
+                       } else if (enc->details.map && Z_TYPE(enc->details.map->to_zval) != IS_UNDEF) {
+                               ZVAL_COPY(&new_enc->details.map->to_zval, &enc->details.map->to_zval);
                        }
                        if (!typemap) {
                                typemap = emalloc(sizeof(HashTable));
@@ -1087,11 +1103,10 @@ static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC)
                        }
                        smart_str_appends(&nscat, type_name);
                        smart_str_0(&nscat);
-                       zend_hash_update(typemap, nscat.c, nscat.len + 1, &new_enc, sizeof(encodePtr), NULL);
+                       zend_hash_update_ptr(typemap, nscat.s, new_enc);
                        smart_str_free(&nscat);
                }
-               zend_hash_move_forward_ex(ht, &pos1);
-       }
+       } ZEND_HASH_FOREACH_END();
        return typemap;
 }
 
@@ -1102,7 +1117,7 @@ PHP_METHOD(SoapServer, SoapServer)
 {
        soapServicePtr service;
        zval *wsdl = NULL, *options = NULL;
-       int ret;
+       zend_resource *res;
        int version = SOAP_1_1;
        long cache_wsdl;
        HashTable *typemap_ht = NULL;
@@ -1125,69 +1140,72 @@ PHP_METHOD(SoapServer, SoapServer)
 
        if (options != NULL) {
                HashTable *ht = Z_ARRVAL_P(options);
-               zval **tmp;
+               zval *tmp;
 
-               if (zend_hash_find(ht, "soap_version", sizeof("soap_version"), (void**)&tmp) == SUCCESS) {
-                       if (Z_TYPE_PP(tmp) == IS_LONG &&
-                           (Z_LVAL_PP(tmp) == SOAP_1_1 || Z_LVAL_PP(tmp) == SOAP_1_2)) {
-                               version = Z_LVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(ht, "soap_version", sizeof("soap_version")-1)) != NULL) {
+                       if (Z_TYPE_P(tmp) == IS_LONG &&
+                           (Z_LVAL_P(tmp) == SOAP_1_1 || Z_LVAL_P(tmp) == SOAP_1_2)) {
+                               version = Z_LVAL_P(tmp);
                        } else {
                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "'soap_version' option must be SOAP_1_1 or SOAP_1_2");
                        }
                }
 
-               if (zend_hash_find(ht, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                       service->uri = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+               if ((tmp = zend_hash_str_find(ht, "uri", sizeof("uri")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                       service->uri = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                } else if (Z_TYPE_P(wsdl) == IS_NULL) {
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "'uri' option is required in nonWSDL mode");
                }
 
-               if (zend_hash_find(ht, "actor", sizeof("actor"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                       service->actor = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+               if ((tmp = zend_hash_str_find(ht, "actor", sizeof("actor")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                       service->actor = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                }
 
-               if (zend_hash_find(ht, "encoding", sizeof("encoding"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
+               if ((tmp = zend_hash_str_find(ht, "encoding", sizeof("encoding")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
                        xmlCharEncodingHandlerPtr encoding;
                
-                       encoding = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
+                       encoding = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp));
                        if (encoding == NULL) {
-                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_PP(tmp));
+                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_P(tmp));
                        } else {
                          service->encoding = encoding;
                        }
                }
 
-               if (zend_hash_find(ht, "classmap", sizeof("classmap"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_ARRAY) {
-                       zval *ztmp;
-
+               if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_ARRAY) {
                        ALLOC_HASHTABLE(service->class_map);
-                       zend_hash_init(service->class_map, zend_hash_num_elements((*tmp)->value.ht), NULL, ZVAL_PTR_DTOR, 0);
-                       zend_hash_copy(service->class_map, (*tmp)->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &ztmp, sizeof(zval *));
+                       zend_hash_init(service->class_map, zend_hash_num_elements(Z_ARRVAL_P(tmp)), NULL, ZVAL_PTR_DTOR, 0);
+                       zend_hash_copy(service->class_map, Z_ARRVAL_P(tmp), zval_add_ref);
                }
 
-               if (zend_hash_find(ht, "typemap", sizeof("typemap"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_ARRAY &&
-                       zend_hash_num_elements(Z_ARRVAL_PP(tmp)) > 0) {
-                       typemap_ht = Z_ARRVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_ARRAY &&
+                       zend_hash_num_elements(Z_ARRVAL_P(tmp)) > 0) {
+                       typemap_ht = Z_ARRVAL_P(tmp);
                }
 
-               if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_LONG) {
-                       service->features = Z_LVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(ht, "features", sizeof("features")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_LONG) {
+                       service->features = Z_LVAL_P(tmp);
                }
 
-               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 ((tmp = zend_hash_str_find(ht, "cache_wsdl", sizeof("cache_wsdl")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_LONG) {
+                       cache_wsdl = Z_LVAL_P(tmp);
                }
 
-               if (zend_hash_find(ht, "send_errors", sizeof("send_errors"), (void**)&tmp) == SUCCESS &&
-                   (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG)) {
-                       service->send_errors = Z_LVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(ht, "send_errors", sizeof("send_errors")-1)) != NULL) {
+                       if (Z_TYPE_P(tmp) == IS_FALSE) {
+                               service->send_errors = 0;
+                       } else if (Z_TYPE_P(tmp) == IS_TRUE) {
+                               service->send_errors = 1;
+                       } else if (Z_TYPE_P(tmp) == IS_LONG) {
+                               service->send_errors = Z_LVAL_P(tmp);
+                       }
                }
 
        } else if (Z_TYPE_P(wsdl) == IS_NULL) {
@@ -1201,7 +1219,7 @@ PHP_METHOD(SoapServer, SoapServer)
        zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0);
 
        if (Z_TYPE_P(wsdl) != IS_NULL) {
-               service->sdl = get_sdl(this_ptr, Z_STRVAL_P(wsdl), cache_wsdl TSRMLS_CC);
+               service->sdl = get_sdl(getThis(), Z_STRVAL_P(wsdl), cache_wsdl TSRMLS_CC);
                if (service->uri == NULL) {
                        if (service->sdl->target_ns) {
                                service->uri = estrdup(service->sdl->target_ns);
@@ -1216,8 +1234,8 @@ PHP_METHOD(SoapServer, SoapServer)
                service->typemap = soap_create_typemap(service->sdl, typemap_ht TSRMLS_CC);
        }
 
-       ret = zend_list_insert(service, le_service TSRMLS_CC);
-       add_property_resource(this_ptr, "service", ret);
+       res = zend_register_resource(NULL, service, le_service TSRMLS_CC);
+       add_property_resource(getThis(), "service", res);
 
        SOAP_SERVER_END_CODE();
 }
@@ -1260,25 +1278,24 @@ PHP_METHOD(SoapServer, setPersistence)
 PHP_METHOD(SoapServer, setClass)
 {
        soapServicePtr service;
-       char *classname;
-       zend_class_entry **ce;
-
-       int classname_len, found, num_args = 0;
-       zval ***argv = NULL;
+       zend_string *classname;
+       zend_class_entry *ce;
+       int num_args = 0;
+       zval *argv = NULL;
 
        SOAP_SERVER_BEGIN_CODE();
 
        FETCH_THIS_SERVICE(service);
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s*", &classname, &classname_len, &argv, &num_args) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S*", &classname, &argv, &num_args) == FAILURE) {
                return;
        }
 
-       found = zend_lookup_class(classname, classname_len, &ce TSRMLS_CC);
+       ce = zend_lookup_class(classname TSRMLS_CC);
 
-       if (found != FAILURE) {
+       if (ce) {
                service->type = SOAP_CLASS;
-               service->soap_class.ce = *ce;
+               service->soap_class.ce = ce;
 
                service->soap_class.persistance = SOAP_PERSISTENCE_REQUEST;
                service->soap_class.argc = num_args;
@@ -1286,12 +1303,11 @@ PHP_METHOD(SoapServer, setClass)
                        int i;
                        service->soap_class.argv = safe_emalloc(sizeof(zval), service->soap_class.argc, 0);
                        for (i = 0;i < service->soap_class.argc;i++) {
-                               service->soap_class.argv[i] = *(argv[i]);
-                               zval_add_ref(&service->soap_class.argv[i]);
+                               ZVAL_COPY(&service->soap_class.argv[i], &argv[i]);
                        }
                }
        } else {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to set a non existent class (%s)", classname);
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to set a non existent class (%s)", classname->val);
                return;
        }
 
@@ -1321,8 +1337,7 @@ PHP_METHOD(SoapServer, setObject)
 
        service->type = SOAP_OBJECT;
 
-       MAKE_STD_ZVAL(service->soap_object);
-       MAKE_COPY_ZVAL(&obj, service->soap_object);
+       ZVAL_COPY(&service->soap_object, obj);
 
        SOAP_SERVER_END_CODE();
 }
@@ -1346,31 +1361,26 @@ PHP_METHOD(SoapServer, getFunctions)
 
        array_init(return_value);
        if (service->type == SOAP_OBJECT) {
-               ft = &(Z_OBJCE_P(service->soap_object)->function_table);
+               ft = &(Z_OBJCE(service->soap_object)->function_table);
        } else if (service->type == SOAP_CLASS) {
                ft = &service->soap_class.ce->function_table;
        } else if (service->soap_functions.functions_all == TRUE) {
                ft = EG(function_table);
        } else if (service->soap_functions.ft != NULL) {
-               zval **name;
-               HashPosition pos;
+               zval *name;
 
-               zend_hash_internal_pointer_reset_ex(service->soap_functions.ft, &pos);
-               while (zend_hash_get_current_data_ex(service->soap_functions.ft, (void **)&name, &pos) != FAILURE) {
-                       add_next_index_string(return_value, Z_STRVAL_PP(name));
-                       zend_hash_move_forward_ex(service->soap_functions.ft, &pos);
-               }
+               ZEND_HASH_FOREACH_VAL(service->soap_functions.ft, name) {
+                       add_next_index_str(return_value, STR_COPY(Z_STR_P(name)));
+               } ZEND_HASH_FOREACH_END();
        }
        if (ft != NULL) {
                zend_function *f;
-               HashPosition pos;
-               zend_hash_internal_pointer_reset_ex(ft, &pos);
-               while (zend_hash_get_current_data_ex(ft, (void **)&f, &pos) != FAILURE) {
+
+               ZEND_HASH_FOREACH_PTR(ft, f) {
                        if ((service->type != SOAP_OBJECT && service->type != SOAP_CLASS) || (f->common.fn_flags & ZEND_ACC_PUBLIC)) {
-                               add_next_index_string(return_value, f->common.function_name);
+                               add_next_index_str(return_value, STR_COPY(f->common.function_name));
                        }
-                       zend_hash_move_forward_ex(ft, &pos);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        SOAP_SERVER_END_CODE();
@@ -1383,8 +1393,7 @@ PHP_METHOD(SoapServer, getFunctions)
 PHP_METHOD(SoapServer, addFunction)
 {
        soapServicePtr service;
-       zval *function_name, *function_copy;
-       HashPosition pos;
+       zval *function_name, function_copy;
 
        SOAP_SERVER_BEGIN_CODE();
 
@@ -1396,9 +1405,9 @@ PHP_METHOD(SoapServer, addFunction)
 
        /* TODO: could use zend_is_callable here */
 
-       if (function_name->type == IS_ARRAY) {
+       if (Z_TYPE_P(function_name) == IS_ARRAY) {
                if (service->type == SOAP_FUNCTIONS) {
-                       zval **tmp_function, *function_copy;
+                       zval *tmp_function;
 
                        if (service->soap_functions.ft == NULL) {
                                service->soap_functions.functions_all = FALSE;
@@ -1406,44 +1415,37 @@ PHP_METHOD(SoapServer, addFunction)
                                zend_hash_init(service->soap_functions.ft, zend_hash_num_elements(Z_ARRVAL_P(function_name)), NULL, ZVAL_PTR_DTOR, 0);
                        }
 
-                       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(function_name), &pos);
-                       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(function_name), (void **)&tmp_function, &pos) != FAILURE) {
-                               char *key;
-                               int   key_len;
+                       ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(function_name), tmp_function) {
+                               zend_string *key;
                                zend_function *f;
 
-                               if (Z_TYPE_PP(tmp_function) != IS_STRING) {
+                               if (Z_TYPE_P(tmp_function) != IS_STRING) {
                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to add a function that isn't a string");
                                        return;
                                }
 
-                               key_len = Z_STRLEN_PP(tmp_function);
-                               key = emalloc(key_len + 1);
-                               zend_str_tolower_copy(key, Z_STRVAL_PP(tmp_function), key_len);
+                               key = STR_ALLOC(Z_STRLEN_P(tmp_function), 0);
+                               zend_str_tolower_copy(key->val, Z_STRVAL_P(tmp_function), Z_STRLEN_P(tmp_function));
 
-                               if (zend_hash_find(EG(function_table), key, key_len+1, (void**)&f) == FAILURE) {
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to add a non existent function '%s'", Z_STRVAL_PP(tmp_function));
+                               if ((f = zend_hash_find_ptr(EG(function_table), key)) == NULL) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to add a non existent function '%s'", Z_STRVAL_P(tmp_function));
                                        return;
                                }
 
-                               MAKE_STD_ZVAL(function_copy);
-                               ZVAL_STRING(function_copy, f->common.function_name, 1);
-                               zend_hash_update(service->soap_functions.ft, key, key_len+1, &function_copy, sizeof(zval *), NULL);
+                               ZVAL_STR(&function_copy, STR_COPY(f->common.function_name));
+                               zend_hash_update(service->soap_functions.ft, key, &function_copy);
 
-                               efree(key);
-                               zend_hash_move_forward_ex(Z_ARRVAL_P(function_name), &pos);
-                       }
+                               STR_RELEASE(key);
+                       } ZEND_HASH_FOREACH_END();
                }
-       } else if (function_name->type == IS_STRING) {
-               char *key;
-               int   key_len;
+       } else if (Z_TYPE_P(function_name) == IS_STRING) {
+               zend_string *key;
                zend_function *f;
 
-               key_len = Z_STRLEN_P(function_name);
-               key = emalloc(key_len + 1);
-               zend_str_tolower_copy(key, Z_STRVAL_P(function_name), key_len);
+               key = STR_ALLOC(Z_STRLEN_P(function_name), 0);
+               zend_str_tolower_copy(key->val, Z_STRVAL_P(function_name), Z_STRLEN_P(function_name));
 
-               if (zend_hash_find(EG(function_table), key, key_len+1, (void**)&f) == FAILURE) {
+               if ((f = zend_hash_find_ptr(EG(function_table), key)) == NULL) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to add a non existent function '%s'", Z_STRVAL_P(function_name));
                        return;
                }
@@ -1453,11 +1455,10 @@ PHP_METHOD(SoapServer, addFunction)
                        zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0);
                }
 
-               MAKE_STD_ZVAL(function_copy);
-               ZVAL_STRING(function_copy, f->common.function_name, 1);
-               zend_hash_update(service->soap_functions.ft, key, key_len+1, &function_copy, sizeof(zval *), NULL);
-               efree(key);
-       } else if (function_name->type == IS_LONG) {
+               ZVAL_STR(&function_copy, STR_COPY(f->common.function_name));
+               zend_hash_update(service->soap_functions.ft, key, &function_copy);
+               STR_RELEASE(key);
+       } else if (Z_TYPE_P(function_name) == IS_LONG) {
                if (Z_LVAL_P(function_name) == SOAP_FUNCTIONS_ALL) {
                        if (service->soap_functions.ft != NULL) {
                                zend_hash_destroy(service->soap_functions.ft);
@@ -1484,7 +1485,7 @@ PHP_METHOD(SoapServer, handle)
        sdlPtr old_sdl = NULL;
        soapServicePtr service;
        xmlDocPtr doc_request=NULL, doc_return;
-       zval function_name, **params, *soap_obj, *retval;
+       zval function_name, *params, *soap_obj, retval;
        char *fn_name, cont_len[30];
        int num_params = 0, size, i, call_status = 0;
        xmlChar *buf;
@@ -1519,15 +1520,11 @@ PHP_METHOD(SoapServer, handle)
                        sapi_add_header(hdr, sizeof("Location: ")+strlen(service->sdl->source)-1, 1);
                        efree(hdr);
 */
-                       zval readfile, readfile_ret, *param;
-
-                       INIT_ZVAL(readfile);
-                       INIT_ZVAL(readfile_ret);
-                       MAKE_STD_ZVAL(param);
+                       zval readfile, readfile_ret, param;
 
                        sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
-                       ZVAL_STRING(param, service->sdl->source, 1);
-                       ZVAL_STRING(&readfile, "readfile", 1);
+                       ZVAL_STRING(&param, service->sdl->source);
+                       ZVAL_STRING(&readfile, "readfile");
                        if (call_user_function(EG(function_table), NULL, &readfile, &readfile_ret, 1, &param  TSRMLS_CC) == FAILURE) {
                                soap_server_fault("Server", "Couldn't find WSDL", NULL, NULL, NULL TSRMLS_CC);
                        }
@@ -1554,7 +1551,7 @@ PHP_METHOD(SoapServer, handle)
                }
        }
 
-       ALLOC_INIT_ZVAL(retval);
+       ZVAL_NULL(&retval);
 
        if (php_output_start_default(TSRMLS_C) != SUCCESS) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR,"ob_start failed");
@@ -1562,22 +1559,22 @@ PHP_METHOD(SoapServer, handle)
 
        if (ZEND_NUM_ARGS() == 0) {
                if (SG(request_info).request_body && 0 == php_stream_rewind(SG(request_info).request_body)) {
-                       zval **server_vars, **encoding;
+                       zval *server_vars, *encoding;
                        php_stream_filter *zf = NULL;
+                       zend_string *server = STR_INIT("_SERVER", sizeof("_SERVER")-1, 0);
 
-                       zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
-                       if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS &&
-                           Z_TYPE_PP(server_vars) == IS_ARRAY &&
-                           zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) &encoding)==SUCCESS &&
-                           Z_TYPE_PP(encoding) == IS_STRING) {
+                       zend_is_auto_global(server TSRMLS_CC);
+                       if ((server_vars = zend_hash_find(&EG(symbol_table).ht, server)) != NULL &&
+                           Z_TYPE_P(server_vars) == IS_ARRAY &&
+                           (encoding = zend_hash_str_find(Z_ARRVAL_P(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING")-1)) != NULL &&
+                           Z_TYPE_P(encoding) == IS_STRING) {
 
-                               if (strcmp(Z_STRVAL_PP(encoding),"gzip") == 0
-                               ||  strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0
-                               ||  strcmp(Z_STRVAL_PP(encoding),"deflate") == 0
+                               if (strcmp(Z_STRVAL_P(encoding),"gzip") == 0
+                               ||  strcmp(Z_STRVAL_P(encoding),"x-gzip") == 0
+                               ||  strcmp(Z_STRVAL_P(encoding),"deflate") == 0
                                ) {
                                        zval filter_params;
 
-                                       INIT_PZVAL(&filter_params);
                                        array_init_size(&filter_params, 1);
                                        add_assoc_long_ex(&filter_params, ZEND_STRS("window"), 0x2f); /* ANY WBITS */
 
@@ -1588,13 +1585,16 @@ PHP_METHOD(SoapServer, handle)
                                                php_stream_filter_append(&SG(request_info).request_body->readfilters, zf);
                                        } else {
                                                php_error_docref(NULL TSRMLS_CC, E_WARNING,"Can't uncompress compressed request");
+                                               STR_RELEASE(server);
                                                return;
                                        }
                                } else {
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING,"Request is compressed with unknown compression '%s'",Z_STRVAL_PP(encoding));
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING,"Request is compressed with unknown compression '%s'",Z_STRVAL_P(encoding));
+                                       STR_RELEASE(server);
                                        return;
                                }
                        }
+                       STR_RELEASE(server);
 
                        doc_request = soap_xmlParseFile("php://input" TSRMLS_CC);
 
@@ -1640,10 +1640,12 @@ PHP_METHOD(SoapServer, handle)
        xmlFreeDoc(doc_request);
 
        if (EG(exception)) {
+               zval exception_object;
+
+               ZVAL_OBJ(&exception_object, EG(exception));
                php_output_discard(TSRMLS_C);
-               if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
-                   instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
-                       soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
+               if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry TSRMLS_CC)) {
+                       soap_server_fault_ex(function, &exception_object, NULL TSRMLS_CC);
                }
                goto fail;
        }
@@ -1652,13 +1654,13 @@ PHP_METHOD(SoapServer, handle)
 
        soap_obj = NULL;
        if (service->type == SOAP_OBJECT) {
-               soap_obj = service->soap_object;
+               soap_obj = &service->soap_object;
                function_table = &((Z_OBJCE_P(soap_obj))->function_table);
        } else if (service->type == SOAP_CLASS) {
 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
                /* If persistent then set soap_obj from from the previous created session (if available) */
                if (service->soap_class.persistance == SOAP_PERSISTENCE_SESSION) {
-                       zval **tmp_soap;
+                       zval *tmp_soap;
 
                        if (PS(session_status) != php_session_active &&
                            PS(session_status) != php_session_disabled) {
@@ -1666,36 +1668,34 @@ PHP_METHOD(SoapServer, handle)
                        }
 
                        /* Find the soap object and assign */
-                       if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name"), (void **) &tmp_soap) == SUCCESS &&
-                           Z_TYPE_PP(tmp_soap) == IS_OBJECT &&
-                           Z_OBJCE_PP(tmp_soap) == service->soap_class.ce) {
-                               soap_obj = *tmp_soap;
+                       if ((tmp_soap = zend_hash_str_find(Z_ARRVAL(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name")-1)) != NULL &&
+                           Z_TYPE_P(tmp_soap) == IS_OBJECT &&
+                           Z_OBJCE_P(tmp_soap) == service->soap_class.ce) {
+                               soap_obj = tmp_soap;
                        }
                }
 #endif
                /* If new session or something weird happned */
                if (soap_obj == NULL) {
-                       zval *tmp_soap;
+                       zval tmp_soap;
 
-                       MAKE_STD_ZVAL(tmp_soap);
-                       object_init_ex(tmp_soap, service->soap_class.ce);
+                       object_init_ex(&tmp_soap, service->soap_class.ce);
 
                        /* Call constructor */
-                       if (zend_hash_exists(&Z_OBJCE_P(tmp_soap)->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) {
+                       if (zend_hash_str_exists(&Z_OBJCE(tmp_soap)->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1)) {
                                zval c_ret, constructor;
 
-                               INIT_ZVAL(c_ret);
-                               INIT_ZVAL(constructor);
-
-                               ZVAL_STRING(&constructor, ZEND_CONSTRUCTOR_FUNC_NAME, 1);
+                               ZVAL_STRING(&constructor, ZEND_CONSTRUCTOR_FUNC_NAME);
                                if (call_user_function(NULL, &tmp_soap, &constructor, &c_ret, service->soap_class.argc, service->soap_class.argv TSRMLS_CC) == FAILURE) {
                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error calling constructor");
                                }
                                if (EG(exception)) {
+                                       zval exception_object;
+
+                                       ZVAL_OBJ(&exception_object, EG(exception));
                                        php_output_discard(TSRMLS_C);
-                                       if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
-                                           instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
-                                               soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
+                                       if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry TSRMLS_CC)) {
+                                               soap_server_fault_ex(function, &exception_object, NULL TSRMLS_CC);
                                        }
                                        zval_dtor(&constructor);
                                        zval_dtor(&c_ret);
@@ -1705,26 +1705,25 @@ PHP_METHOD(SoapServer, handle)
                                zval_dtor(&constructor);
                                zval_dtor(&c_ret);
                        } else {
-                               int class_name_len = strlen(service->soap_class.ce->name);
+                               int class_name_len = service->soap_class.ce->name->len;
                                char *class_name = emalloc(class_name_len+1);
 
-                               memcpy(class_name, service->soap_class.ce->name,class_name_len+1);
-                               if (zend_hash_exists(&Z_OBJCE_P(tmp_soap)->function_table, php_strtolower(class_name, class_name_len), class_name_len+1)) {
+                               memcpy(class_name, service->soap_class.ce->name->val, class_name_len+1);
+                               if (zend_hash_str_exists(&Z_OBJCE(tmp_soap)->function_table, php_strtolower(class_name, class_name_len), class_name_len)) {
                                        zval c_ret, constructor;
 
-                                       INIT_ZVAL(c_ret);
-                                       INIT_ZVAL(constructor);
-
-                                       ZVAL_STRING(&constructor, service->soap_class.ce->name, 1);
+                                       ZVAL_STR(&constructor, STR_COPY(service->soap_class.ce->name));
                                        if (call_user_function(NULL, &tmp_soap, &constructor, &c_ret, service->soap_class.argc, service->soap_class.argv TSRMLS_CC) == FAILURE) {
                                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error calling constructor");
                                        }
 
                                        if (EG(exception)) {
+                                               zval exception_object;
+
+                                               ZVAL_OBJ(&exception_object, EG(exception));
                                                php_output_discard(TSRMLS_C);
-                                               if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
-                                                   instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
-                                                       soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
+                                               if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry TSRMLS_CC)) {
+                                                       soap_server_fault_ex(function, &exception_object, NULL TSRMLS_CC);
                                                }
                                                zval_dtor(&constructor);
                                                zval_dtor(&c_ret);
@@ -1741,15 +1740,15 @@ PHP_METHOD(SoapServer, handle)
 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
                        /* If session then update session hash with new object */
                        if (service->soap_class.persistance == SOAP_PERSISTENCE_SESSION) {
-                               zval **tmp_soap_pp;
-                               if (zend_hash_update(Z_ARRVAL_P(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name"), &tmp_soap, sizeof(zval *), (void **)&tmp_soap_pp) == SUCCESS) {
-                                       soap_obj = *tmp_soap_pp;
+                               zval *tmp_soap_pp;
+                               if ((tmp_soap_pp = zend_hash_str_update(Z_ARRVAL(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name")-1, &tmp_soap)) != NULL) {
+                                       soap_obj = tmp_soap_pp;
                                }
                        } else {
-                               soap_obj = tmp_soap;
+                               soap_obj = &tmp_soap;
                        }
 #else
-                       soap_obj = tmp_soap;
+                       soap_obj = &tmp_soap;
 #endif
 
                }
@@ -1781,11 +1780,11 @@ PHP_METHOD(SoapServer, handle)
                        }
 #endif
                        fn_name = estrndup(Z_STRVAL(h->function_name),Z_STRLEN(h->function_name));
-                       if (zend_hash_exists(function_table, php_strtolower(fn_name, Z_STRLEN(h->function_name)), Z_STRLEN(h->function_name) + 1) ||
+                       if (zend_hash_str_exists(function_table, php_strtolower(fn_name, Z_STRLEN(h->function_name)), Z_STRLEN(h->function_name)) ||
                            ((service->type == SOAP_CLASS || service->type == SOAP_OBJECT) &&
-                            zend_hash_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)))) {
+                            zend_hash_str_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
                                if (service->type == SOAP_CLASS || service->type == SOAP_OBJECT) {
-                                       call_status = call_user_function(NULL, &soap_obj, &h->function_name, &h->retval, h->num_params, h->parameters TSRMLS_CC);
+                                       call_status = call_user_function(NULL, soap_obj, &h->function_name, &h->retval, h->num_params, h->parameters TSRMLS_CC);
                                } else {
                                        call_status = call_user_function(EG(function_table), NULL, &h->function_name, &h->retval, h->num_params, h->parameters TSRMLS_CC);
                                }
@@ -1795,31 +1794,35 @@ PHP_METHOD(SoapServer, handle)
                                }
                                if (Z_TYPE(h->retval) == IS_OBJECT &&
                                    instanceof_function(Z_OBJCE(h->retval), soap_fault_class_entry TSRMLS_CC)) {
-                                       zval *headerfault = NULL, **tmp;
+//???                                  zval *headerfault = NULL;
+                                       zval *tmp;
 
-                                       if (zend_hash_find(Z_OBJPROP(h->retval), "headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS &&
-                                           Z_TYPE_PP(tmp) != IS_NULL) {
-                                               headerfault = *tmp;
+                                       if ((tmp = zend_hash_str_find(Z_OBJPROP(h->retval), "headerfault", sizeof("headerfault")-1)) != NULL &&
+                                           Z_TYPE_P(tmp) != IS_NULL) {
+//???                                          headerfault = tmp;
                                        }
                                        php_output_discard(TSRMLS_C);
                                        soap_server_fault_ex(function, &h->retval, h TSRMLS_CC);
                                        efree(fn_name);
-                                       if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(&soap_obj);}
+                                       if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);}
                                        goto fail;
                                } else if (EG(exception)) {
+                                       zval exception_object;
+
+                                       ZVAL_OBJ(&exception_object, EG(exception));
                                        php_output_discard(TSRMLS_C);
-                                       if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
-                                           instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
-                                               zval *headerfault = NULL, **tmp;
+                                       if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry TSRMLS_CC)) {
+//???                                          zval *headerfault = NULL;
+                                               zval *tmp;
 
-                                               if (zend_hash_find(Z_OBJPROP_P(EG(exception)), "headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS &&
-                                                   Z_TYPE_PP(tmp) != IS_NULL) {
-                                                       headerfault = *tmp;
+                                               if ((tmp = zend_hash_str_find(Z_OBJPROP(exception_object), "headerfault", sizeof("headerfault")-1)) != NULL &&
+                                                   Z_TYPE_P(tmp) != IS_NULL) {
+//???                                                  headerfault = tmp;
                                                }
-                                               soap_server_fault_ex(function, EG(exception), h TSRMLS_CC);
+                                               soap_server_fault_ex(function, &exception_object, h TSRMLS_CC);
                                        }
                                        efree(fn_name);
-                                       if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(&soap_obj);}
+                                       if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);}
                                        goto fail;
                                }
                        } else if (h->mustUnderstand) {
@@ -1830,24 +1833,24 @@ PHP_METHOD(SoapServer, handle)
        }
 
        fn_name = estrndup(Z_STRVAL(function_name),Z_STRLEN(function_name));
-       if (zend_hash_exists(function_table, php_strtolower(fn_name, Z_STRLEN(function_name)), Z_STRLEN(function_name) + 1) ||
+       if (zend_hash_str_exists(function_table, php_strtolower(fn_name, Z_STRLEN(function_name)), Z_STRLEN(function_name)) ||
            ((service->type == SOAP_CLASS || service->type == SOAP_OBJECT) &&
-            zend_hash_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)))) {
+            zend_hash_str_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
                if (service->type == SOAP_CLASS || service->type == SOAP_OBJECT) {
-                       call_status = call_user_function(NULL, &soap_obj, &function_name, retval, num_params, params TSRMLS_CC);
+                       call_status = call_user_function(NULL, soap_obj, &function_name, &retval, num_params, params TSRMLS_CC);
                        if (service->type == SOAP_CLASS) {
 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
                                if (service->soap_class.persistance != SOAP_PERSISTENCE_SESSION) {
-                                       zval_ptr_dtor(&soap_obj);
+                                       zval_ptr_dtor(soap_obj);
                                        soap_obj = NULL;
                                }
 #else
-                               zval_ptr_dtor(&soap_obj);
+                               zval_ptr_dtor(soap_obj);
                                soap_obj = NULL;
 #endif
                        }
                } else {
-                       call_status = call_user_function(EG(function_table), NULL, &function_name, retval, num_params, params TSRMLS_CC);
+                       call_status = call_user_function(EG(function_table), NULL, &function_name, &retval, num_params, params TSRMLS_CC);
                }
        } else {
                php_error(E_ERROR, "Function '%s' doesn't exist", Z_STRVAL(function_name));
@@ -1855,10 +1858,12 @@ PHP_METHOD(SoapServer, handle)
        efree(fn_name);
 
        if (EG(exception)) {
+               zval exception_object;
+
+               ZVAL_OBJ(&exception_object, EG(exception));
                php_output_discard(TSRMLS_C);
-               if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
-                   instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
-                       soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
+               if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry TSRMLS_CC)) {
+                       soap_server_fault_ex(function, &exception_object, NULL TSRMLS_CC);
                }
                if (service->type == SOAP_CLASS) {
 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
@@ -1866,7 +1871,7 @@ PHP_METHOD(SoapServer, handle)
 #else
                        if (soap_obj) {
 #endif
-                         zval_ptr_dtor(&soap_obj);
+                               zval_ptr_dtor(soap_obj);
                        }
                }
                goto fail;
@@ -1875,10 +1880,10 @@ PHP_METHOD(SoapServer, handle)
        if (call_status == SUCCESS) {
                char *response_name;
 
-               if (Z_TYPE_P(retval) == IS_OBJECT &&
-                   instanceof_function(Z_OBJCE_P(retval), soap_fault_class_entry TSRMLS_CC)) {
+               if (Z_TYPE(retval) == IS_OBJECT &&
+                   instanceof_function(Z_OBJCE(retval), soap_fault_class_entry TSRMLS_CC)) {
                        php_output_discard(TSRMLS_C);
-                       soap_server_fault_ex(function, retval, NULL TSRMLS_CC);
+                       soap_server_fault_ex(function, &retval, NULL TSRMLS_CC);
                        goto fail;
                }
 
@@ -1889,7 +1894,7 @@ PHP_METHOD(SoapServer, handle)
                        memcpy(response_name,Z_STRVAL(function_name),Z_STRLEN(function_name));
                        memcpy(response_name+Z_STRLEN(function_name),"Response",sizeof("Response"));
                }
-               doc_return = serialize_response_call(function, response_name, service->uri, retval, soap_headers, soap_version TSRMLS_CC);
+               doc_return = serialize_response_call(function, response_name, service->uri, &retval, soap_headers, soap_version TSRMLS_CC);
                efree(response_name);
        } else {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function '%s' call failed", Z_STRVAL(function_name));
@@ -1897,10 +1902,12 @@ PHP_METHOD(SoapServer, handle)
        }
 
        if (EG(exception)) {
+               zval exception_object;
+
+               ZVAL_OBJ(&exception_object, EG(exception));
                php_output_discard(TSRMLS_C);
-               if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
-                   instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
-                       soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
+               if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry TSRMLS_CC)) {
+                       soap_server_fault_ex(function, &exception_object, NULL TSRMLS_CC);
                }
                if (service->type == SOAP_CLASS) {
 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
@@ -1908,7 +1915,7 @@ PHP_METHOD(SoapServer, handle)
 #else
                        if (soap_obj) {
 #endif
-                         zval_ptr_dtor(&soap_obj);
+                               zval_ptr_dtor(soap_obj);
                        }
                }
                goto fail;
@@ -2055,8 +2062,9 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade
        char cont_len[30];
        int size;
        xmlDocPtr doc_return;
-       zval **agent_name;
+       zval *agent_name;
        int use_http_error_status = 1;
+       zend_string *server;
 
        soap_version = SOAP_GLOBAL(soap_version);
 
@@ -2064,11 +2072,12 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade
 
        xmlDocDumpMemory(doc_return, &buf, &size);
 
-       zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC);
-       if (PG(http_globals)[TRACK_VARS_SERVER] &&
-               zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &agent_name) == SUCCESS &&
-               Z_TYPE_PP(agent_name) == IS_STRING) {
-               if (strncmp(Z_STRVAL_PP(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) {
+       server = STR_INIT("_SERVER", sizeof("_SERVER") - 1, 0);
+       zend_is_auto_global(server TSRMLS_CC);
+       if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF &&
+               (agent_name = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) != NULL &&
+               Z_TYPE_P(agent_name) == IS_STRING) {
+               if (strncmp(Z_STRVAL_P(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) {
                        use_http_error_status = 0;
                }
        }
@@ -2102,8 +2111,7 @@ static void soap_server_fault(char* code, char* string, char *actor, zval* detai
 {
        zval ret;
 
-       INIT_ZVAL(ret);
-
+       ZVAL_NULL(&ret);
        set_soap_fault(&ret, NULL, code, string, actor, details, name TSRMLS_CC);
        /* TODO: Which function */
        soap_server_fault_ex(NULL, &ret, NULL TSRMLS_CC);
@@ -2132,11 +2140,11 @@ 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;
+               zval *tmp;
                int use_exceptions = 0;
 
-               if (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) {
+               if ((tmp = zend_hash_str_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object)), "_exceptions", sizeof("_exceptions")-1)) == NULL ||
+                    Z_TYPE_P(tmp) != IS_FALSE) {
                     use_exceptions = 1;
                }
 
@@ -2146,19 +2154,19 @@ static void soap_error_handler(int error_num, const char *error_filename, const
                     error_num == E_ERROR || 
                     error_num == E_PARSE) &&
                    use_exceptions) {
-                       zval *fault, *exception;
+                       zval *fault;
                        char* code = SOAP_GLOBAL(error_code);
                        char buffer[1024];
                        int buffer_len;
-                       zval outbuf, outbuflen;
+//???                  zval outbuf, outbuflen;
 #ifdef va_copy
                        va_list argcopy;
 #endif
-                       zend_object_store_bucket *old_objects;
+//???                  zend_object_store_bucket *old_objects;
                        int old = PG(display_errors);
 
-                       INIT_ZVAL(outbuf);
-                       INIT_ZVAL(outbuflen);
+//???                  INIT_ZVAL(outbuf);
+//???                  INIT_ZVAL(outbuflen);
 #ifdef va_copy
                        va_copy(argcopy, args);
                        buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, argcopy);
@@ -2175,12 +2183,11 @@ static void soap_error_handler(int error_num, const char *error_filename, const
                                code = "Client";
                        }
                        fault = add_soap_fault(SOAP_GLOBAL(error_object), code, buffer, NULL, NULL TSRMLS_CC);
-                       MAKE_STD_ZVAL(exception);
-                       MAKE_COPY_ZVAL(&fault, exception);
-                       zend_throw_exception_object(exception TSRMLS_CC);
+                       Z_ADDREF_P(fault);
+                       zend_throw_exception_object(fault TSRMLS_CC);
 
-                       old_objects = EG(objects_store).object_buckets;
-                       EG(objects_store).object_buckets = NULL;
+//???                  old_objects = EG(objects_store).object_buckets;
+//???                  EG(objects_store).object_buckets = NULL;
                        PG(display_errors) = 0;
                        SG(sapi_headers).http_status_line = NULL;
                        zend_try {
@@ -2195,7 +2202,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const
                                SG(sapi_headers).http_status_line = _old_http_status_line;
                                SG(sapi_headers).http_response_code = _old_http_response_code;
                        } zend_end_try();
-                       EG(objects_store).object_buckets = old_objects;
+//???                  EG(objects_store).object_buckets = old_objects;
                        PG(display_errors) = old;
                        zend_bailout();
                } else if (!use_exceptions ||
@@ -2220,17 +2227,18 @@ static void soap_error_handler(int error_num, const char *error_filename, const
 
                        char* code = SOAP_GLOBAL(error_code);
                        char buffer[1024];
-                       zval *outbuf = NULL;
-                       zval **tmp;
+                       zval outbuf;
+                       zval *tmp;
                        soapServicePtr service;
 
+                       ZVAL_UNDEF(&outbuf);
                        if (code == NULL) {
                                code = "Server";
                        }
                        if (SOAP_GLOBAL(error_object) &&
                            Z_TYPE_P(SOAP_GLOBAL(error_object)) == IS_OBJECT &&
                            instanceof_function(Z_OBJCE_P(SOAP_GLOBAL(error_object)), soap_server_class_entry TSRMLS_CC) &&
-                       zend_hash_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object)), "service", sizeof("service"), (void **)&tmp) != FAILURE &&
+                       (tmp = zend_hash_str_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object)), "service", sizeof("service")-1)) != NULL &&
                                (service = (soapServicePtr)zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service)) &&
                                !service->send_errors) {
                                strcpy(buffer, "Internal Error");
@@ -2238,7 +2246,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const
                                int buffer_len;
                                zval outbuflen;
 
-                               INIT_ZVAL(outbuflen);
+//???                          INIT_ZVAL(outbuflen);
 
 #ifdef va_copy
                                va_copy(argcopy, args);
@@ -2254,14 +2262,12 @@ static void soap_error_handler(int error_num, const char *error_filename, const
 
                                /* Get output buffer and send as fault detials */
                                if (php_output_get_length(&outbuflen TSRMLS_CC) != FAILURE && Z_LVAL(outbuflen) != 0) {
-                                       ALLOC_INIT_ZVAL(outbuf);
-                                       php_output_get_contents(outbuf TSRMLS_CC);
+                                       php_output_get_contents(&outbuf TSRMLS_CC);
                                }
                                php_output_discard(TSRMLS_C);
 
                        }
-                       INIT_ZVAL(fault_obj);
-                       set_soap_fault(&fault_obj, NULL, code, buffer, NULL, outbuf, NULL TSRMLS_CC);
+                       set_soap_fault(&fault_obj, NULL, code, buffer, NULL, &outbuf, NULL TSRMLS_CC);
                        fault = 1;
                }
 
@@ -2323,6 +2329,7 @@ PHP_METHOD(SoapClient, SoapClient)
        long cache_wsdl;
        sdlPtr sdl = NULL;
        HashTable *typemap_ht = NULL;
+       zval *this_ptr = getThis();
 
        SOAP_CLIENT_BEGIN_CODE();
 
@@ -2338,173 +2345,174 @@ PHP_METHOD(SoapClient, SoapClient)
 
        if (options != NULL) {
                HashTable *ht = Z_ARRVAL_P(options);
-               zval **tmp;
+               zval *tmp;
 
                if (Z_TYPE_P(wsdl) == IS_NULL) {
                        /* Fetching non-WSDL mode options */
-                       if (zend_hash_find(ht, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) == IS_STRING) {
-                               add_property_stringl(this_ptr, "uri", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                       if ((tmp = zend_hash_str_find(ht, "uri", sizeof("uri")-1)) != NULL &&
+                           Z_TYPE_P(tmp) == IS_STRING) {
+                               add_property_str(this_ptr, "uri", STR_COPY(Z_STR_P(tmp)));
                        } else {
                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "'uri' option is required in nonWSDL mode");
                        }
 
-                       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));
+                       if ((tmp = zend_hash_str_find(ht, "style", sizeof("style")-1)) != NULL &&
+                                       Z_TYPE_P(tmp) == IS_LONG &&
+                                       (Z_LVAL_P(tmp) == SOAP_RPC || Z_LVAL_P(tmp) == SOAP_DOCUMENT)) {
+                               add_property_long(this_ptr, "style", Z_LVAL_P(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));
+                       if ((tmp = zend_hash_str_find(ht, "use", sizeof("use")-1)) != NULL &&
+                                       Z_TYPE_P(tmp) == IS_LONG &&
+                                       (Z_LVAL_P(tmp) == SOAP_LITERAL || Z_LVAL_P(tmp) == SOAP_ENCODED)) {
+                               add_property_long(this_ptr, "use", Z_LVAL_P(tmp));
                        }
                }
 
-               if (zend_hash_find(ht, "stream_context", sizeof("stream_context"), (void**)&tmp) == SUCCESS &&
-                               Z_TYPE_PP(tmp) == IS_RESOURCE) {
-                       context = php_stream_context_from_zval(*tmp, 1);
-                       zend_list_addref(context->rsrc_id);
+               if ((tmp = zend_hash_str_find(ht, "stream_context", sizeof("stream_context")-1)) != NULL &&
+                               Z_TYPE_P(tmp) == IS_RESOURCE) {
+                       context = php_stream_context_from_zval(tmp, 1);
+                       Z_ADDREF_P(tmp);
                }
 
-               if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                       add_property_stringl(this_ptr, "location", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+               if ((tmp = zend_hash_str_find(ht, "location", sizeof("location")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                       add_property_str(this_ptr, "location", STR_COPY(Z_STR_P(tmp)));
                } else if (Z_TYPE_P(wsdl) == IS_NULL) {
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' option is required in nonWSDL mode");
                }
 
-               if (zend_hash_find(ht, "soap_version", sizeof("soap_version"), (void**)&tmp) == SUCCESS) {
-                       if (Z_TYPE_PP(tmp) == IS_LONG ||
-                           (Z_LVAL_PP(tmp) == SOAP_1_1 && Z_LVAL_PP(tmp) == SOAP_1_2)) {
-                               soap_version = Z_LVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(ht, "soap_version", sizeof("soap_version")-1)) != NULL) {
+                       if (Z_TYPE_P(tmp) == IS_LONG ||
+                           (Z_LVAL_P(tmp) == SOAP_1_1 && Z_LVAL_P(tmp) == SOAP_1_2)) {
+                               soap_version = Z_LVAL_P(tmp);
                        }
                }
-               if (zend_hash_find(ht, "login", sizeof("login"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                       add_property_stringl(this_ptr, "_login", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-                       if (zend_hash_find(ht, "password", sizeof("password"), (void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) == IS_STRING) {
-                               add_property_stringl(this_ptr, "_password", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+               if ((tmp = zend_hash_str_find(ht, "login", sizeof("login")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                       add_property_str(this_ptr, "_login", STR_COPY(Z_STR_P(tmp)));
+                       if ((tmp = zend_hash_str_find(ht, "password", sizeof("password")-1)) != NULL &&
+                           Z_TYPE_P(tmp) == IS_STRING) {
+                               add_property_str(this_ptr, "_password", STR_COPY(Z_STR_P(tmp)));
                        }
-                       if (zend_hash_find(ht, "authentication", sizeof("authentication"), (void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) == IS_LONG &&
-                           Z_LVAL_PP(tmp) == SOAP_AUTHENTICATION_DIGEST) {
+                       if ((tmp = zend_hash_str_find(ht, "authentication", sizeof("authentication")-1)) != NULL &&
+                           Z_TYPE_P(tmp) == IS_LONG &&
+                           Z_LVAL_P(tmp) == SOAP_AUTHENTICATION_DIGEST) {
                                add_property_null(this_ptr, "_digest");
                        }
                }
-               if (zend_hash_find(ht, "proxy_host", sizeof("proxy_host"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                       add_property_stringl(this_ptr, "_proxy_host", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-                       if (zend_hash_find(ht, "proxy_port", sizeof("proxy_port"), (void**)&tmp) == SUCCESS) {
-                               convert_to_long(*tmp);
-                               add_property_long(this_ptr, "_proxy_port", Z_LVAL_PP(tmp));
+               if ((tmp = zend_hash_str_find(ht, "proxy_host", sizeof("proxy_host")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                       add_property_str(this_ptr, "_proxy_host", STR_COPY(Z_STR_P(tmp)));
+                       if ((tmp = zend_hash_str_find(ht, "proxy_port", sizeof("proxy_port")-1)) != NULL) {
+                               convert_to_long(tmp);
+                               add_property_long(this_ptr, "_proxy_port", Z_LVAL_P(tmp));
                        }
-                       if (zend_hash_find(ht, "proxy_login", sizeof("proxy_login"), (void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) == IS_STRING) {
-                               add_property_stringl(this_ptr, "_proxy_login", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-                               if (zend_hash_find(ht, "proxy_password", sizeof("proxy_password"), (void**)&tmp) == SUCCESS &&
-                                   Z_TYPE_PP(tmp) == IS_STRING) {
-                                       add_property_stringl(this_ptr, "_proxy_password", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                       if ((tmp = zend_hash_str_find(ht, "proxy_login", sizeof("proxy_login")-1)) != NULL &&
+                           Z_TYPE_P(tmp) == IS_STRING) {
+                               add_property_str(this_ptr, "_proxy_login", STR_COPY(Z_STR_P(tmp)));
+                               if ((tmp = zend_hash_str_find(ht, "proxy_password", sizeof("proxy_password")-1)) != NULL &&
+                                   Z_TYPE_P(tmp) == IS_STRING) {
+                                       add_property_str(this_ptr, "_proxy_password", STR_COPY(Z_STR_P(tmp)));
                                }
                        }
                }
-               if (zend_hash_find(ht, "local_cert", sizeof("local_cert"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
+               if ((tmp = zend_hash_str_find(ht, "local_cert", sizeof("local_cert")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
                  if (!context) {
                        context = php_stream_context_alloc(TSRMLS_C);
                  }
-                       php_stream_context_set_option(context, "ssl", "local_cert", *tmp);
-                       if (zend_hash_find(ht, "passphrase", sizeof("passphrase"), (void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) == IS_STRING) {
-                               php_stream_context_set_option(context, "ssl", "passphrase", *tmp);
+                       php_stream_context_set_option(context, "ssl", "local_cert", tmp);
+                       if ((tmp = zend_hash_str_find(ht, "passphrase", sizeof("passphrase")-1)) != NULL &&
+                           Z_TYPE_P(tmp) == IS_STRING) {
+                               php_stream_context_set_option(context, "ssl", "passphrase", tmp);
                        }
                }
-               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) {
+               if ((tmp = zend_hash_str_find(ht, "trace", sizeof("trace")-1)) != NULL &&
+                   (Z_TYPE_P(tmp) == IS_TRUE ||
+                    (Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == 1))) {
                        add_property_long(this_ptr, "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) {
+               if ((tmp = zend_hash_str_find(ht, "exceptions", sizeof("exceptions")-1)) != NULL &&
+                   (Z_TYPE_P(tmp) == IS_FALSE ||
+                    (Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == 0))) {
                        add_property_bool(this_ptr, "_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));
+               if ((tmp = zend_hash_str_find(ht, "compression", sizeof("compression")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_LONG &&
+             zend_hash_str_exists(EG(function_table), "gzinflate", sizeof("gzinflate")-1) &&
+             zend_hash_str_exists(EG(function_table), "gzdeflate", sizeof("gzdeflate")-1) &&
+             zend_hash_str_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1) &&
+             zend_hash_str_exists(EG(function_table), "gzcompress", sizeof("gzcompress")-1) &&
+             zend_hash_str_exists(EG(function_table), "gzencode", sizeof("gzencode")-1)) {
+                       add_property_long(this_ptr, "compression", Z_LVAL_P(tmp));
                }
-               if (zend_hash_find(ht, "encoding", sizeof("encoding"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
+               if ((tmp = zend_hash_str_find(ht, "encoding", sizeof("encoding")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
                        xmlCharEncodingHandlerPtr encoding;
                
-                       encoding = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
+                       encoding = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp));
                        if (encoding == NULL) {
-                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_PP(tmp));
+                               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_P(tmp));
                        } else {
                                xmlCharEncCloseFunc(encoding);
-                               add_property_stringl(this_ptr, "_encoding", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                               add_property_str(this_ptr, "_encoding", STR_COPY(Z_STR_P(tmp)));
                        }
                }
-               if (zend_hash_find(ht, "classmap", sizeof("classmap"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_ARRAY) {
-                       zval *class_map;
-
-                       MAKE_STD_ZVAL(class_map);
-                       MAKE_COPY_ZVAL(tmp, class_map);
-                       Z_DELREF_P(class_map);
-
-                       add_property_zval(this_ptr, "_classmap", class_map);
+               if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_ARRAY) {
+//???                  zval *class_map;
+//???
+//???                  MAKE_STD_ZVAL(class_map);
+//???                  MAKE_COPY_ZVAL(tmp, class_map);
+//???                  Z_DELREF_P(class_map);
+//???
+                       add_property_zval(this_ptr, "_classmap", tmp);
                }
 
-               if (zend_hash_find(ht, "typemap", sizeof("typemap"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_ARRAY &&
-                       zend_hash_num_elements(Z_ARRVAL_PP(tmp)) > 0) {
-                       typemap_ht = Z_ARRVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_ARRAY &&
+                       zend_hash_num_elements(Z_ARRVAL_P(tmp)) > 0) {
+                       typemap_ht = Z_ARRVAL_P(tmp);
                }
 
-               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));
+               if ((tmp = zend_hash_str_find(ht, "features", sizeof("features")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_LONG) {
+                       add_property_long(this_ptr, "_features", Z_LVAL_P(tmp));
            }
 
-               if (zend_hash_find(ht, "connection_timeout", sizeof("connection_timeout"), (void**)&tmp) == SUCCESS) {
-                       convert_to_long(*tmp);
-                       if (Z_LVAL_PP(tmp) > 0) {
-                               add_property_long(this_ptr, "_connection_timeout", Z_LVAL_PP(tmp));
+               if ((tmp = zend_hash_str_find(ht, "connection_timeout", sizeof("connection_timeout")-1)) != NULL) {
+                       convert_to_long(tmp);
+                       if (Z_LVAL_P(tmp) > 0) {
+                               add_property_long(this_ptr, "_connection_timeout", Z_LVAL_P(tmp));
                        }
                }
 
                if (context) {
-                       add_property_resource(this_ptr, "_stream_context", context->rsrc_id);
+                       add_property_resource(this_ptr, "_stream_context", context->res);
                }
        
-               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 ((tmp = zend_hash_str_find(ht, "cache_wsdl", sizeof("cache_wsdl")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_LONG) {
+                       cache_wsdl = Z_LVAL_P(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));
+               if ((tmp = zend_hash_str_find(ht, "user_agent", sizeof("user_agent")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                       add_property_str(this_ptr, "_user_agent", STR_COPY(Z_STR_P(tmp)));
                }
                
-               if (zend_hash_find(ht, "keep_alive", sizeof("keep_alive"), (void**)&tmp) == SUCCESS &&
-                               (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) && Z_LVAL_PP(tmp) == 0) {
+               if ((tmp = zend_hash_str_find(ht, "keep_alive", sizeof("keep_alive")-1)) != NULL &&
+                               (Z_TYPE_P(tmp) == IS_FALSE ||
+                                (Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == 0))) {
                        add_property_long(this_ptr, "_keep_alive", 0);
                }
 
-               if (zend_hash_find(ht, "ssl_method", sizeof("ssl_method"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_LONG) {
-                       add_property_long(this_ptr, "_ssl_method", Z_LVAL_PP(tmp));
+               if ((tmp = zend_hash_str_find(ht, "ssl_method", sizeof("ssl_method")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_LONG) {
+                       add_property_long(this_ptr, "_ssl_method", Z_LVAL_P(tmp));
                }
        } else if (Z_TYPE_P(wsdl) == IS_NULL) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' and 'uri' options are required in nonWSDL mode");
@@ -2513,15 +2521,16 @@ PHP_METHOD(SoapClient, SoapClient)
        add_property_long(this_ptr, "_soap_version", soap_version);
 
        if (Z_TYPE_P(wsdl) != IS_NULL) {
-               int    old_soap_version, ret;
+               int    old_soap_version;
+               zend_resource *res;
 
                old_soap_version = SOAP_GLOBAL(soap_version);
                SOAP_GLOBAL(soap_version) = soap_version;
 
                sdl = get_sdl(this_ptr, Z_STRVAL_P(wsdl), cache_wsdl TSRMLS_CC);
-               ret = zend_list_insert(sdl, le_sdl TSRMLS_CC);
+               res = zend_register_resource(NULL, sdl, le_sdl TSRMLS_CC);
 
-               add_property_resource(this_ptr, "sdl", ret);
+               add_property_resource(this_ptr, "sdl", res);
 
                SOAP_GLOBAL(soap_version) = old_soap_version;
        }
@@ -2529,10 +2538,10 @@ PHP_METHOD(SoapClient, SoapClient)
        if (typemap_ht) {
                HashTable *typemap = soap_create_typemap(sdl, typemap_ht TSRMLS_CC);
                if (typemap) {
-                       int ret;
+                       zend_resource *res;
 
-                       ret = zend_list_insert(typemap, le_typemap TSRMLS_CC);
-                       add_property_resource(this_ptr, "typemap", ret);
+                       res = zend_register_resource(NULL, typemap, le_typemap TSRMLS_CC);
+                       add_property_resource(this_ptr, "typemap", res);
                }
        }
        SOAP_CLIENT_END_CODE();
@@ -2545,11 +2554,11 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
        char  *buf;
        int    buf_size;
        zval   func;
-       zval  *params[5];
-       zval **trace;
-       zval **fault;
+       zval  params[5];
+       zval  *trace;
+       zval  *fault;
 
-       INIT_ZVAL(*response);
+       ZVAL_NULL(response);
 
        xmlDocDumpMemory(request, (xmlChar**)&buf, &buf_size);
        if (!buf) {
@@ -2557,52 +2566,46 @@ 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) {
+       if ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL &&
+           Z_LVAL_P(trace) > 0) {
                add_property_stringl(this_ptr, "__last_request", buf, buf_size);
        }
 
-       INIT_ZVAL(func);
-       ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1,0);
-       ALLOC_INIT_ZVAL(params[0]);
-       ZVAL_STRINGL(params[0], buf, buf_size, 1);
-       ALLOC_INIT_ZVAL(params[1]);
+       ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1);
+       ZVAL_STRINGL(&params[0], buf, buf_size);
        if (location == NULL) {
-               ZVAL_NULL(params[1]);
+               ZVAL_NULL(&params[1]);
        } else {
-               ZVAL_STRING(params[1], location, 1);
+               ZVAL_STRING(&params[1], location);
        }
-       ALLOC_INIT_ZVAL(params[2]);
        if (action == NULL) {
-               ZVAL_NULL(params[2]);
+               ZVAL_NULL(&params[2]);
        } else {
-               ZVAL_STRING(params[2], action, 1);
+               ZVAL_STRING(&params[2], action);
        }
-       ALLOC_INIT_ZVAL(params[3]);
-       ZVAL_LONG(params[3], version);
+       ZVAL_LONG(&params[3], version);
+       ZVAL_LONG(&params[4], one_way);
 
-       ALLOC_INIT_ZVAL(params[4]);
-       ZVAL_LONG(params[4], one_way);
-
-       if (call_user_function(NULL, &this_ptr, &func, response, 5, params TSRMLS_CC) != SUCCESS) {
+       if (call_user_function(NULL, this_ptr, &func, response, 5, params TSRMLS_CC) != SUCCESS) {
                add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() failed", NULL, NULL TSRMLS_CC);
                ret = FALSE;
        } else if (Z_TYPE_P(response) != IS_STRING) {
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == FAILURE) {
+               if ((fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) == NULL) {
                        add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() returned non string value", NULL, NULL TSRMLS_CC);
                }
                ret = FALSE;
-       } else 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));
+       } else if ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL &&
+           Z_LVAL_P(trace) > 0) {
+               add_property_str(this_ptr, "__last_response", STR_COPY(Z_STR_P(response)));
        }
+       zval_ptr_dtor(&func);
        zval_ptr_dtor(&params[4]);
        zval_ptr_dtor(&params[3]);
        zval_ptr_dtor(&params[2]);
        zval_ptr_dtor(&params[1]);
        zval_ptr_dtor(&params[0]);
        xmlFree(buf);
-       if (ret && zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
+       if (ret && (fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) != NULL) {
          return FALSE;
        }         
   return ret;
@@ -2612,7 +2615,7 @@ static void do_soap_call(zval* this_ptr,
                          char* function,
                          int function_len,
                          int arg_count,
-                         zval** real_args,
+                         zval* real_args,
                          zval* return_value,
                          char* location,
                          char* soap_action,
@@ -2621,8 +2624,8 @@ static void do_soap_call(zval* this_ptr,
                          zval* output_headers
                          TSRMLS_DC)
 {
-       zval **tmp;
-       zval **trace;
+       zval *tmp;
+       zval *trace;
        sdlPtr sdl = NULL;
        sdlPtr old_sdl = NULL;
        sdlFunctionPtr fn;
@@ -2637,29 +2640,29 @@ static void do_soap_call(zval* this_ptr,
 
        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 ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL
+               && Z_LVAL_P(trace) > 0) {
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "__last_request", sizeof("__last_request")-1);
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response")-1);
        }
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_soap_version", sizeof("_soap_version"), (void **) &tmp) == SUCCESS
-               && Z_LVAL_PP(tmp) == SOAP_1_2) {
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_soap_version", sizeof("_soap_version")-1)) != NULL
+               && Z_LVAL_P(tmp) == SOAP_1_2) {
                soap_version = SOAP_1_2;
        } else {
                soap_version = SOAP_1_1;
        }
 
        if (location == NULL) {
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) == IS_STRING) {
-                 location = Z_STRVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location")-1)) != NULL &&
+                   Z_TYPE_P(tmp) == IS_STRING) {
+                 location = Z_STRVAL_P(tmp);
                }
        }
 
-       if (FIND_SDL_PROPERTY(this_ptr,tmp) != FAILURE) {
+       if (FIND_SDL_PROPERTY(this_ptr,tmp) != NULL) {
                FETCH_SDL_RES(sdl,tmp);
        }
-       if (FIND_TYPEMAP_PROPERTY(this_ptr,tmp) != FAILURE) {
+       if (FIND_TYPEMAP_PROPERTY(this_ptr,tmp) != NULL) {
                FETCH_TYPEMAP_RES(typemap,tmp);
        }
 
@@ -2669,25 +2672,25 @@ static void do_soap_call(zval* this_ptr,
        old_sdl = SOAP_GLOBAL(sdl);
        SOAP_GLOBAL(sdl) = sdl;
        old_encoding = SOAP_GLOBAL(encoding);
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_encoding", sizeof("_encoding"), (void **) &tmp) == SUCCESS &&
-           Z_TYPE_PP(tmp) == IS_STRING) {
-               SOAP_GLOBAL(encoding) = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_encoding", sizeof("_encoding")-1)) != NULL &&
+           Z_TYPE_P(tmp) == IS_STRING) {
+               SOAP_GLOBAL(encoding) = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp));
        } else {
                SOAP_GLOBAL(encoding) = NULL;
        }
        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;
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_classmap", sizeof("_classmap")-1)) != NULL &&
+           Z_TYPE_P(tmp) == IS_ARRAY) {
+               SOAP_GLOBAL(class_map) = Z_ARRVAL_P(tmp);
        } else {
                SOAP_GLOBAL(class_map) = NULL;
        }
        old_typemap = SOAP_GLOBAL(typemap);
        SOAP_GLOBAL(typemap) = typemap;
        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);
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_features", sizeof("_features")-1)) != NULL &&
+           Z_TYPE_P(tmp) == IS_LONG) {
+               SOAP_GLOBAL(features) = Z_LVAL_P(tmp);
        } else {
                SOAP_GLOBAL(features) = 0;
        }
@@ -2733,20 +2736,20 @@ static void do_soap_call(zval* this_ptr,
                                smart_str_appends(&error,function);
                                smart_str_appends(&error,"\") is not a valid method for this service");
                                smart_str_0(&error);
-                               add_soap_fault(this_ptr, "Client", error.c, NULL, NULL TSRMLS_CC);
+                               add_soap_fault(this_ptr, "Client", error.s->val, NULL, NULL TSRMLS_CC);
                                smart_str_free(&error);
                        }
                } else {
-                       zval **uri;
+                       zval *uri;
                        smart_str action = {0};
 
-                       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) {
+                       if ((uri = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri")-1)) == NULL) {
                                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 {
                                if (call_uri == NULL) {
-                                       call_uri = Z_STRVAL_PP(uri);
+                                       call_uri = Z_STRVAL_P(uri);
                                }
                                request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
 
@@ -2759,7 +2762,7 @@ static void do_soap_call(zval* this_ptr,
                                }
                                smart_str_0(&action);
 
-                               ret = do_request(this_ptr, request, location, action.c, soap_version, 0, &response TSRMLS_CC);
+                               ret = do_request(this_ptr, request, location, action.s->val, soap_version, 0, &response TSRMLS_CC);
 
                                smart_str_free(&action);
                                xmlFreeDoc(request);
@@ -2775,32 +2778,26 @@ 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;
-                               zval_copy_ctor(return_value);
+                       zval* fault;
+                       if ((fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) != NULL) {
+                               ZVAL_COPY(return_value, fault);
                        } else {
-                               *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC);
-                               zval_copy_ctor(return_value);
+                               ZVAL_COPY(return_value, add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC));
                        }
                } else {
-                       zval** fault;
-                       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
-                               *return_value = **fault;
-                               zval_copy_ctor(return_value);
+                       zval* fault;
+                       if ((fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) != NULL) {
+                               ZVAL_COPY(return_value, fault);
                        }
                }
 
                if (!EG(exception) &&
                    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)) {
-                       zval *exception;
-
-                       MAKE_STD_ZVAL(exception);
-                       MAKE_COPY_ZVAL(&return_value, exception);
-                       zend_throw_exception_object(exception TSRMLS_CC);
+                   ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions")-1)) == NULL ||
+                          Z_TYPE_P(tmp) != IS_FALSE)) {
+                       Z_ADDREF_P(return_value);
+                       zend_throw_exception_object(return_value TSRMLS_CC);
                }
 
        } zend_catch {
@@ -2825,16 +2822,14 @@ static void do_soap_call(zval* this_ptr,
 
 static void verify_soap_headers_array(HashTable *ht TSRMLS_DC)
 {
-       zval **tmp;
+       zval *tmp;
 
-       zend_hash_internal_pointer_reset(ht);
-       while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
-               if (Z_TYPE_PP(tmp) != IS_OBJECT ||
-                   !instanceof_function(Z_OBJCE_PP(tmp), soap_header_class_entry TSRMLS_CC)) {
+       ZEND_HASH_FOREACH_VAL(ht, tmp) {
+               if (Z_TYPE_P(tmp) != IS_OBJECT ||
+                   !instanceof_function(Z_OBJCE_P(tmp), soap_header_class_entry TSRMLS_CC)) {
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid SOAP header");
                }
-               zend_hash_move_forward(ht);
-       }
+       } ZEND_HASH_FOREACH_END();
 }
 
 
@@ -2849,13 +2844,13 @@ PHP_METHOD(SoapClient, __call)
        zval *headers = NULL;
        zval *output_headers = NULL;
        zval *args;
-       zval **real_args = NULL;
-       zval **param;
+       zval *real_args = NULL;
+       zval *param;
        int arg_count;
-       zval **tmp;
+       zval *tmp;
        zend_bool free_soap_headers = 0;
-
-       HashPosition pos;
+       zval *this_ptr;
+//???  HashPosition pos;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a!zz",
                &function, &function_len, &args, &options, &headers, &output_headers) == FAILURE) {
@@ -2864,19 +2859,19 @@ PHP_METHOD(SoapClient, __call)
 
        if (options) {
                HashTable *hto = Z_ARRVAL_P(options);
-               if (zend_hash_find(hto, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_STRING) {
-                       location = Z_STRVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(hto, "location", sizeof("location")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_STRING) {
+                       location = Z_STRVAL_P(tmp);
                }
 
-               if (zend_hash_find(hto, "soapaction", sizeof("soapaction"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_STRING) {
-                       soap_action = Z_STRVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(hto, "soapaction", sizeof("soapaction")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_STRING) {
+                       soap_action = Z_STRVAL_P(tmp);
                }
 
-               if (zend_hash_find(hto, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
-                       Z_TYPE_PP(tmp) == IS_STRING) {
-                       uri = Z_STRVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(hto, "uri", sizeof("uri")-1)) != NULL &&
+                       Z_TYPE_P(tmp) == IS_STRING) {
+                       uri = Z_STRVAL_P(tmp);
                }
        }
 
@@ -2889,7 +2884,7 @@ PHP_METHOD(SoapClient, __call)
                   instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry TSRMLS_CC)) {
            soap_headers = emalloc(sizeof(HashTable));
                zend_hash_init(soap_headers, 0, NULL, ZVAL_PTR_DTOR, 0);
-               zend_hash_next_index_insert(soap_headers, &headers, sizeof(zval*), NULL);
+               zend_hash_next_index_insert(soap_headers, headers);
                Z_ADDREF_P(headers);
                free_soap_headers = 1;
        } else{
@@ -2898,24 +2893,23 @@ 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);
+       this_ptr = getThis();
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers")-1)) != NULL) {
+               HashTable *default_headers = Z_ARRVAL_P(tmp);
                if (soap_headers) {
                        if (!free_soap_headers) {
                                HashTable *t =  emalloc(sizeof(HashTable));
                                zend_hash_init(t, 0, NULL, ZVAL_PTR_DTOR, 0);
-                               zend_hash_copy(t, soap_headers, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+                               zend_hash_copy(t, soap_headers, zval_add_ref);
                                soap_headers = t;
                                free_soap_headers = 1;
                        }
-                       zend_hash_internal_pointer_reset(default_headers);
-                       while (zend_hash_get_current_data(default_headers, (void**)&tmp) == SUCCESS) {
-                               Z_ADDREF_PP(tmp);
-                               zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL);
-                               zend_hash_move_forward(default_headers);
-                       }
+                       ZEND_HASH_FOREACH_VAL(default_headers, tmp) {
+                               Z_ADDREF_P(tmp);
+                               zend_hash_next_index_insert(soap_headers, tmp);
+                       } ZEND_HASH_FOREACH_END();
                } else {
-                       soap_headers = Z_ARRVAL_P(*tmp);
+                       soap_headers = Z_ARRVAL_P(tmp);
                        free_soap_headers = 0;
                }
        }
@@ -2923,13 +2917,12 @@ PHP_METHOD(SoapClient, __call)
        arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
 
        if (arg_count > 0) {
-               real_args = safe_emalloc(sizeof(zval *), arg_count, 0);
-               for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos);
-                       zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **) &param, &pos) == SUCCESS;
-                       zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos)) {
-                               /*zval_add_ref(param);*/
-                               real_args[i++] = *param;
-               }
+               real_args = safe_emalloc(sizeof(zval), arg_count, 0);
+               ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), param) {
+                       /*zval_add_ref(param);*/
+                       ZVAL_COPY_VALUE(&real_args[i], param);
+                       i++;
+               } ZEND_HASH_FOREACH_END();
        }
        if (output_headers) {
                array_init(output_headers);
@@ -2952,7 +2945,6 @@ PHP_METHOD(SoapClient, __call)
 PHP_METHOD(SoapClient, __getFunctions)
 {
        sdlPtr sdl;
-       HashPosition pos;
 
        FETCH_THIS_SDL(sdl);
 
@@ -2962,16 +2954,13 @@ PHP_METHOD(SoapClient, __getFunctions)
 
        if (sdl) {
                smart_str buf = {0};
-               sdlFunctionPtr *function;
+               sdlFunctionPtr function;
 
                array_init(return_value);
-               zend_hash_internal_pointer_reset_ex(&sdl->functions, &pos);
-               while (zend_hash_get_current_data_ex(&sdl->functions, (void **)&function, &pos) != FAILURE) {
-                       function_to_string((*function), &buf);
-                       add_next_index_stringl(return_value, buf.c, buf.len);
-                       smart_str_free(&buf);
-                       zend_hash_move_forward_ex(&sdl->functions, &pos);
-               }
+               ZEND_HASH_FOREACH_PTR(&sdl->functions, function) {
+                       function_to_string(function, &buf);
+                       add_next_index_str(return_value, buf.s);
+               } ZEND_HASH_FOREACH_END();
        }
 }
 /* }}} */
@@ -2982,7 +2971,6 @@ PHP_METHOD(SoapClient, __getFunctions)
 PHP_METHOD(SoapClient, __getTypes)
 {
        sdlPtr sdl;
-       HashPosition pos;
 
        FETCH_THIS_SDL(sdl);
        
@@ -2991,18 +2979,15 @@ PHP_METHOD(SoapClient, __getTypes)
        }
 
        if (sdl) {
-               sdlTypePtr *type;
+               sdlTypePtr type;
                smart_str buf = {0};
 
                array_init(return_value);
                if (sdl->types) {
-                       zend_hash_internal_pointer_reset_ex(sdl->types, &pos);
-                       while (zend_hash_get_current_data_ex(sdl->types, (void **)&type, &pos) != FAILURE) {
-                               type_to_string((*type), &buf, 0);
-                               add_next_index_stringl(return_value, buf.c, buf.len);
-                               smart_str_free(&buf);
-                               zend_hash_move_forward_ex(sdl->types, &pos);
-                       }
+                       ZEND_HASH_FOREACH_PTR(sdl->types, type) {
+                               type_to_string(type, &buf, 0);
+                               add_next_index_str(return_value, buf.s);
+                       } ZEND_HASH_FOREACH_END();
                }
        }
 }
@@ -3013,14 +2998,14 @@ PHP_METHOD(SoapClient, __getTypes)
    Returns last SOAP request */
 PHP_METHOD(SoapClient, __getLastRequest)
 {
-       zval **tmp;
+       zval *tmp;
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       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);
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_request", sizeof("__last_request")-1)) != NULL) {
+               RETURN_STR(STR_COPY(Z_STR_P(tmp)));
        }
        RETURN_NULL();
 }
@@ -3031,14 +3016,14 @@ PHP_METHOD(SoapClient, __getLastRequest)
    Returns last SOAP response */
 PHP_METHOD(SoapClient, __getLastResponse)
 {
-       zval **tmp;
+       zval *tmp;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        
-       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);
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_response", sizeof("__last_response")-1)) != NULL) {
+               RETURN_STR(STR_COPY(Z_STR_P(tmp)));
        }
        RETURN_NULL();
 }
@@ -3049,14 +3034,14 @@ PHP_METHOD(SoapClient, __getLastResponse)
    Returns last SOAP request headers */
 PHP_METHOD(SoapClient, __getLastRequestHeaders)
 {
-       zval **tmp;
+       zval *tmp;
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        
-       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);
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_request_headers", sizeof("__last_request_headers")-1)) != NULL) {
+               RETURN_STR(STR_COPY(Z_STR_P(tmp)));
        }
        RETURN_NULL();
 }
@@ -3067,14 +3052,14 @@ PHP_METHOD(SoapClient, __getLastRequestHeaders)
    Returns last SOAP response headers */
 PHP_METHOD(SoapClient, __getLastResponseHeaders)
 {
-       zval **tmp;
+       zval *tmp;
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       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);
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_response_headers", sizeof("__last_response_headers")-1)) != NULL) {
+               RETURN_STR(STR_COPY(Z_STR_P(tmp)));
        }
        RETURN_NULL();
 }
@@ -3089,6 +3074,7 @@ PHP_METHOD(SoapClient, __doRequest)
   int   buf_size, location_size, action_size;
   long  version;
   long  one_way = 0;
+  zval *this_ptr = getThis();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssl|l",
            &buf, &buf_size,
@@ -3101,12 +3087,11 @@ PHP_METHOD(SoapClient, __doRequest)
                one_way = 0;
        }
        if (one_way) {
-               if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version, NULL, NULL TSRMLS_CC)) {
+               if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version, 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;
+           return_value TSRMLS_CC)) {
                return;
        }
        RETURN_NULL();
@@ -3122,31 +3107,30 @@ PHP_METHOD(SoapClient, __setCookie)
        char *name;
        char *val = NULL;
        int  name_len, val_len = 0;
-       zval **cookies;
+       zval *cookies;
+       zval *this_ptr = getThis();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &name_len, &val, &val_len) == FAILURE) {
                return;
        }
 
        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 ((cookies = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1)) != NULL) {
+                       zend_hash_str_del(Z_ARRVAL_P(cookies), name, name_len);
                }
        } else {
-               zval *zcookie;
+               zval zcookie;
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE) {
-                       zval *tmp_cookies;
+               if ((cookies = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1)) == NULL) {
+                       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);
+                       array_init(&tmp_cookies);
+                       cookies = zend_hash_str_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1, &tmp_cookies);
                }
 
-               ALLOC_INIT_ZVAL(zcookie);
-               array_init(zcookie);
-               add_index_stringl(zcookie, 0, val, val_len);
-               add_assoc_zval_ex(*cookies, name, name_len+1, zcookie);
+               array_init(&zcookie);
+               add_index_stringl(&zcookie, 0, val, val_len);
+               add_assoc_zval_ex(cookies, name, name_len, &zcookie);
        }
 }
 /* }}} */
@@ -3158,29 +3142,30 @@ PHP_METHOD(SoapClient, __setCookie)
 PHP_METHOD(SoapClient, __setSoapHeaders)
 {
        zval *headers = NULL;
+       zval *this_ptr = getThis();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &headers) == FAILURE) {
                return;
        }
 
        if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"));
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers")-1);
        } 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) {
+               if ((default_headers = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers")-1)) == NULL) {
                        add_property_zval(this_ptr, "__default_headers", 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);
+               zval default_headers;
+
+               array_init(&default_headers);
                Z_ADDREF_P(headers);
-               add_next_index_zval(default_headers, headers);
-               Z_DELREF_P(default_headers);
-               add_property_zval(this_ptr, "__default_headers", default_headers);
+               add_next_index_zval(&default_headers, headers);
+               add_property_zval(this_ptr, "__default_headers", &default_headers);
+               Z_DELREF_P(&default_headers);
        } else{
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid SOAP header");
        }
@@ -3200,42 +3185,44 @@ PHP_METHOD(SoapClient, __setLocation)
 {
        char *location = NULL;
        int  location_len = 0;
-       zval **tmp;
+       zval *tmp;
+       zval *this_ptr = getThis();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &location, &location_len) == FAILURE) {
                return;
        }
 
-       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {
-               RETVAL_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
+               RETVAL_STR(STR_COPY(Z_STR_P(tmp)));
        } else {
-         RETVAL_NULL();
+               RETVAL_NULL();
        }
 
        if (location && location_len) {
                add_property_stringl(this_ptr, "location", location, location_len);
        } else {
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "location", sizeof("location"));
+               zend_hash_str_del(Z_OBJPROP_P(this_ptr), "location", sizeof("location")-1);
        }
 }
 /* }}} */
 
 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"));
+       if (obj != NULL && Z_TYPE_P(obj) == IS_OBJECT) {
+               zend_hash_str_del(Z_OBJPROP_P(obj), "__soap_fault", sizeof("__soap_fault")-1);
        }
 }
 
 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);
-       Z_DELREF_P(fault);
+       zval fault;
 
-       add_property_zval(obj, "__soap_fault", fault);
-       return fault;
+       set_soap_fault(&fault, NULL, fault_code, fault_string, fault_actor, fault_detail, NULL TSRMLS_CC);
+       add_property_zval(obj, "__soap_fault", &fault);
+       Z_DELREF(fault);
+//??? FIXME
+//     return &fault;
+       return NULL;
 }
 
 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)
@@ -3291,13 +3278,13 @@ static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, cha
        }
 }
 
-static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, int *num_params, zval ***parameters TSRMLS_DC)
+static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, int *num_params, zval **parameters TSRMLS_DC)
 {
        int cur_param = 0,num_of_params = 0;
-       zval **tmp_parameters = NULL;
+       zval *tmp_parameters = NULL;
 
        if (function != NULL) {
-               sdlParamPtr *param;
+               sdlParamPtr param;
                xmlNodePtr val;
                int     use_names = 0;
 
@@ -3305,31 +3292,25 @@ static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, i
                        return;
                }
                num_of_params = zend_hash_num_elements(function->requestParameters);
-               zend_hash_internal_pointer_reset(function->requestParameters);
-               while (zend_hash_get_current_data(function->requestParameters, (void **)&param) == SUCCESS) {
-                       if (get_node(params, (*param)->paramName) != NULL) {
+               ZEND_HASH_FOREACH_PTR(function->requestParameters, param) {
+                       if (get_node(params, param->paramName) != NULL) {
                                use_names = 1;
                        }
-                       zend_hash_move_forward(function->requestParameters);
-               }
+               } ZEND_HASH_FOREACH_END();
                if (use_names) {
                        tmp_parameters = safe_emalloc(num_of_params, sizeof(zval *), 0);
-                       zend_hash_internal_pointer_reset(function->requestParameters);
-                       while (zend_hash_get_current_data(function->requestParameters, (void **)&param) == SUCCESS) {
-                               val = get_node(params, (*param)->paramName);
+                       ZEND_HASH_FOREACH_PTR(function->requestParameters, param) {
+                               val = get_node(params, param->paramName);
                                if (!val) {
                                        /* TODO: may be "nil" is not OK? */
-                                       MAKE_STD_ZVAL(tmp_parameters[cur_param]);
-                                       ZVAL_NULL(tmp_parameters[cur_param]);
+                                       ZVAL_NULL(&tmp_parameters[cur_param]);
                                } else {
-                                       tmp_parameters[cur_param] = master_to_zval((*param)->encode, val TSRMLS_CC);
+                                       master_to_zval(&tmp_parameters[cur_param], param->encode, val TSRMLS_CC);
                                }
                                cur_param++;
-
-                               zend_hash_move_forward(function->requestParameters);
-                       }
-                       (*parameters) = tmp_parameters;
-                       (*num_params) = num_of_params;
+                       } ZEND_HASH_FOREACH_END();
+                       *parameters = tmp_parameters;
+                       *num_params = num_of_params;
                        return;
                }
        }
@@ -3361,18 +3342,18 @@ static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, i
                        while (trav != 0 && cur_param < num_of_params) {
                                if (trav->type == XML_ELEMENT_NODE) {
                                        encodePtr enc;
-                                       sdlParamPtr *param = NULL;
+                                       sdlParamPtr param = NULL;
                                        if (function != NULL &&
-                                           zend_hash_index_find(function->requestParameters, cur_param, (void **)&param) == FAILURE) {
+                                           (param = zend_hash_index_find_ptr(function->requestParameters, cur_param)) == NULL) {
                                                TSRMLS_FETCH();
                                                soap_server_fault("Client", "Error cannot find parameter", NULL, NULL, NULL TSRMLS_CC);
                                        }
                                        if (param == NULL) {
                                                enc = NULL;
                                        } else {
-                                               enc = (*param)->encode;
+                                               enc = param->encode;
                                        }
-                                       tmp_parameters[cur_param] = master_to_zval(enc, trav TSRMLS_CC);
+                                       master_to_zval(&tmp_parameters[cur_param], enc, trav TSRMLS_CC);
                                        cur_param++;
                                }
                                trav = trav->next;
@@ -3405,17 +3386,16 @@ static sdlFunctionPtr find_function(sdlPtr sdl, xmlNodePtr func, zval* function_
                function = get_doc_function(sdl, func);
        }
 
-       INIT_ZVAL(*function_name);
        if (function != NULL) {
-               ZVAL_STRING(function_name, (char *)function->functionName, 1);
+               ZVAL_STRING(function_name, (char *)function->functionName);
        } else {
-               ZVAL_STRING(function_name, (char *)func->name, 1);
+               ZVAL_STRING(function_name, (char *)func->name);
        }
 
        return function;
 }
 
-static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval ***parameters, int *version, soapHeader **headers TSRMLS_DC)
+static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters, int *version, soapHeader **headers TSRMLS_DC)
 {
        char* envelope_ns = NULL;
        xmlNodePtr trav,env,head,body,func;
@@ -3526,8 +3506,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
        if (func == NULL) {
                function = get_doc_function(sdl, NULL);
                if (function != NULL) {
-                       INIT_ZVAL(*function_name);
-                       ZVAL_STRING(function_name, (char *)function->functionName, 1);
+                       ZVAL_STRING(function_name, (char *)function->functionName);
                } else {
                        soap_server_fault("Client", "looks like we got \"Body\" without function call", NULL, NULL, NULL TSRMLS_CC);
                }
@@ -3619,7 +3598,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
                                h->mustUnderstand = mustUnderstand;
                                h->function = find_function(sdl, hdr_func, &h->function_name);
                                if (!h->function && sdl && function && function->binding && function->binding->bindingType == BINDING_SOAP) {
-                                       sdlSoapBindingFunctionHeaderPtr *hdr;
+                                       sdlSoapBindingFunctionHeaderPtr hdr;
                                        sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
                                        if (fnb->input.headers) {
                                                smart_str key = {0};
@@ -3630,16 +3609,16 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
                                                }
                                                smart_str_appendl(&key, Z_STRVAL(h->function_name), Z_STRLEN(h->function_name));
                                                smart_str_0(&key);
-                                               if (zend_hash_find(fnb->input.headers, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
-                                                       h->hdr = *hdr;
+                                               if ((hdr = zend_hash_find_ptr(fnb->input.headers, key.s)) != NULL) {
+                                                       h->hdr = hdr;
                                                }
                                                smart_str_free(&key);
                                        }
                                }
                                if (h->hdr) {
                                        h->num_params = 1;
-                                       h->parameters = emalloc(sizeof(zval*));
-                                       h->parameters[0] = master_to_zval(h->hdr->encode, hdr_func TSRMLS_CC);
+                                       h->parameters = emalloc(sizeof(zval));
+                                       master_to_zval(&h->parameters[0], h->hdr->encode, hdr_func TSRMLS_CC);
                                } else {
                                        if (h->function && h->function->binding && h->function->binding->bindingType == BINDING_SOAP) {
                                                sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)h->function->bindingAttributes;
@@ -3649,7 +3628,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
                                        }
                                        deserialize_parameters(hdr_func, h->function, &h->num_params, &h->parameters TSRMLS_CC);
                                }
-                               INIT_ZVAL(h->retval);
+                               ZVAL_NULL(&h->retval);
                                if (last == NULL) {
                                        *headers = h;
                                } else {
@@ -3679,34 +3658,34 @@ ignore_header:
 
 static void set_soap_header_attributes(xmlNodePtr h, HashTable *ht, int version)
 {
-       zval **tmp;
+       zval *tmp;
 
-       if (zend_hash_find(ht, "mustUnderstand", sizeof("mustUnderstand"), (void**)&tmp) == SUCCESS &&
-           Z_TYPE_PP(tmp) == IS_BOOL && Z_LVAL_PP(tmp)) {
+       if ((tmp = zend_hash_str_find(ht, "mustUnderstand", sizeof("mustUnderstand")-1)) != NULL &&
+           Z_TYPE_P(tmp) == IS_TRUE) {
                if (version == SOAP_1_1) {
                        xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":mustUnderstand"), BAD_CAST("1"));
                } else {
                        xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":mustUnderstand"), BAD_CAST("true"));
                }
        }
-       if (zend_hash_find(ht, "actor", sizeof("actor"), (void**)&tmp) == SUCCESS) {
-               if (Z_TYPE_PP(tmp) == IS_STRING) {
+       if ((tmp = zend_hash_str_find(ht, "actor", sizeof("actor")-1)) != NULL) {
+               if (Z_TYPE_P(tmp) == IS_STRING) {
                        if (version == SOAP_1_1) {
-                               xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(Z_STRVAL_PP(tmp)));
+                               xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(Z_STRVAL_P(tmp)));
                        } else {
-                               xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(Z_STRVAL_PP(tmp)));
+                               xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(Z_STRVAL_P(tmp)));
                        }
-               } else if (Z_TYPE_PP(tmp) == IS_LONG) {
+               } else if (Z_TYPE_P(tmp) == IS_LONG) {
                        if (version == SOAP_1_1) {
-                               if (Z_LVAL_PP(tmp) == SOAP_ACTOR_NEXT) {
+                               if (Z_LVAL_P(tmp) == SOAP_ACTOR_NEXT) {
                                        xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(SOAP_1_1_ACTOR_NEXT));
                                }
                        } else {
-                               if (Z_LVAL_PP(tmp) == SOAP_ACTOR_NEXT) {
+                               if (Z_LVAL_P(tmp) == SOAP_ACTOR_NEXT) {
                                        xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_NEXT));
-                               } else if (Z_LVAL_PP(tmp) == SOAP_ACTOR_NONE) {
+                               } else if (Z_LVAL_P(tmp) == SOAP_ACTOR_NONE) {
                                        xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_NONE));
-                               } else if (Z_LVAL_PP(tmp) == SOAP_ACTOR_UNLIMATERECEIVER) {
+                               } else if (Z_LVAL_P(tmp) == SOAP_ACTOR_UNLIMATERECEIVER) {
                                        xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_UNLIMATERECEIVER));
                                }
                        }
@@ -3782,22 +3761,18 @@ static int serialize_response_call2(xmlNodePtr body, sdlFunctionPtr function, ch
                        }
                }
        } else if (param_count > 1 && Z_TYPE_P(ret) == IS_ARRAY) {
-               HashPosition pos;
-               zval **data;
+               zval *data;
                int i = 0;
+               zend_string *param_name;
+//???
+               ulong param_index = i;
 
-               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ret), &pos);
-               while (zend_hash_get_current_data_ex(Z_ARRVAL_P(ret), (void **)&data, &pos) != FAILURE) {
-                       char *param_name = NULL;
-                       unsigned int param_name_len;
-                       ulong param_index = i;
-
-                       zend_hash_get_current_key_ex(Z_ARRVAL_P(ret), &param_name, &param_name_len, &param_index, 0, &pos);
-                       parameter = get_param(function, param_name, param_index, TRUE);
+               ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(ret), param_index, param_name, data) {
+                       parameter = get_param(function, param_name->val, param_index, TRUE);
                        if (style == SOAP_RPC) {
-                               param = serialize_parameter(parameter, *data, i, param_name, use, method TSRMLS_CC);
+                               param = serialize_parameter(parameter, data, i, param_name->val, use, method TSRMLS_CC);
                        } else {
-                               param = serialize_parameter(parameter, *data, i, param_name, use, body TSRMLS_CC);
+                               param = serialize_parameter(parameter, data, i, param_name->val, use, body TSRMLS_CC);
                                if (function && function->binding->bindingType == BINDING_SOAP) {
                                        if (parameter && parameter->element) {
                                                ns = encode_add_ns(param, parameter->element->namens);
@@ -3807,9 +3782,9 @@ static int serialize_response_call2(xmlNodePtr body, sdlFunctionPtr function, ch
                                }
                        }
 
-                       zend_hash_move_forward_ex(Z_ARRVAL_P(ret), &pos);
                        i++;
-               }
+                       param_index = i;
+               } ZEND_HASH_FOREACH_END();
        }
        if (use == SOAP_ENCODED && version == SOAP_1_2 && method != NULL) {
                xmlSetNsProp(method, body->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
@@ -3851,17 +3826,17 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
            instanceof_function(Z_OBJCE_P(ret), soap_fault_class_entry TSRMLS_CC)) {
          char *detail_name;
                HashTable* prop;
-               zval **tmp;
+               zval *tmp;
                sdlFaultPtr fault = NULL;
                char *fault_ns = NULL;
 
                prop = Z_OBJPROP_P(ret);
 
                if (headers &&
-                   zend_hash_find(prop, "headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS) {
+                   (tmp = zend_hash_str_find(prop, "headerfault", sizeof("headerfault")-1)) != NULL) {
                        encodePtr hdr_enc = NULL;
                        int hdr_use = SOAP_LITERAL;
-                       zval *hdr_ret  = *tmp;
+                       zval *hdr_ret  = tmp;
                        char *hdr_ns   = headers->hdr?headers->hdr->ns:NULL;
                        char *hdr_name = Z_STRVAL(headers->function_name);
 
@@ -3869,29 +3844,29 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                        if (Z_TYPE_P(hdr_ret) == IS_OBJECT &&
                            instanceof_function(Z_OBJCE_P(hdr_ret), soap_header_class_entry TSRMLS_CC)) {
                                HashTable* ht = Z_OBJPROP_P(hdr_ret);
-                               sdlSoapBindingFunctionHeaderPtr *hdr;
+                               sdlSoapBindingFunctionHeaderPtr hdr;
                                smart_str key = {0};
 
-                               if (zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&tmp) == SUCCESS &&
-                             Z_TYPE_PP(tmp) == IS_STRING) {
-                                       smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                               if ((tmp = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
+                             Z_TYPE_P(tmp) == IS_STRING) {
+                                       smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                        smart_str_appendc(&key, ':');
-                                       hdr_ns = Z_STRVAL_PP(tmp);
+                                       hdr_ns = Z_STRVAL_P(tmp);
                                }
-                               if (zend_hash_find(ht, "name", sizeof("name"), (void**)&tmp) == SUCCESS &&
-                                   Z_TYPE_PP(tmp) == IS_STRING) {
-                                       smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-                                       hdr_name = Z_STRVAL_PP(tmp);
+                               if ((tmp = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
+                                   Z_TYPE_P(tmp) == IS_STRING) {
+                                       smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
+                                       hdr_name = Z_STRVAL_P(tmp);
                                }
                                smart_str_0(&key);
                                if (headers->hdr && headers->hdr->headerfaults &&
-                                   zend_hash_find(headers->hdr->headerfaults, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
-                                       hdr_enc = (*hdr)->encode;
-                                       hdr_use = (*hdr)->use;
+                                   (hdr = zend_hash_find_ptr(headers->hdr->headerfaults, key.s)) != NULL) {
+                                       hdr_enc = hdr->encode;
+                                       hdr_use = hdr->use;
                                }
                                smart_str_free(&key);
-                               if (zend_hash_find(ht, "data", sizeof("data"), (void**)&tmp) == SUCCESS) {
-                                       hdr_ret = *tmp;
+                               if ((tmp = zend_hash_str_find(ht, "data", sizeof("data")-1)) != NULL) {
+                                       hdr_ret = tmp;
                                } else {
                                        hdr_ret = NULL;
                                }
@@ -3916,15 +3891,15 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                body = xmlNewChild(envelope, ns, BAD_CAST("Body"), NULL);
                param = xmlNewChild(body, ns, BAD_CAST("Fault"), NULL);
 
-               if (zend_hash_find(prop, "faultcodens", sizeof("faultcodens"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {
-                       fault_ns = Z_STRVAL_PP(tmp);
+               if ((tmp = zend_hash_str_find(prop, "faultcodens", sizeof("faultcodens")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
+                       fault_ns = Z_STRVAL_P(tmp);
                }
                use = SOAP_LITERAL;
-               if (zend_hash_find(prop, "_name", sizeof("_name"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {
-                       sdlFaultPtr *tmp_fault;
+               if ((tmp = zend_hash_str_find(prop, "_name", sizeof("_name")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
+                       sdlFaultPtr tmp_fault;
                        if (function && function->faults &&
-                           zend_hash_find(function->faults, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)+1, (void**)&tmp_fault) == SUCCESS) {
-                         fault = *tmp_fault;
+                           (tmp_fault = zend_hash_find_ptr(function->faults, Z_STR_P(tmp))) != NULL) {
+                               fault = tmp_fault;
                                if (function->binding &&
                                    function->binding->bindingType == BINDING_SOAP &&
                                    fault->bindingAttributes) {
@@ -3939,15 +3914,14 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                           zend_hash_num_elements(function->faults) == 1) {
 
                        zend_hash_internal_pointer_reset(function->faults);
-                       zend_hash_get_current_data(function->faults, (void**)&fault);
-                       fault = *(sdlFaultPtr*)fault;
+                       fault = zend_hash_get_current_data_ptr(function->faults);
                        if (function->binding &&
                            function->binding->bindingType == BINDING_SOAP &&
                            fault->bindingAttributes) {
                                sdlSoapBindingFunctionFaultPtr fb = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
                                use = fb->use;
                                if (fault_ns == NULL) {
-                                 fault_ns = fb->ns;
+                                       fault_ns = fb->ns;
                                }
                        }
                }
@@ -3959,57 +3933,54 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                        sdlParamPtr sparam;
 
                        zend_hash_internal_pointer_reset(fault->details);
-                       zend_hash_get_current_data(fault->details, (void**)&sparam);
-                       sparam = *(sdlParamPtr*)sparam;
+                       sparam = zend_hash_get_current_data_ptr(fault->details);
                        if (sparam->element) {
                                fault_ns = sparam->element->namens;
                        }
                }
 
                if (version == SOAP_1_1) {
-                       if (zend_hash_find(prop, "faultcode", sizeof("faultcode"), (void**)&tmp) == SUCCESS) {
-                               size_t new_len;
+                       if ((tmp = zend_hash_str_find(prop, "faultcode", sizeof("faultcode")-1)) != NULL) {
                                xmlNodePtr node = xmlNewNode(NULL, BAD_CAST("faultcode"));
-                               char *str = php_escape_html_entities((unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &new_len, 0, 0, NULL TSRMLS_CC);
+                               zend_string *str = php_escape_html_entities((unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 0, 0, NULL TSRMLS_CC);
                                xmlAddChild(param, node);
                                if (fault_ns) {
                                        xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
-                                       xmlChar *code = xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0);
+                                       xmlChar *code = xmlBuildQName(BAD_CAST(str->val), nsptr->prefix, NULL, 0);
                                        xmlNodeSetContent(node, code);
                                        xmlFree(code);
                                } else {        
-                                       xmlNodeSetContentLen(node, BAD_CAST(str), (int)new_len);
+                                       xmlNodeSetContentLen(node, BAD_CAST(str->val), (int)str->len);
                                }
-                               efree(str);
+                               STR_RELEASE(str);
                        }
-                       if (zend_hash_find(prop, "faultstring", sizeof("faultstring"), (void**)&tmp) == SUCCESS) {
-                               xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), *tmp, SOAP_LITERAL, param TSRMLS_CC);
+                       if ((tmp = zend_hash_str_find(prop, "faultstring", sizeof("faultstring")-1)) != NULL) {
+                               xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), tmp, SOAP_LITERAL, param TSRMLS_CC);
                                xmlNodeSetName(node, BAD_CAST("faultstring"));
                        }
-                       if (zend_hash_find(prop, "faultactor", sizeof("faultactor"), (void**)&tmp) == SUCCESS) {
-                               xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), *tmp, SOAP_LITERAL, param TSRMLS_CC);
+                       if ((tmp = zend_hash_str_find(prop, "faultactor", sizeof("faultactor")-1)) != NULL) {
+                               xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), tmp, SOAP_LITERAL, param TSRMLS_CC);
                                xmlNodeSetName(node, BAD_CAST("faultactor"));
                        }
                        detail_name = "detail";
                } else {
-                       if (zend_hash_find(prop, "faultcode", sizeof("faultcode"), (void**)&tmp) == SUCCESS) {
-                               size_t new_len;
+               if ((tmp = zend_hash_str_find(prop, "faultcode", sizeof("faultcode")-1)) != NULL) {
                                xmlNodePtr node = xmlNewChild(param, ns, BAD_CAST("Code"), NULL);
-                               char *str = php_escape_html_entities((unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &new_len, 0, 0, NULL TSRMLS_CC);
+                               zend_string *str = php_escape_html_entities((unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 0, 0, NULL TSRMLS_CC);
                                node = xmlNewChild(node, ns, BAD_CAST("Value"), NULL);
                                if (fault_ns) {
                                        xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
-                                       xmlChar *code = xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0);
+                                       xmlChar *code = xmlBuildQName(BAD_CAST(str->val), nsptr->prefix, NULL, 0);
                                        xmlNodeSetContent(node, code);
                                        xmlFree(code);
                                } else {        
-                                       xmlNodeSetContentLen(node, BAD_CAST(str), (int)new_len);
+                                       xmlNodeSetContentLen(node, BAD_CAST(str->val), (int)str->len);
                                }
-                               efree(str);
+                               STR_RELEASE(str);
                        }
-                       if (zend_hash_find(prop, "faultstring", sizeof("faultstring"), (void**)&tmp) == SUCCESS) {
+                       if ((tmp = zend_hash_str_find(prop, "faultstring", sizeof("faultstring")-1)) != NULL) {
                                xmlNodePtr node = xmlNewChild(param, ns, BAD_CAST("Reason"), NULL);
-                               node = master_to_xml(get_conversion(IS_STRING), *tmp, SOAP_LITERAL, node TSRMLS_CC);
+                               node = master_to_xml(get_conversion(IS_STRING), tmp, SOAP_LITERAL, node TSRMLS_CC);
                                xmlNodeSetName(node, BAD_CAST("Text"));
                                xmlSetNs(node, ns);
                        }
@@ -4021,23 +3992,22 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                        sdlParamPtr sparam;
                        xmlNodePtr x;
 
-                       if (zend_hash_find(prop, "detail", sizeof("detail"), (void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) != IS_NULL) {
-                               detail = *tmp;
+                       if ((tmp = zend_hash_str_find(prop, "detail", sizeof("detail")-1)) != NULL &&
+                           Z_TYPE_P(tmp) != IS_NULL) {
+                               detail = tmp;
                        }
                        node = xmlNewNode(NULL, BAD_CAST(detail_name));
                        xmlAddChild(param, node);
 
                        zend_hash_internal_pointer_reset(fault->details);
-                       zend_hash_get_current_data(fault->details, (void**)&sparam);
-                       sparam = *(sdlParamPtr*)sparam;
+                       sparam = zend_hash_get_current_data_ptr(fault->details);
 
                        if (detail &&
                            Z_TYPE_P(detail) == IS_OBJECT &&
                            sparam->element &&
                            zend_hash_num_elements(Z_OBJPROP_P(detail)) == 1 &&
-                           zend_hash_find(Z_OBJPROP_P(detail), sparam->element->name, strlen(sparam->element->name)+1, (void**)&tmp) == SUCCESS) {
-                               detail = *tmp;
+                           (tmp = zend_hash_str_find(Z_OBJPROP_P(detail), sparam->element->name, strlen(sparam->element->name))) != NULL) {
+                               detail = tmp;
                        }
 
                        x = serialize_parameter(sparam, detail, 1, NULL, use, node TSRMLS_CC);
@@ -4066,9 +4036,9 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
                        if (use == SOAP_ENCODED && version == SOAP_1_2) {
                                xmlSetNsProp(x, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
                        }
-               } else if (zend_hash_find(prop, "detail", sizeof("detail"), (void**)&tmp) == SUCCESS &&
-                   Z_TYPE_PP(tmp) != IS_NULL) {
-                       serialize_zval(*tmp, NULL, detail_name, use, param TSRMLS_CC);
+               } else if ((tmp = zend_hash_str_find(prop, "detail", sizeof("detail")-1)) != NULL &&
+                   Z_TYPE_P(tmp) != IS_NULL) {
+                       serialize_zval(tmp, NULL, detail_name, use, param TSRMLS_CC);
                }
        } else {
 
@@ -4088,35 +4058,35 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
 
                                        if (Z_TYPE(h->retval) == IS_OBJECT &&
                                            instanceof_function(Z_OBJCE(h->retval), soap_header_class_entry TSRMLS_CC)) {
-                                               zval **tmp;
-                                               sdlSoapBindingFunctionHeaderPtr *hdr;
+                                               zval *tmp;
+                                               sdlSoapBindingFunctionHeaderPtr hdr;
                                                smart_str key = {0};
 
                                                ht = Z_OBJPROP(h->retval);
-                                               if (zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&tmp) == SUCCESS &&
-                                             Z_TYPE_PP(tmp) == IS_STRING) {
-                                                       smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                               if ((tmp = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
+                                             Z_TYPE_P(tmp) == IS_STRING) {
+                                                       smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                                        smart_str_appendc(&key, ':');
-                                                       hdr_ns = Z_STRVAL_PP(tmp);
+                                                       hdr_ns = Z_STRVAL_P(tmp);
                                                }
-                                               if (zend_hash_find(ht, "name", sizeof("name"), (void**)&tmp) == SUCCESS &&
-                                                   Z_TYPE_PP(tmp) == IS_STRING) {
-                                                       smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-                                                       hdr_name = Z_STRVAL_PP(tmp);
+                                               if ((tmp = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
+                                                   Z_TYPE_P(tmp) == IS_STRING) {
+                                                       smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
+                                                       hdr_name = Z_STRVAL_P(tmp);
                                                }
                                                smart_str_0(&key);
                                                if (function && function->binding && function->binding->bindingType == BINDING_SOAP) {
                                                        sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
 
                                                        if (fnb->output.headers &&
-                                                           zend_hash_find(fnb->output.headers, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
-                                                               hdr_enc = (*hdr)->encode;
-                                                               hdr_use = (*hdr)->use;
+                                                           (hdr = zend_hash_find_ptr(fnb->output.headers, key.s)) != NULL) {
+                                                               hdr_enc = hdr->encode;
+                                                               hdr_use = hdr->use;
                                                        }
                                                }
                                                smart_str_free(&key);
-                                               if (zend_hash_find(ht, "data", sizeof("data"), (void**)&tmp) == SUCCESS) {
-                                                       hdr_ret = *tmp;
+                                               if ((tmp = zend_hash_str_find(ht, "data", sizeof("data")-1)) != NULL) {
+                                                       hdr_ret = tmp;
                                                } else {
                                                        hdr_ret = NULL;
                                                }
@@ -4182,12 +4152,12 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
        return doc;
 }
 
-static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count, int version, HashTable *soap_headers TSRMLS_DC)
+static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval *arguments, int arg_count, int version, HashTable *soap_headers TSRMLS_DC)
 {
        xmlDoc *doc;
        xmlNodePtr envelope = NULL, body, method = NULL, head = NULL;
        xmlNsPtr ns = NULL;
-       zval **zstyle, **zuse;
+       zval *zstyle, *zuse;
        int i, style, use;
        HashTable *hdrs = NULL;
 
@@ -4232,8 +4202,8 @@ 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);
+               if ((zstyle = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "style", sizeof("style")-1)) != NULL) {
+                       style = Z_LVAL_P(zstyle);
                } else {
                        style = SOAP_RPC;
                }
@@ -4254,8 +4224,8 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
                        method = body;
                }
 
-               if (zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS &&
-                         Z_LVAL_PP(zuse) == SOAP_LITERAL) {
+               if ((zuse = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use")-1)) != NULL &&
+                         Z_LVAL_P(zuse) == SOAP_LITERAL) {
                        use = SOAP_LITERAL;
                } else {
                        use = SOAP_ENCODED;
@@ -4267,9 +4237,9 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
                sdlParamPtr parameter = get_param(function, NULL, i, FALSE);
 
                if (style == SOAP_RPC) {
-                       param = serialize_parameter(parameter, arguments[i], i, NULL, use, method TSRMLS_CC);
+                       param = serialize_parameter(parameter, &arguments[i], i, NULL, use, method TSRMLS_CC);
                } else if (style == SOAP_DOCUMENT) {
-                       param = serialize_parameter(parameter, arguments[i], i, NULL, use, body TSRMLS_CC);
+                       param = serialize_parameter(parameter, &arguments[i], i, NULL, use, body TSRMLS_CC);
                        if (function && function->binding->bindingType == BINDING_SOAP) {
                                if (parameter && parameter->element) {
                                        ns = encode_add_ns(param, parameter->element->namens);
@@ -4305,17 +4275,16 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
        }
 
        if (head) {
-               zval** header;
+               zval* header;
 
-               zend_hash_internal_pointer_reset(soap_headers);
-               while (zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS) {
-                       HashTable *ht = Z_OBJPROP_PP(header);
-                       zval **name, **ns, **tmp;
+               ZEND_HASH_FOREACH_VAL(soap_headers, header) {
+                       HashTable *ht = Z_OBJPROP_P(header);
+                       zval *name, *ns, *tmp;
 
-                       if (zend_hash_find(ht, "name", sizeof("name"), (void**)&name) == SUCCESS &&
-                           Z_TYPE_PP(name) == IS_STRING &&
-                           zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&ns) == SUCCESS &&
-                           Z_TYPE_PP(ns) == IS_STRING) {
+                       if ((name = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
+                           Z_TYPE_P(name) == IS_STRING &&
+                           (ns = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
+                           Z_TYPE_P(ns) == IS_STRING) {
                                xmlNodePtr h;
                                xmlNsPtr nsptr;
                                int hdr_use = SOAP_LITERAL;
@@ -4323,15 +4292,15 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
 
                                if (hdrs) {
                                        smart_str key = {0};
-                                       sdlSoapBindingFunctionHeaderPtr *hdr;
+                                       sdlSoapBindingFunctionHeaderPtr hdr;
 
-                                       smart_str_appendl(&key, Z_STRVAL_PP(ns), Z_STRLEN_PP(ns));
+                                       smart_str_appendl(&key, Z_STRVAL_P(ns), Z_STRLEN_P(ns));
                                        smart_str_appendc(&key, ':');
-                                       smart_str_appendl(&key, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
+                                       smart_str_appendl(&key, Z_STRVAL_P(name), Z_STRLEN_P(name));
                                        smart_str_0(&key);
-                                       if (zend_hash_find(hdrs, key.c, key.len+1,(void**)&hdr) == SUCCESS) {
-                                               hdr_use = (*hdr)->use;
-                                               enc = (*hdr)->encode;
+                                       if ((hdr = zend_hash_find_ptr(hdrs, key.s)) != NULL) {
+                                               hdr_use = hdr->use;
+                                               enc = hdr->encode;
                                                if (hdr_use == SOAP_ENCODED) {
                                                        use = SOAP_ENCODED;
                                                }
@@ -4339,19 +4308,18 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
                                        smart_str_free(&key);
                                }
 
-                               if (zend_hash_find(ht, "data", sizeof("data"), (void**)&tmp) == SUCCESS) {
-                                       h = master_to_xml(enc, *tmp, hdr_use, head TSRMLS_CC);
-                                       xmlNodeSetName(h, BAD_CAST(Z_STRVAL_PP(name)));
+                               if ((tmp = zend_hash_str_find(ht, "data", sizeof("data")-1)) != NULL) {
+                                       h = master_to_xml(enc, tmp, hdr_use, head TSRMLS_CC);
+                                       xmlNodeSetName(h, BAD_CAST(Z_STRVAL_P(name)));
                                } else {
-                                       h = xmlNewNode(NULL, BAD_CAST(Z_STRVAL_PP(name)));
+                                       h = xmlNewNode(NULL, BAD_CAST(Z_STRVAL_P(name)));
                                        xmlAddChild(head, h);
                                }
-                               nsptr = encode_add_ns(h, Z_STRVAL_PP(ns));
+                               nsptr = encode_add_ns(h, Z_STRVAL_P(ns));
                                xmlSetNs(h, nsptr);
                                set_soap_header_attributes(h, ht, version);
                        }
-                       zend_hash_move_forward(soap_headers);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        if (use == SOAP_ENCODED) {
@@ -4381,13 +4349,13 @@ static xmlNodePtr serialize_parameter(sdlParamPtr param, zval *param_val, int in
        if (param_val &&
            Z_TYPE_P(param_val) == IS_OBJECT &&
            Z_OBJCE_P(param_val) == soap_param_class_entry) {
-               zval **param_name;
-               zval **param_data;
+               zval *param_name;
+               zval *param_data;
 
-               if (zend_hash_find(Z_OBJPROP_P(param_val), "param_name", sizeof("param_name"), (void **)&param_name) == SUCCESS &&
-                   zend_hash_find(Z_OBJPROP_P(param_val), "param_data", sizeof("param_data"), (void **)&param_data) == SUCCESS) {
-                       param_val = *param_data;
-                       name = Z_STRVAL_PP(param_name);
+               if ((param_name = zend_hash_str_find(Z_OBJPROP_P(param_val), "param_name", sizeof("param_name")-1)) != NULL &&
+                   (param_data = zend_hash_str_find(Z_OBJPROP_P(param_val), "param_data", sizeof("param_data")-1)) != NULL) {
+                       param_val = param_data;
+                       name = Z_STRVAL_P(param_name);
                }
        }
 
@@ -4418,10 +4386,12 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
                if (val == NULL) {
                        if (param->element) {
                                if (param->element->fixed) {
-                                       ZVAL_STRING(&defval, param->element->fixed, 0);
+                                       //??? val has to be freed
+                                       ZVAL_STRING(&defval, param->element->fixed);
                                        val = &defval;
                                } else if (param->element->def && !param->element->nillable) {
-                                       ZVAL_STRING(&defval, param->element->def, 0);
+                                       //??? val has to be freed
+                                       ZVAL_STRING(&defval, param->element->def);
                                        val = &defval;
                                }
                        }
@@ -4438,7 +4408,7 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
 
 static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int response)
 {
-       sdlParamPtr *tmp;
+       sdlParamPtr tmp;
        HashTable   *ht;
 
        if (function == NULL) {
@@ -4456,22 +4426,18 @@ static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int inde
        }
 
        if (param_name != NULL) {
-               if (zend_hash_find(ht, param_name, strlen(param_name), (void **)&tmp) != FAILURE) {
-                       return *tmp;
+               if ((tmp = zend_hash_str_find_ptr(ht, param_name, strlen(param_name))) != NULL) {
+                       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) {
-                                       return *tmp;
+                       ZEND_HASH_FOREACH_PTR(ht, tmp) {
+                               if (tmp->paramName && strcmp(param_name, tmp->paramName) == 0) {
+                                       return tmp;
                                }
-                               zend_hash_move_forward_ex(ht, &pos);
-                       }
+                       } ZEND_HASH_FOREACH_END();
                }
        } else {
-               if (zend_hash_index_find(ht, index, (void **)&tmp) != FAILURE) {
-                       return (*tmp);
+               if ((tmp = zend_hash_index_find_ptr(ht, index)) != NULL) {
+                       return tmp;
                }
        }
        return NULL;
@@ -4479,18 +4445,18 @@ static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int inde
 
 static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name)
 {
-       sdlFunctionPtr *tmp;
+       sdlFunctionPtr tmp;
 
        int len = strlen(function_name);
        char *str = estrndup(function_name,len);
        php_strtolower(str,len);
        if (sdl != NULL) {
-               if (zend_hash_find(&sdl->functions, str, len+1, (void **)&tmp) != FAILURE) {
+               if ((tmp = zend_hash_str_find_ptr(&sdl->functions, str, len)) != NULL) {
                        efree(str);
-                       return (*tmp);
-               } else if (sdl->requests != NULL && zend_hash_find(sdl->requests, str, len+1, (void **)&tmp) != FAILURE) {
+                       return tmp;
+               } else if (sdl->requests != NULL && (tmp = zend_hash_str_find_ptr(sdl->requests, str, len)) != NULL) {
                        efree(str);
-                       return (*tmp);
+                       return tmp;
                }
        }
        efree(str);
@@ -4500,55 +4466,51 @@ static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name)
 static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr params)
 {
        if (sdl) {
-               sdlFunctionPtr *tmp;
-               sdlParamPtr    *param;
+               sdlFunctionPtr tmp;
+               sdlParamPtr    param;
 
-               zend_hash_internal_pointer_reset(&sdl->functions);
-               while (zend_hash_get_current_data(&sdl->functions, (void**)&tmp) == SUCCESS) {
-                       if ((*tmp)->binding && (*tmp)->binding->bindingType == BINDING_SOAP) {
-                               sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)(*tmp)->bindingAttributes;
+               ZEND_HASH_FOREACH_PTR(&sdl->functions, tmp) {
+                       if (tmp->binding && tmp->binding->bindingType == BINDING_SOAP) {
+                               sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)tmp->bindingAttributes;
                                if (fnb->style == SOAP_DOCUMENT) {
                                        if (params == NULL) {
-                                               if ((*tmp)->requestParameters == NULL ||
-                                                   zend_hash_num_elements((*tmp)->requestParameters) == 0) {
-                                                 return *tmp;
+                                               if (tmp->requestParameters == NULL ||
+                                                   zend_hash_num_elements(tmp->requestParameters) == 0) {
+                                                 return tmp;
                                                }
-                                       } else if ((*tmp)->requestParameters != NULL &&
-                                                  zend_hash_num_elements((*tmp)->requestParameters) > 0) {
+                                       } else if (tmp->requestParameters != NULL &&
+                                                  zend_hash_num_elements(tmp->requestParameters) > 0) {
                                                int ok = 1;
                                                xmlNodePtr node = params;
 
-                                               zend_hash_internal_pointer_reset((*tmp)->requestParameters);
-                                               while (zend_hash_get_current_data((*tmp)->requestParameters, (void**)&param) == SUCCESS) {
-                                                       if ((*param)->element) {
-                                                               if (strcmp((*param)->element->name, (char*)node->name) != 0) {
+                                               ZEND_HASH_FOREACH_PTR(tmp->requestParameters, param) {
+                                                       if (param->element) {
+                                                               if (strcmp(param->element->name, (char*)node->name) != 0) {
                                                                        ok = 0;
                                                                        break;
                                                                }
-                                                               if ((*param)->element->namens != NULL && node->ns != NULL) {
-                                                                       if (strcmp((*param)->element->namens, (char*)node->ns->href) != 0) {
+                                                               if (param->element->namens != NULL && node->ns != NULL) {
+                                                                       if (strcmp(param->element->namens, (char*)node->ns->href) != 0) {
                                                                                ok = 0;
                                                                                break;
                                                                        }
-                                                               } else if ((void*)(*param)->element->namens != (void*)node->ns) {
+                                                               } else if ((void*)param->element->namens != (void*)node->ns) {
                                                                        ok = 0;
                                                                        break;
                                                                }
-                                                       } else if (strcmp((*param)->paramName, (char*)node->name) != 0) {
+                                                       } else if (strcmp(param->paramName, (char*)node->name) != 0) {
                                                                ok = 0;
                                                                break;
                                                        }
-                                                       zend_hash_move_forward((*tmp)->requestParameters);
                                                        node = node->next;
-                                               }
+                                               } ZEND_HASH_FOREACH_END();
                                                if (ok /*&& node == NULL*/) {
-                                                       return (*tmp);
+                                                       return tmp;
                                                }
                                        }
                                }
                        }
-                       zend_hash_move_forward(&sdl->functions);
-               }
+               } ZEND_HASH_FOREACH_END();
        }
        return NULL;
 }
@@ -4556,16 +4518,15 @@ static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr params)
 static void function_to_string(sdlFunctionPtr function, smart_str *buf)
 {
        int i = 0;
-       HashPosition pos;
-       sdlParamPtr *param;
+       sdlParamPtr param;
 
        if (function->responseParameters &&
            zend_hash_num_elements(function->responseParameters) > 0) {
                if (zend_hash_num_elements(function->responseParameters) == 1) {
                        zend_hash_internal_pointer_reset(function->responseParameters);
-                       zend_hash_get_current_data(function->responseParameters, (void**)&param);
-                       if ((*param)->encode && (*param)->encode->details.type_str) {
-                               smart_str_appendl(buf, (*param)->encode->details.type_str, strlen((*param)->encode->details.type_str));
+                       param = zend_hash_get_current_data_ptr(function->responseParameters);
+                       if (param->encode && param->encode->details.type_str) {
+                               smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str));
                                smart_str_appendc(buf, ' ');
                        } else {
                                smart_str_appendl(buf, "UNKNOWN ", 8);
@@ -4573,21 +4534,19 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf)
                } else {
                        i = 0;
                        smart_str_appendl(buf, "list(", 5);
-                       zend_hash_internal_pointer_reset_ex(function->responseParameters, &pos);
-                       while (zend_hash_get_current_data_ex(function->responseParameters, (void **)&param, &pos) != FAILURE) {
+                       ZEND_HASH_FOREACH_PTR(function->responseParameters, param) {
                                if (i > 0) {
                                        smart_str_appendl(buf, ", ", 2);
                                }
-                               if ((*param)->encode && (*param)->encode->details.type_str) {
-                                       smart_str_appendl(buf, (*param)->encode->details.type_str, strlen((*param)->encode->details.type_str));
+                               if (param->encode && param->encode->details.type_str) {
+                                       smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str));
                                } else {
                                        smart_str_appendl(buf, "UNKNOWN", 7);
                                }
                                smart_str_appendl(buf, " $", 2);
-                               smart_str_appendl(buf, (*param)->paramName, strlen((*param)->paramName));
-                               zend_hash_move_forward_ex(function->responseParameters, &pos);
+                               smart_str_appendl(buf, param->paramName, strlen(param->paramName));
                                i++;
-                       }
+                       } ZEND_HASH_FOREACH_END();
                        smart_str_appendl(buf, ") ", 2);
                }
        } else {
@@ -4599,21 +4558,19 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf)
        smart_str_appendc(buf, '(');
        if (function->requestParameters) {
                i = 0;
-               zend_hash_internal_pointer_reset_ex(function->requestParameters, &pos);
-               while (zend_hash_get_current_data_ex(function->requestParameters, (void **)&param, &pos) != FAILURE) {
+               ZEND_HASH_FOREACH_PTR(function->requestParameters, param) {
                        if (i > 0) {
                                smart_str_appendl(buf, ", ", 2);
                        }
-                       if ((*param)->encode && (*param)->encode->details.type_str) {
-                               smart_str_appendl(buf, (*param)->encode->details.type_str, strlen((*param)->encode->details.type_str));
+                       if (param->encode && param->encode->details.type_str) {
+                               smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str));
                        } else {
                                smart_str_appendl(buf, "UNKNOWN", 7);
                        }
                        smart_str_appendl(buf, " $", 2);
-                       smart_str_appendl(buf, (*param)->paramName, strlen((*param)->paramName));
-                       zend_hash_move_forward_ex(function->requestParameters, &pos);
+                       smart_str_appendl(buf, param->paramName, strlen(param->paramName));
                        i++;
-               }
+               } ZEND_HASH_FOREACH_END();
        }
        smart_str_appendc(buf, ')');
        smart_str_0(buf);
@@ -4637,13 +4594,11 @@ static void model_to_string(sdlContentModelPtr model, smart_str *buf, int level)
                case XSD_CONTENT_SEQUENCE:
                case XSD_CONTENT_ALL:
                case XSD_CONTENT_CHOICE: {
-                       sdlContentModelPtr *tmp;
+                       sdlContentModelPtr tmp;
 
-                       zend_hash_internal_pointer_reset(model->u.content);
-                       while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
-                               model_to_string(*tmp, buf, level);
-                               zend_hash_move_forward(model->u.content);
-                       }
+                       ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
+                               model_to_string(tmp, buf, level);
+                       } ZEND_HASH_FOREACH_END();
                        break;
                }
                case XSD_CONTENT_GROUP:
@@ -4657,12 +4612,11 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
 {
        int i;
        smart_str spaces = {0};
-       HashPosition pos;
 
        for (i = 0;i < level;i++) {
                smart_str_appendc(&spaces, ' ');
        }
-       smart_str_appendl(buf, spaces.c, spaces.len);
+       smart_str_appendl(buf, spaces.s->val, spaces.s->len);
 
        switch (type->kind) {
                case XSD_TYPEKIND_SIMPLE:
@@ -4678,13 +4632,12 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
                        smart_str_appendl(buf, "list ", 5);
                        smart_str_appendl(buf, type->name, strlen(type->name));
                        if (type->elements) {
-                               sdlTypePtr *item_type;
+                               sdlTypePtr item_type;
 
                                smart_str_appendl(buf, " {", 2);
-                               zend_hash_internal_pointer_reset_ex(type->elements, &pos);
-                               if (zend_hash_get_current_data_ex(type->elements, (void **)&item_type, &pos) != FAILURE) {
-                                       smart_str_appendl(buf, (*item_type)->name, strlen((*item_type)->name));
-                               }
+                               ZEND_HASH_FOREACH_PTR(type->elements, item_type) {
+                                       smart_str_appendl(buf, item_type->name, strlen(item_type->name));
+                               } ZEND_HASH_FOREACH_END();
                                smart_str_appendc(buf, '}');
                        }
                        break;
@@ -4692,19 +4645,17 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
                        smart_str_appendl(buf, "union ", 6);
                        smart_str_appendl(buf, type->name, strlen(type->name));
                        if (type->elements) {
-                               sdlTypePtr *item_type;
+                               sdlTypePtr item_type;
                                int first = 0;
 
                                smart_str_appendl(buf, " {", 2);
-                               zend_hash_internal_pointer_reset_ex(type->elements, &pos);
-                               while (zend_hash_get_current_data_ex(type->elements, (void **)&item_type, &pos) != FAILURE) {
+                               ZEND_HASH_FOREACH_PTR(type->elements, item_type) {
                                        if (!first) {
                                                smart_str_appendc(buf, ',');
                                                first = 0;
                                        }
-                                       smart_str_appendl(buf, (*item_type)->name, strlen((*item_type)->name));
-                                       zend_hash_move_forward_ex(type->elements, &pos);
-                               }
+                                       smart_str_appendl(buf, item_type->name, strlen(item_type->name));
+                               } ZEND_HASH_FOREACH_END();
                                smart_str_appendc(buf, '}');
                        }
                        break;
@@ -4714,25 +4665,24 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
                        if (type->encode &&
                            (type->encode->details.type == IS_ARRAY ||
                             type->encode->details.type == SOAP_ENC_ARRAY)) {
-                         sdlAttributePtr *attr;
-                         sdlExtraAttributePtr *ext;
+                         sdlAttributePtr attr;
+                         sdlExtraAttributePtr ext;
 
                                if (type->attributes &&
-                                   zend_hash_find(type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
-                                     sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"),
-                                     (void **)&attr) == SUCCESS &&
-                                     zend_hash_find((*attr)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
-                                       char *end = strchr((*ext)->val, '[');
+                                   (attr = zend_hash_str_find_ptr(type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
+                                     sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType")-1)) != NULL &&
+                                   (ext = zend_hash_str_find_ptr(attr->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType")-1)) != NULL) {
+                                       char *end = strchr(ext->val, '[');
                                        int len;
                                        if (end == NULL) {
-                                               len = strlen((*ext)->val);
+                                               len = strlen(ext->val);
                                        } else {
-                                               len = end-(*ext)->val;
+                                               len = end-ext->val;
                                        }
                                        if (len == 0) {
                                                smart_str_appendl(buf, "anyType", sizeof("anyType")-1);
                                        } else {
-                                               smart_str_appendl(buf, (*ext)->val, len);
+                                               smart_str_appendl(buf, ext->val, len);
                                        }
                                        smart_str_appendc(buf, ' ');
                                        smart_str_appendl(buf, type->name, strlen(type->name));
@@ -4742,17 +4692,15 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
                                } else {
                                        sdlTypePtr elementType;
                                        if (type->attributes &&
-                                           zend_hash_find(type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
-                                             sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"),
-                                             (void **)&attr) == SUCCESS &&
-                                             zend_hash_find((*attr)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
-                                               smart_str_appends(buf, (*ext)->val);
+                                           (attr = zend_hash_str_find_ptr(type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
+                                             sizeof(SOAP_1_2_ENC_NAMESPACE":itemType")-1)) != NULL &&
+                                   (ext = zend_hash_str_find_ptr(attr->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arrayType")-1)) != NULL) {
+                                               smart_str_appends(buf, ext->val);
                                                smart_str_appendc(buf, ' ');
                                        } else if (type->elements &&
                                                   zend_hash_num_elements(type->elements) == 1 &&
                                                   (zend_hash_internal_pointer_reset(type->elements),
-                                                   zend_hash_get_current_data(type->elements, (void**)&elementType) == SUCCESS) &&
-                                                  (elementType = *(sdlTypePtr*)elementType) != NULL &&
+                                                   (elementType = zend_hash_get_current_data_ptr(type->elements)) != NULL) &&
                                                   elementType->encode && elementType->encode->details.type_str) {
                                                smart_str_appends(buf, elementType->encode->details.type_str);
                                                smart_str_appendc(buf, ' ');
@@ -4761,12 +4709,11 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
                                        }
                                        smart_str_appendl(buf, type->name, strlen(type->name));
                                        if (type->attributes &&
-                                           zend_hash_find(type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
-                                             sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
-                                             (void **)&attr) == SUCCESS &&
-                                             zend_hash_find((*attr)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arraySize"), (void **)&ext) == SUCCESS) {
+                                           (attr = zend_hash_str_find_ptr(type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
+                                             sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize")-1)) != NULL &&
+                                           (ext = zend_hash_str_find_ptr(attr->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arraySize")-1)) != NULL) {
                                                smart_str_appendc(buf, '[');
-                                               smart_str_appends(buf, (*ext)->val);
+                                               smart_str_appends(buf, ext->val);
                                                smart_str_appendc(buf, ']');
                                        } else {
                                                smart_str_appendl(buf, "[]", 2);
@@ -4788,7 +4735,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
                                                enc = enc->details.sdl_type->encode;
                                        }
                                        if (enc) {
-                                               smart_str_appendl(buf, spaces.c, spaces.len);
+                                               smart_str_appendl(buf, spaces.s->val, spaces.s->len);
                                                smart_str_appendc(buf, ' ');
                                                smart_str_appendl(buf, type->encode->details.type_str, strlen(type->encode->details.type_str));
                                                smart_str_appendl(buf, " _;\n", 4);
@@ -4798,24 +4745,22 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
                                        model_to_string(type->model, buf, level+1);
                                }
                                if (type->attributes) {
-                                       sdlAttributePtr *attr;
+                                       sdlAttributePtr attr;
 
-                                       zend_hash_internal_pointer_reset_ex(type->attributes, &pos);
-                                       while (zend_hash_get_current_data_ex(type->attributes, (void **)&attr, &pos) != FAILURE) {
-                                               smart_str_appendl(buf, spaces.c, spaces.len);
+                                       ZEND_HASH_FOREACH_PTR(type->attributes, attr) {
+                                               smart_str_appendl(buf, spaces.s->val, spaces.s->len);
                                                smart_str_appendc(buf, ' ');
-                                               if ((*attr)->encode && (*attr)->encode->details.type_str) {
-                                                       smart_str_appends(buf, (*attr)->encode->details.type_str);
+                                               if (attr->encode && attr->encode->details.type_str) {
+                                                       smart_str_appends(buf, attr->encode->details.type_str);
                                                        smart_str_appendc(buf, ' ');
                                                } else {
                                                        smart_str_appendl(buf, "UNKNOWN ", 8);
                                                }
-                                               smart_str_appends(buf, (*attr)->name);
+                                               smart_str_appends(buf, attr->name);
                                                smart_str_appendl(buf, ";\n", 2);
-                                               zend_hash_move_forward_ex(type->attributes, &pos);
-                                       }
+                                       } ZEND_HASH_FOREACH_END();
                                }
-                               smart_str_appendl(buf, spaces.c, spaces.len);
+                               smart_str_appendl(buf, spaces.s->val, spaces.s->len);
                                smart_str_appendc(buf, '}');
                        }
                        break;
@@ -4869,9 +4814,7 @@ static void delete_service(void *data)
                zend_hash_destroy(service->class_map);
                FREE_HASHTABLE(service->class_map);
        }
-       if (service->soap_object) {
-               zval_ptr_dtor(&service->soap_object);
-       }
+       zval_ptr_dtor(&service->soap_object);
        efree(service);
 }