summaryrefslogtreecommitdiff
path: root/ext/soap
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2008-01-09 13:49:40 +0000
committerDmitry Stogov <dmitry@php.net>2008-01-09 13:49:40 +0000
commit18226f79bcdb8f7df2d1dde919356a5539d7b8cb (patch)
treea05b2840c8e91a8f4b33a91d5a4ffa0ba5f332d1 /ext/soap
parent9238ee440f661530bb58c2a499dc2bb5ae9d58c6 (diff)
downloadphp-git-18226f79bcdb8f7df2d1dde919356a5539d7b8cb.tar.gz
Remplemented support for SplArray using Traversable interface.
Diffstat (limited to 'ext/soap')
-rw-r--r--ext/soap/php_encoding.c82
-rw-r--r--ext/soap/tests/server031.phpt67
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