diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/soap/php_encoding.c | 27 | ||||
-rw-r--r-- | ext/soap/tests/server030.phpt | 51 | ||||
-rw-r--r-- | ext/soap/tests/server030.wsdl | 59 |
4 files changed, 138 insertions, 1 deletions
@@ -1,6 +1,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 20??, PHP 5.3.0 +- Added ability to use SplArrays instead of plain arrays in ext/soap. + (Joshua Reese, Dmitry) - Added "?:" operator. (Marcus) - Added stream_supports_lock() function. (Benjamin Schulz) - Added msg_queue_exists() function. (Benjamin Schulz) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index df6b9cd6bd..d7dea05396 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -27,6 +27,10 @@ #include <libxml/parserInternals.h> #include "zend_strtod.h" +#ifdef HAVE_SPL +# include "ext/spl/spl_array.h" +#endif + /* zval type decode */ static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data); static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data); @@ -2238,7 +2242,9 @@ 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); @@ -2258,6 +2264,18 @@ 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) { + data = array_copy; + } + } +#endif + if (Z_TYPE_P(data) == IS_ARRAY) { sdlAttributePtr *arrayType; sdlExtraAttributePtr *ext; @@ -2435,6 +2453,13 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod set_ns_and_type(xmlParam, type); } } + +#ifdef HAVE_SPL + if (array_copy) { + zval_ptr_dtor(&array_copy); + } +#endif + return xmlParam; } diff --git a/ext/soap/tests/server030.phpt b/ext/soap/tests/server030.phpt new file mode 100644 index 0000000000..fa59bc77ad --- /dev/null +++ b/ext/soap/tests/server030.phpt @@ -0,0 +1,51 @@ +--TEST-- +SOAP Server 30: Handling classes which extend the SPL ArrayObject or ArrayIterator as arrays in wsdl mode +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +class ItemArray extends ArrayObject { + +} + +class Item { + public $text; +} + +class handlerClass { + public function getItems() + { + $items = new ItemArray(array()); + + for ($i = 0; $i < 10; $i++) { + $item = new Item(); + $item->text = 'text'.$i; + + $items[] = $item; + } + + return $items; + } +} + +$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 diff --git a/ext/soap/tests/server030.wsdl b/ext/soap/tests/server030.wsdl new file mode 100644 index 0000000000..2139c78d96 --- /dev/null +++ b/ext/soap/tests/server030.wsdl @@ -0,0 +1,59 @@ +<?xml version='1.0' encoding='UTF-8'?> +<definitions + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:si="http://soapinterop.org/xsd" + xmlns:tns="http://testuri.org" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns="http://schemas.xmlsoap.org/wsdl/" + targetNamespace="http://testuri.org"> + + <types> + <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://testuri.org"> + <xsd:complexType name="ItemArray"> + <xsd:complexContent> + <xsd:extension base="SOAP-ENC:Array"> + <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:Item[]"/> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <xsd:complexType name="Item"> + <xsd:sequence> + <xsd:element name="text" type="string"/> + </xsd:sequence> + </xsd:complexType> + </xsd:schema> + </types> + + <message name="getItems"/> + <message name="getItemsResponse"> + <part name="getItemsReturn" type="tns:ItemArray"/> + </message> + + <portType name="TestServicePortType"> + <operation name="getItems"> + <input message="tns:getItems"/> + <output message="tns:getItemsResponse"/> + </operation> + </portType> + + <binding name="TestServiceBinding" type="tns:TestServicePortType"> + <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> + <operation name="getItems"> + <soap:operation soapAction="http://testuri.orgTestServiceAction"/> + <input/> + <output> + <soap:body namespace="http://testuri.org" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> + </output> + </operation> + </binding> + + <service name="TestServiceService"> + <port name="TestServicePort" binding="tns:TestServiceBinding"> + <soap:address location="http://linuxsrv.home/~dmitry/soap/soap_server.php"/> + </port> + </service> + +</definitions> |