diff options
author | Dmitry Stogov <dmitry@php.net> | 2008-01-09 13:49:40 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2008-01-09 13:49:40 +0000 |
commit | 18226f79bcdb8f7df2d1dde919356a5539d7b8cb (patch) | |
tree | a05b2840c8e91a8f4b33a91d5a4ffa0ba5f332d1 /ext/soap | |
parent | 9238ee440f661530bb58c2a499dc2bb5ae9d58c6 (diff) | |
download | php-git-18226f79bcdb8f7df2d1dde919356a5539d7b8cb.tar.gz |
Remplemented support for SplArray using Traversable interface.
Diffstat (limited to 'ext/soap')
-rw-r--r-- | ext/soap/php_encoding.c | 82 | ||||
-rw-r--r-- | ext/soap/tests/server031.phpt | 67 |
2 files changed, 133 insertions, 16 deletions
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 <libxml/parserInternals.h> #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-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +class ItemArray implements Iterator { + private $a = array(); + + public function __construct(array $a) { + $this->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 +<?xml version="1.0" encoding="ISO-8859-1"?> +<SOAP-ENV:Envelope + SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> + <SOAP-ENV:Body> + <getItems/> + </SOAP-ENV:Body> +</SOAP-ENV:Envelope> +EOF; + +$server->handle($HTTP_RAW_POST_DATA); +echo "ok\n"; +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getItemsResponse><getItemsReturn SOAP-ENC:arrayType="ns1:Item[10]" xsi:type="ns1:ItemArray"><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text0</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text1</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text2</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text3</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text4</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text5</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text6</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text7</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text8</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text9</text></item></getItemsReturn></ns1:getItemsResponse></SOAP-ENV:Body></SOAP-ENV:Envelope> +ok |