From 18226f79bcdb8f7df2d1dde919356a5539d7b8cb Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 9 Jan 2008 13:49:40 +0000 Subject: Remplemented support for SplArray using Traversable interface. --- ext/soap/php_encoding.c | 82 ++++++++++++++++++++++++++++++++++--------- ext/soap/tests/server031.phpt | 67 +++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 ext/soap/tests/server031.phpt (limited to 'ext/soap') diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 5fcfdcfc74..b6225270e8 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -26,10 +26,7 @@ #include "ext/standard/base64.h" #include #include "zend_strtod.h" - -#ifdef HAVE_SPL -# include "ext/spl/spl_array.h" -#endif +#include "zend_interfaces.h" /* zval type decode */ static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data); @@ -2242,9 +2239,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod int dimension = 1; int* dims; int soap_version; -#ifdef HAVE_SPL zval *array_copy = NULL; -#endif TSRMLS_FETCH(); soap_version = SOAP_GLOBAL(soap_version); @@ -2264,17 +2259,74 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod return xmlParam; } -#ifdef HAVE_SPL - if (Z_TYPE_P(data) == IS_OBJECT && (instanceof_function(Z_OBJCE_P(data), spl_ce_ArrayObject TSRMLS_CC) || instanceof_function(Z_OBJCE_P(data), spl_ce_ArrayIterator TSRMLS_CC))) { - zval getArray; - - ZVAL_STRING(&getArray, "getArrayCopy", 0); - call_user_function_ex(NULL, &data, &getArray, &array_copy, 0, 0, 0, NULL TSRMLS_CC); - if (Z_TYPE_P(array_copy) == IS_ARRAY) { + 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; + char *str_key; + uint str_key_len; + ulong int_key; + int key_type; + + ALLOC_ZVAL(array_copy); + INIT_PZVAL(array_copy); + array_init(array_copy); + + iter = ce->get_iterator(ce, data, 0 TSRMLS_CC); + + if (EG(exception)) { + goto iterator_done; + } + + if (iter->funcs->rewind) { + iter->funcs->rewind(iter TSRMLS_CC); + if (EG(exception)) { + goto iterator_done; + } + } + + while (iter->funcs->valid(iter TSRMLS_CC) == SUCCESS) { + if (EG(exception)) { + goto iterator_done; + } + + iter->funcs->get_current_data(iter, &val TSRMLS_CC); + if (EG(exception)) { + goto iterator_done; + } + if (iter->funcs->get_current_key) { + key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC); + if (EG(exception)) { + goto iterator_done; + } + switch(key_type) { + case HASH_KEY_IS_STRING: + add_assoc_zval_ex(array_copy, str_key, str_key_len, *val); + efree(str_key); + break; + case HASH_KEY_IS_LONG: + add_index_zval(array_copy, int_key, *val); + break; + } + } else { + add_next_index_zval(array_copy, *val); + } + Z_ADDREF_PP(val); + + iter->funcs->move_forward(iter TSRMLS_CC); + if (EG(exception)) { + goto iterator_done; + } + } +iterator_done: + iter->funcs->dtor(iter TSRMLS_CC); + if (EG(exception)) { + zval_ptr_dtor(&array_copy); + array_copy = NULL; + } else { data = array_copy; } } -#endif if (Z_TYPE_P(data) == IS_ARRAY) { sdlAttributePtr *arrayType; @@ -2454,11 +2506,9 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod } } -#ifdef HAVE_SPL if (array_copy) { zval_ptr_dtor(&array_copy); } -#endif return xmlParam; } diff --git a/ext/soap/tests/server031.phpt b/ext/soap/tests/server031.phpt new file mode 100644 index 0000000000..f520f1f9f1 --- /dev/null +++ b/ext/soap/tests/server031.phpt @@ -0,0 +1,67 @@ +--TEST-- +SOAP Server 31: Handling classes which implements Iterator +--SKIPIF-- + +--FILE-- +a = $a; + } + + public function rewind() { return reset($this->a); } + public function current() { return current($this->a); } + public function key() { return key($this->a); } + public function next() { return next($this->a); } + public function valid() { return (current($this->a) !== false); } +} + +class Item { + public $text; + + public function __construct($n) { + $this->text = 'text'.$n; + } +} + +class handlerClass { + public function getItems() + { + return new ItemArray(array( + new Item(0), + new Item(1), + new Item(2), + new Item(3), + new Item(4), + new Item(5), + new Item(6), + new Item(7), + new Item(8), + new Item(9) + )); + } +} + +$server = new SoapServer(dirname(__FILE__)."/server030.wsdl"); +$server->setClass('handlerClass'); + +$HTTP_RAW_POST_DATA = << + + + + + +EOF; + +$server->handle($HTTP_RAW_POST_DATA); +echo "ok\n"; +?> +--EXPECT-- + +text0text1text2text3text4text5text6text7text8text9 +ok -- cgit v1.2.1