2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Brad Lafountain <rodif_bl@yahoo.com> |
16 | Shane Caraveo <shane@caraveo.com> |
17 | Dmitry Stogov <dmitry@zend.com> |
18 +----------------------------------------------------------------------+
26 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
27 #include "ext/session/php_session.h"
29 #include "zend_exceptions.h"
32 static int le_sdl
= 0;
34 static int le_service
= 0;
35 static int le_typemap
= 0;
37 typedef struct _soapHeader
{
38 sdlFunctionPtr function
;
44 sdlSoapBindingFunctionHeaderPtr hdr
;
45 struct _soapHeader
*next
;
49 static void function_to_string(sdlFunctionPtr function
, smart_str
*buf
);
50 static void type_to_string(sdlTypePtr type
, smart_str
*buf
, int level
);
52 static void clear_soap_fault(zval
*obj TSRMLS_DC
);
53 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
);
54 static void soap_server_fault(char* code
, char* string
, char *actor
, zval
* details
, char *name TSRMLS_DC
);
55 static void soap_server_fault_ex(sdlFunctionPtr function
, zval
* fault
, soapHeader
* hdr TSRMLS_DC
);
57 static sdlParamPtr
get_param(sdlFunctionPtr function
, char *param_name
, int index
, int);
58 static sdlFunctionPtr
get_function(sdlPtr sdl
, const char *function_name
);
59 static sdlFunctionPtr
get_doc_function(sdlPtr sdl
, xmlNodePtr node
);
61 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
);
62 static xmlDocPtr
serialize_response_call(sdlFunctionPtr function
, char *function_name
,char *uri
,zval
*ret
, soapHeader
*headers
, int version TSRMLS_DC
);
63 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
);
64 static xmlNodePtr
serialize_parameter(sdlParamPtr param
,zval
*param_val
,int index
,char *name
, int style
, xmlNodePtr parent TSRMLS_DC
);
65 static xmlNodePtr
serialize_zval(zval
*val
, sdlParamPtr param
, char *paramName
, int style
, xmlNodePtr parent TSRMLS_DC
);
67 static void delete_service(void *service
);
68 static void delete_url(void *handle
);
69 static void delete_hashtable(void *hashtable
);
71 static void soap_error_handler(int error_num
, const char *error_filename
, const uint error_lineno
, const char *format
, va_list args
);
73 #define SOAP_SERVER_BEGIN_CODE() \
74 zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
75 char* _old_error_code = SOAP_GLOBAL(error_code);\
76 zval* _old_error_object = SOAP_GLOBAL(error_object);\
77 int _old_soap_version = SOAP_GLOBAL(soap_version);\
78 SOAP_GLOBAL(use_soap_error_handler) = 1;\
79 SOAP_GLOBAL(error_code) = "Server";\
80 SOAP_GLOBAL(error_object) = this_ptr;
82 #define SOAP_SERVER_END_CODE() \
83 SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
84 SOAP_GLOBAL(error_code) = _old_error_code;\
85 SOAP_GLOBAL(error_object) = _old_error_object;\
86 SOAP_GLOBAL(soap_version) = _old_soap_version;
88 #define SOAP_CLIENT_BEGIN_CODE() \
89 zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
90 char* _old_error_code = SOAP_GLOBAL(error_code);\
91 zval* _old_error_object = SOAP_GLOBAL(error_object);\
92 int _old_soap_version = SOAP_GLOBAL(soap_version);\
93 zend_bool _old_in_compilation = CG(in_compilation); \
94 zend_bool _old_in_execution = EG(in_execution); \
95 zend_execute_data *_old_current_execute_data = EG(current_execute_data); \
96 void **_old_stack_top = EG(argument_stack)->top; \
98 SOAP_GLOBAL(use_soap_error_handler) = 1;\
99 SOAP_GLOBAL(error_code) = "Client";\
100 SOAP_GLOBAL(error_object) = this_ptr;\
103 #define SOAP_CLIENT_END_CODE() \
105 CG(in_compilation) = _old_in_compilation; \
106 EG(in_execution) = _old_in_execution; \
107 EG(current_execute_data) = _old_current_execute_data; \
108 if (EG(exception) == NULL || \
109 Z_TYPE_P(EG(exception)) != IS_OBJECT || \
110 !instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {\
113 if (_old_stack_top != EG(argument_stack)->top) { \
114 while (EG(argument_stack)->prev != NULL && \
115 ((char*)_old_stack_top < (char*)EG(argument_stack) || \
116 (char*) _old_stack_top > (char*)EG(argument_stack)->end)) { \
117 zend_vm_stack tmp = EG(argument_stack)->prev; \
118 efree(EG(argument_stack)); \
119 EG(argument_stack) = tmp; \
121 EG(argument_stack)->top = _old_stack_top; \
124 SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
125 SOAP_GLOBAL(error_code) = _old_error_code;\
126 SOAP_GLOBAL(error_object) = _old_error_object;\
127 SOAP_GLOBAL(soap_version) = _old_soap_version;\
132 #define FETCH_THIS_SDL(ss) \
135 if(FIND_SDL_PROPERTY(this_ptr,__tmp) != FAILURE) { \
136 FETCH_SDL_RES(ss,__tmp); \
142 #define FIND_SDL_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "sdl", sizeof("sdl"), (void **)&tmp)
143 #define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource(tmp TSRMLS_CC, -1, "sdl", NULL, 1, le_sdl)
145 #define FIND_TYPEMAP_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "typemap", sizeof("typemap"), (void **)&tmp)
146 #define FETCH_TYPEMAP_RES(ss,tmp) ss = (HashTable*) zend_fetch_resource(tmp TSRMLS_CC, -1, "typemap", NULL, 1, le_typemap)
148 #define FETCH_THIS_SERVICE(ss) \
151 if (zend_hash_find(Z_OBJPROP_P(this_ptr),"service", sizeof("service"), (void **)&tmp) != FAILURE) { \
152 ss = (soapServicePtr)zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service); \
158 static zend_class_entry
* soap_class_entry
;
159 static zend_class_entry
* soap_server_class_entry
;
160 static zend_class_entry
* soap_fault_class_entry
;
161 static zend_class_entry
* soap_header_class_entry
;
162 static zend_class_entry
* soap_param_class_entry
;
163 zend_class_entry
* soap_var_class_entry
;
165 ZEND_DECLARE_MODULE_GLOBALS(soap
)
167 static void (*old_error_handler
)(int, const char *, const uint
, const char*, va_list);
170 #define call_old_error_handler(error_num, error_filename, error_lineno, format, args) \
173 va_copy(copy, args); \
174 old_error_handler(error_num, error_filename, error_lineno, format, copy); \
178 #define call_old_error_handler(error_num, error_filename, error_lineno, format, args) \
180 old_error_handler(error_num, error_filename, error_lineno, format, args); \
184 #define PHP_SOAP_SERVER_CLASSNAME "SoapServer"
185 #define PHP_SOAP_CLIENT_CLASSNAME "SoapClient"
186 #define PHP_SOAP_VAR_CLASSNAME "SoapVar"
187 #define PHP_SOAP_FAULT_CLASSNAME "SoapFault"
188 #define PHP_SOAP_PARAM_CLASSNAME "SoapParam"
189 #define PHP_SOAP_HEADER_CLASSNAME "SoapHeader"
191 PHP_RINIT_FUNCTION(soap
);
192 PHP_MINIT_FUNCTION(soap
);
193 PHP_MSHUTDOWN_FUNCTION(soap
);
194 PHP_MINFO_FUNCTION(soap
);
200 PHP_FUNCTION(soap_encode_to_xml
);
201 PHP_FUNCTION(soap_encode_to_zval
);
202 PHP_FUNCTION(use_soap_error_handler
);
203 PHP_FUNCTION(is_soap_fault
);
206 /* Server Functions */
207 PHP_METHOD(SoapServer
, SoapServer
);
208 PHP_METHOD(SoapServer
, setClass
);
209 PHP_METHOD(SoapServer
, setObject
);
210 PHP_METHOD(SoapServer
, addFunction
);
211 PHP_METHOD(SoapServer
, getFunctions
);
212 PHP_METHOD(SoapServer
, handle
);
213 PHP_METHOD(SoapServer
, setPersistence
);
214 PHP_METHOD(SoapServer
, fault
);
215 PHP_METHOD(SoapServer
, addSoapHeader
);
217 /* Client Functions */
218 PHP_METHOD(SoapClient
, SoapClient
);
219 PHP_METHOD(SoapClient
, __call
);
220 PHP_METHOD(SoapClient
, __getLastRequest
);
221 PHP_METHOD(SoapClient
, __getLastResponse
);
222 PHP_METHOD(SoapClient
, __getLastRequestHeaders
);
223 PHP_METHOD(SoapClient
, __getLastResponseHeaders
);
224 PHP_METHOD(SoapClient
, __getFunctions
);
225 PHP_METHOD(SoapClient
, __getTypes
);
226 PHP_METHOD(SoapClient
, __doRequest
);
227 PHP_METHOD(SoapClient
, __setCookie
);
228 PHP_METHOD(SoapClient
, __setLocation
);
229 PHP_METHOD(SoapClient
, __setSoapHeaders
);
231 /* SoapVar Functions */
232 PHP_METHOD(SoapVar
, SoapVar
);
234 /* SoapFault Functions */
235 PHP_METHOD(SoapFault
, SoapFault
);
236 PHP_METHOD(SoapFault
, __toString
);
238 /* SoapParam Functions */
239 PHP_METHOD(SoapParam
, SoapParam
);
241 /* SoapHeader Functions */
242 PHP_METHOD(SoapHeader
, SoapHeader
);
244 #define SOAP_CTOR(class_name, func_name, arginfo, flags) PHP_ME(class_name, func_name, arginfo, flags)
247 ZEND_BEGIN_ARG_INFO(arginfo_soap__void
, 0)
250 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapparam_soapparam
, 0, 0, 2)
251 ZEND_ARG_INFO(0, data
)
252 ZEND_ARG_INFO(0, name
)
255 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapheader_soapheader
, 0, 0, 2)
256 ZEND_ARG_INFO(0, namespace)
257 ZEND_ARG_INFO(0, name
)
258 ZEND_ARG_INFO(0, data
)
259 ZEND_ARG_INFO(0, mustunderstand
)
260 ZEND_ARG_INFO(0, actor
)
263 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapfault_soapfault
, 0, 0, 2)
264 ZEND_ARG_INFO(0, faultcode
)
265 ZEND_ARG_INFO(0, faultstring
)
266 ZEND_ARG_INFO(0, faultactor
)
267 ZEND_ARG_INFO(0, detail
)
268 ZEND_ARG_INFO(0, faultname
)
269 ZEND_ARG_INFO(0, headerfault
)
272 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapvar_soapvar
, 0, 0, 2)
273 ZEND_ARG_INFO(0, data
)
274 ZEND_ARG_INFO(0, encoding
)
275 ZEND_ARG_INFO(0, type_name
)
276 ZEND_ARG_INFO(0, type_namespace
)
277 ZEND_ARG_INFO(0, node_name
)
278 ZEND_ARG_INFO(0, node_namespace
)
281 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_fault
, 0, 0, 2)
282 ZEND_ARG_INFO(0, code
)
283 ZEND_ARG_INFO(0, string
)
284 ZEND_ARG_INFO(0, actor
)
285 ZEND_ARG_INFO(0, details
)
286 ZEND_ARG_INFO(0, name
)
289 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_addsoapheader
, 0, 0, 1)
290 ZEND_ARG_INFO(0, object
)
293 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_soapserver
, 0, 0, 1)
294 ZEND_ARG_INFO(0, wsdl
)
295 ZEND_ARG_INFO(0, options
)
298 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setpersistence
, 0, 0, 1)
299 ZEND_ARG_INFO(0, mode
)
302 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setclass
, 0, 0, 1)
303 ZEND_ARG_INFO(0, class_name
)
304 ZEND_ARG_INFO(0, args
)
307 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setobject
, 0, 0, 1)
308 ZEND_ARG_INFO(0, object
)
311 ZEND_BEGIN_ARG_INFO(arginfo_soapserver_getfunctions
, 0)
314 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_addfunction
, 0, 0, 1)
315 ZEND_ARG_INFO(0, functions
)
318 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_handle
, 0, 0, 0)
319 ZEND_ARG_INFO(0, soap_request
)
322 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient_soapclient
, 0, 0, 1)
323 ZEND_ARG_INFO(0, wsdl
)
324 ZEND_ARG_INFO(0, options
)
327 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___call
, 0, 0, 2)
328 ZEND_ARG_INFO(0, function_name
)
329 ZEND_ARG_INFO(0, arguments
)
332 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___soapcall
, 0, 0, 2)
333 ZEND_ARG_INFO(0, function_name
)
334 ZEND_ARG_INFO(0, arguments
)
335 ZEND_ARG_INFO(0, options
)
336 ZEND_ARG_INFO(0, input_headers
)
337 ZEND_ARG_INFO(1, output_headers
)
340 ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getfunctions
, 0)
343 ZEND_BEGIN_ARG_INFO(arginfo_soapclient___gettypes
, 0)
346 ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastrequest
, 0)
349 ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastresponse
, 0)
352 ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastrequestheaders
, 0)
355 ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastresponseheaders
, 0)
358 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___dorequest
, 0, 0, 4)
359 ZEND_ARG_INFO(0, request
)
360 ZEND_ARG_INFO(0, location
)
361 ZEND_ARG_INFO(0, action
)
362 ZEND_ARG_INFO(0, version
)
363 ZEND_ARG_INFO(0, one_way
)
366 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setcookie
, 0, 0, 1)
367 ZEND_ARG_INFO(0, name
)
368 ZEND_ARG_INFO(0, value
)
371 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setsoapheaders
, 0, 0, 1)
372 ZEND_ARG_INFO(0, soapheaders
)
375 ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setlocation
, 0, 0, 0)
376 ZEND_ARG_INFO(0, new_location
)
379 ZEND_BEGIN_ARG_INFO_EX(arginfo_soap_use_soap_error_handler
, 0, 0, 0)
380 ZEND_ARG_INFO(0, handler
)
383 ZEND_BEGIN_ARG_INFO_EX(arginfo_soap_is_soap_fault
, 0, 0, 1)
384 ZEND_ARG_INFO(0, object
)
388 static const zend_function_entry soap_functions
[] = {
389 PHP_FE(use_soap_error_handler
, arginfo_soap_use_soap_error_handler
)
390 PHP_FE(is_soap_fault
, arginfo_soap_is_soap_fault
)
394 static const zend_function_entry soap_fault_functions
[] = {
395 SOAP_CTOR(SoapFault
, SoapFault
, arginfo_soapfault_soapfault
, 0)
396 PHP_ME(SoapFault
, __toString
, arginfo_soap__void
, 0)
400 static const zend_function_entry soap_server_functions
[] = {
401 SOAP_CTOR(SoapServer
, SoapServer
, arginfo_soapserver_soapserver
, 0)
402 PHP_ME(SoapServer
, setPersistence
, arginfo_soapserver_setpersistence
, 0)
403 PHP_ME(SoapServer
, setClass
, arginfo_soapserver_setclass
, 0)
404 PHP_ME(SoapServer
, setObject
, arginfo_soapserver_setobject
, 0)
405 PHP_ME(SoapServer
, addFunction
, arginfo_soapserver_addfunction
, 0)
406 PHP_ME(SoapServer
, getFunctions
, arginfo_soapserver_getfunctions
, 0)
407 PHP_ME(SoapServer
, handle
, arginfo_soapserver_handle
, 0)
408 PHP_ME(SoapServer
, fault
, arginfo_soapserver_fault
, 0)
409 PHP_ME(SoapServer
, addSoapHeader
, arginfo_soapserver_addsoapheader
, 0)
413 static const zend_function_entry soap_client_functions
[] = {
414 SOAP_CTOR(SoapClient
, SoapClient
, arginfo_soapclient_soapclient
, 0)
415 PHP_ME(SoapClient
, __call
, arginfo_soapclient___call
, 0)
416 ZEND_NAMED_ME(__soapCall
, ZEND_MN(SoapClient___call
), arginfo_soapclient___soapcall
, 0)
417 PHP_ME(SoapClient
, __getLastRequest
, arginfo_soapclient___getlastrequest
, 0)
418 PHP_ME(SoapClient
, __getLastResponse
, arginfo_soapclient___getlastresponse
, 0)
419 PHP_ME(SoapClient
, __getLastRequestHeaders
, arginfo_soapclient___getlastrequestheaders
, 0)
420 PHP_ME(SoapClient
, __getLastResponseHeaders
, arginfo_soapclient___getlastresponseheaders
, 0)
421 PHP_ME(SoapClient
, __getFunctions
, arginfo_soapclient___getfunctions
, 0)
422 PHP_ME(SoapClient
, __getTypes
, arginfo_soapclient___gettypes
, 0)
423 PHP_ME(SoapClient
, __doRequest
, arginfo_soapclient___dorequest
, 0)
424 PHP_ME(SoapClient
, __setCookie
, arginfo_soapclient___setcookie
, 0)
425 PHP_ME(SoapClient
, __setLocation
, arginfo_soapclient___setlocation
, 0)
426 PHP_ME(SoapClient
, __setSoapHeaders
, arginfo_soapclient___setsoapheaders
, 0)
430 static const zend_function_entry soap_var_functions
[] = {
431 SOAP_CTOR(SoapVar
, SoapVar
, arginfo_soapvar_soapvar
, 0)
435 static const zend_function_entry soap_param_functions
[] = {
436 SOAP_CTOR(SoapParam
, SoapParam
, arginfo_soapparam_soapparam
, 0)
440 static const zend_function_entry soap_header_functions
[] = {
441 SOAP_CTOR(SoapHeader
, SoapHeader
, arginfo_soapheader_soapheader
, 0)
445 zend_module_entry soap_module_entry
= {
446 #ifdef STANDARD_MODULE_HEADER
447 STANDARD_MODULE_HEADER
,
456 #ifdef STANDARD_MODULE_HEADER
459 STANDARD_MODULE_PROPERTIES
,
462 #ifdef COMPILE_DL_SOAP
463 ZEND_GET_MODULE(soap
)
466 ZEND_INI_MH(OnUpdateCacheMode
)
470 char *base
= (char *) mh_arg2
;
472 char *base
= (char *) ts_resource(*((int *) mh_arg2
));
475 p
= (char*) (base
+(size_t) mh_arg1
);
477 *p
= (char)atoi(new_value
);
482 static PHP_INI_MH(OnUpdateCacheDir
)
484 /* Only do the open_basedir check at runtime */
485 if (stage
== PHP_INI_STAGE_RUNTIME
|| stage
== PHP_INI_STAGE_HTACCESS
) {
488 if (memchr(new_value
, '\0', new_value_length
) != NULL
) {
492 /* we do not use zend_memrchr() since path can contain ; itself */
493 if ((p
= strchr(new_value
, ';'))) {
496 if ((p2
= strchr(p
, ';'))) {
503 if (PG(open_basedir
) && *p
&& php_check_open_basedir(p TSRMLS_CC
)) {
508 OnUpdateString(entry
, new_value
, new_value_length
, mh_arg1
, mh_arg2
, mh_arg3
, stage TSRMLS_CC
);
513 STD_PHP_INI_ENTRY("soap.wsdl_cache_enabled", "1", PHP_INI_ALL
, OnUpdateBool
,
514 cache_enabled
, zend_soap_globals
, soap_globals
)
515 STD_PHP_INI_ENTRY("soap.wsdl_cache_dir", "/tmp", PHP_INI_ALL
, OnUpdateCacheDir
,
516 cache_dir
, zend_soap_globals
, soap_globals
)
517 STD_PHP_INI_ENTRY("soap.wsdl_cache_ttl", "86400", PHP_INI_ALL
, OnUpdateLong
,
518 cache_ttl
, zend_soap_globals
, soap_globals
)
519 STD_PHP_INI_ENTRY("soap.wsdl_cache", "1", PHP_INI_ALL
, OnUpdateCacheMode
,
520 cache_mode
, zend_soap_globals
, soap_globals
)
521 STD_PHP_INI_ENTRY("soap.wsdl_cache_limit", "5", PHP_INI_ALL
, OnUpdateLong
,
522 cache_limit
, zend_soap_globals
, soap_globals
)
525 static HashTable defEnc
, defEncIndex
, defEncNs
;
527 static void php_soap_prepare_globals()
532 zend_hash_init(&defEnc
, 0, NULL
, NULL
, 1);
533 zend_hash_init(&defEncIndex
, 0, NULL
, NULL
, 1);
534 zend_hash_init(&defEncNs
, 0, NULL
, NULL
, 1);
538 enc
= &defaultEncoding
[i
];
540 /* If has a ns and a str_type then index it */
541 if (defaultEncoding
[i
].details
.type_str
) {
542 if (defaultEncoding
[i
].details
.ns
!= NULL
) {
544 spprintf(&ns_type
, 0, "%s:%s", defaultEncoding
[i
].details
.ns
, defaultEncoding
[i
].details
.type_str
);
545 zend_hash_add(&defEnc
, ns_type
, strlen(ns_type
) + 1, &enc
, sizeof(encodePtr
), NULL
);
548 zend_hash_add(&defEnc
, defaultEncoding
[i
].details
.type_str
, strlen(defaultEncoding
[i
].details
.type_str
) + 1, &enc
, sizeof(encodePtr
), NULL
);
551 /* Index everything by number */
552 if (!zend_hash_index_exists(&defEncIndex
, defaultEncoding
[i
].details
.type
)) {
553 zend_hash_index_update(&defEncIndex
, defaultEncoding
[i
].details
.type
, &enc
, sizeof(encodePtr
), NULL
);
556 } while (defaultEncoding
[i
].details
.type
!= END_KNOWN_TYPES
);
558 /* hash by namespace */
559 zend_hash_add(&defEncNs
, XSD_1999_NAMESPACE
, sizeof(XSD_1999_NAMESPACE
), XSD_NS_PREFIX
, sizeof(XSD_NS_PREFIX
), NULL
);
560 zend_hash_add(&defEncNs
, XSD_NAMESPACE
, sizeof(XSD_NAMESPACE
), XSD_NS_PREFIX
, sizeof(XSD_NS_PREFIX
), NULL
);
561 zend_hash_add(&defEncNs
, XSI_NAMESPACE
, sizeof(XSI_NAMESPACE
), XSI_NS_PREFIX
, sizeof(XSI_NS_PREFIX
), NULL
);
562 zend_hash_add(&defEncNs
, XML_NAMESPACE
, sizeof(XML_NAMESPACE
), XML_NS_PREFIX
, sizeof(XML_NS_PREFIX
), NULL
);
563 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
);
564 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
);
567 static void php_soap_init_globals(zend_soap_globals
*soap_globals TSRMLS_DC
)
569 soap_globals
->defEnc
= defEnc
;
570 soap_globals
->defEncIndex
= defEncIndex
;
571 soap_globals
->defEncNs
= defEncNs
;
572 soap_globals
->typemap
= NULL
;
573 soap_globals
->use_soap_error_handler
= 0;
574 soap_globals
->error_code
= NULL
;
575 soap_globals
->error_object
= NULL
;
576 soap_globals
->sdl
= NULL
;
577 soap_globals
->soap_version
= SOAP_1_1
;
578 soap_globals
->mem_cache
= NULL
;
579 soap_globals
->ref_map
= NULL
;
582 PHP_MSHUTDOWN_FUNCTION(soap
)
584 zend_error_cb
= old_error_handler
;
585 zend_hash_destroy(&SOAP_GLOBAL(defEnc
));
586 zend_hash_destroy(&SOAP_GLOBAL(defEncIndex
));
587 zend_hash_destroy(&SOAP_GLOBAL(defEncNs
));
588 if (SOAP_GLOBAL(mem_cache
)) {
589 zend_hash_destroy(SOAP_GLOBAL(mem_cache
));
590 free(SOAP_GLOBAL(mem_cache
));
592 UNREGISTER_INI_ENTRIES();
596 PHP_RINIT_FUNCTION(soap
)
598 SOAP_GLOBAL(typemap
) = NULL
;
599 SOAP_GLOBAL(use_soap_error_handler
) = 0;
600 SOAP_GLOBAL(error_code
) = NULL
;
601 SOAP_GLOBAL(error_object
) = NULL
;
602 SOAP_GLOBAL(sdl
) = NULL
;
603 SOAP_GLOBAL(soap_version
) = SOAP_1_1
;
604 SOAP_GLOBAL(encoding
) = NULL
;
605 SOAP_GLOBAL(class_map
) = NULL
;
606 SOAP_GLOBAL(features
) = 0;
607 SOAP_GLOBAL(ref_map
) = NULL
;
611 PHP_MINIT_FUNCTION(soap
)
615 /* TODO: add ini entry for always use soap errors */
616 php_soap_prepare_globals();
617 ZEND_INIT_MODULE_GLOBALS(soap
, php_soap_init_globals
, NULL
);
618 REGISTER_INI_ENTRIES();
620 /* Register SoapClient class */
621 /* BIG NOTE : THIS EMITS AN COMPILATION WARNING UNDER ZE2 - handle_function_call deprecated.
622 soap_call_function_handler should be of type struct _zend_function, not (*handle_function_call).
625 zend_internal_function fe
;
627 fe
.type
= ZEND_INTERNAL_FUNCTION
;
628 fe
.handler
= ZEND_MN(SoapClient___call
);
629 fe
.function_name
= NULL
;
636 INIT_OVERLOADED_CLASS_ENTRY(ce
, PHP_SOAP_CLIENT_CLASSNAME
, soap_client_functions
,
637 (zend_function
*)&fe
, NULL
, NULL
);
638 soap_class_entry
= zend_register_internal_class(&ce TSRMLS_CC
);
640 /* Register SoapVar class */
641 INIT_CLASS_ENTRY(ce
, PHP_SOAP_VAR_CLASSNAME
, soap_var_functions
);
642 soap_var_class_entry
= zend_register_internal_class(&ce TSRMLS_CC
);
644 /* Register SoapServer class */
645 INIT_CLASS_ENTRY(ce
, PHP_SOAP_SERVER_CLASSNAME
, soap_server_functions
);
646 soap_server_class_entry
= zend_register_internal_class(&ce TSRMLS_CC
);
648 /* Register SoapFault class */
649 INIT_CLASS_ENTRY(ce
, PHP_SOAP_FAULT_CLASSNAME
, soap_fault_functions
);
650 soap_fault_class_entry
= zend_register_internal_class_ex(&ce
, zend_exception_get_default(TSRMLS_C
), NULL TSRMLS_CC
);
652 /* Register SoapParam class */
653 INIT_CLASS_ENTRY(ce
, PHP_SOAP_PARAM_CLASSNAME
, soap_param_functions
);
654 soap_param_class_entry
= zend_register_internal_class(&ce TSRMLS_CC
);
656 INIT_CLASS_ENTRY(ce
, PHP_SOAP_HEADER_CLASSNAME
, soap_header_functions
);
657 soap_header_class_entry
= zend_register_internal_class(&ce TSRMLS_CC
);
659 le_sdl
= register_list_destructors(delete_sdl
, NULL
);
660 le_url
= register_list_destructors(delete_url
, NULL
);
661 le_service
= register_list_destructors(delete_service
, NULL
);
662 le_typemap
= register_list_destructors(delete_hashtable
, NULL
);
664 REGISTER_LONG_CONSTANT("SOAP_1_1", SOAP_1_1
, CONST_CS
| CONST_PERSISTENT
);
665 REGISTER_LONG_CONSTANT("SOAP_1_2", SOAP_1_2
, CONST_CS
| CONST_PERSISTENT
);
667 REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_SESSION", SOAP_PERSISTENCE_SESSION
, CONST_CS
| CONST_PERSISTENT
);
668 REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_REQUEST", SOAP_PERSISTENCE_REQUEST
, CONST_CS
| CONST_PERSISTENT
);
669 REGISTER_LONG_CONSTANT("SOAP_FUNCTIONS_ALL", SOAP_FUNCTIONS_ALL
, CONST_CS
| CONST_PERSISTENT
);
671 REGISTER_LONG_CONSTANT("SOAP_ENCODED", SOAP_ENCODED
, CONST_CS
| CONST_PERSISTENT
);
672 REGISTER_LONG_CONSTANT("SOAP_LITERAL", SOAP_LITERAL
, CONST_CS
| CONST_PERSISTENT
);
674 REGISTER_LONG_CONSTANT("SOAP_RPC", SOAP_RPC
, CONST_CS
| CONST_PERSISTENT
);
675 REGISTER_LONG_CONSTANT("SOAP_DOCUMENT", SOAP_DOCUMENT
, CONST_CS
| CONST_PERSISTENT
);
677 REGISTER_LONG_CONSTANT("SOAP_ACTOR_NEXT", SOAP_ACTOR_NEXT
, CONST_CS
| CONST_PERSISTENT
);
678 REGISTER_LONG_CONSTANT("SOAP_ACTOR_NONE", SOAP_ACTOR_NONE
, CONST_CS
| CONST_PERSISTENT
);
679 REGISTER_LONG_CONSTANT("SOAP_ACTOR_UNLIMATERECEIVER", SOAP_ACTOR_UNLIMATERECEIVER
, CONST_CS
| CONST_PERSISTENT
);
681 REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_ACCEPT", SOAP_COMPRESSION_ACCEPT
, CONST_CS
| CONST_PERSISTENT
);
682 REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_GZIP", SOAP_COMPRESSION_GZIP
, CONST_CS
| CONST_PERSISTENT
);
683 REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_DEFLATE", SOAP_COMPRESSION_DEFLATE
, CONST_CS
| CONST_PERSISTENT
);
685 REGISTER_LONG_CONSTANT("SOAP_AUTHENTICATION_BASIC", SOAP_AUTHENTICATION_BASIC
, CONST_CS
| CONST_PERSISTENT
);
686 REGISTER_LONG_CONSTANT("SOAP_AUTHENTICATION_DIGEST", SOAP_AUTHENTICATION_DIGEST
, CONST_CS
| CONST_PERSISTENT
);
688 REGISTER_LONG_CONSTANT("UNKNOWN_TYPE", UNKNOWN_TYPE
, CONST_CS
| CONST_PERSISTENT
);
690 REGISTER_LONG_CONSTANT("XSD_STRING", XSD_STRING
, CONST_CS
| CONST_PERSISTENT
);
691 REGISTER_LONG_CONSTANT("XSD_BOOLEAN", XSD_BOOLEAN
, CONST_CS
| CONST_PERSISTENT
);
692 REGISTER_LONG_CONSTANT("XSD_DECIMAL", XSD_DECIMAL
, CONST_CS
| CONST_PERSISTENT
);
693 REGISTER_LONG_CONSTANT("XSD_FLOAT", XSD_FLOAT
, CONST_CS
| CONST_PERSISTENT
);
694 REGISTER_LONG_CONSTANT("XSD_DOUBLE", XSD_DOUBLE
, CONST_CS
| CONST_PERSISTENT
);
695 REGISTER_LONG_CONSTANT("XSD_DURATION", XSD_DURATION
, CONST_CS
| CONST_PERSISTENT
);
696 REGISTER_LONG_CONSTANT("XSD_DATETIME", XSD_DATETIME
, CONST_CS
| CONST_PERSISTENT
);
697 REGISTER_LONG_CONSTANT("XSD_TIME", XSD_TIME
, CONST_CS
| CONST_PERSISTENT
);
698 REGISTER_LONG_CONSTANT("XSD_DATE", XSD_DATE
, CONST_CS
| CONST_PERSISTENT
);
699 REGISTER_LONG_CONSTANT("XSD_GYEARMONTH", XSD_GYEARMONTH
, CONST_CS
| CONST_PERSISTENT
);
700 REGISTER_LONG_CONSTANT("XSD_GYEAR", XSD_GYEAR
, CONST_CS
| CONST_PERSISTENT
);
701 REGISTER_LONG_CONSTANT("XSD_GMONTHDAY", XSD_GMONTHDAY
, CONST_CS
| CONST_PERSISTENT
);
702 REGISTER_LONG_CONSTANT("XSD_GDAY", XSD_GDAY
, CONST_CS
| CONST_PERSISTENT
);
703 REGISTER_LONG_CONSTANT("XSD_GMONTH", XSD_GMONTH
, CONST_CS
| CONST_PERSISTENT
);
704 REGISTER_LONG_CONSTANT("XSD_HEXBINARY", XSD_HEXBINARY
, CONST_CS
| CONST_PERSISTENT
);
705 REGISTER_LONG_CONSTANT("XSD_BASE64BINARY", XSD_BASE64BINARY
, CONST_CS
| CONST_PERSISTENT
);
706 REGISTER_LONG_CONSTANT("XSD_ANYURI", XSD_ANYURI
, CONST_CS
| CONST_PERSISTENT
);
707 REGISTER_LONG_CONSTANT("XSD_QNAME", XSD_QNAME
, CONST_CS
| CONST_PERSISTENT
);
708 REGISTER_LONG_CONSTANT("XSD_NOTATION", XSD_NOTATION
, CONST_CS
| CONST_PERSISTENT
);
709 REGISTER_LONG_CONSTANT("XSD_NORMALIZEDSTRING", XSD_NORMALIZEDSTRING
, CONST_CS
| CONST_PERSISTENT
);
710 REGISTER_LONG_CONSTANT("XSD_TOKEN", XSD_TOKEN
, CONST_CS
| CONST_PERSISTENT
);
711 REGISTER_LONG_CONSTANT("XSD_LANGUAGE", XSD_LANGUAGE
, CONST_CS
| CONST_PERSISTENT
);
712 REGISTER_LONG_CONSTANT("XSD_NMTOKEN", XSD_NMTOKEN
, CONST_CS
| CONST_PERSISTENT
);
713 REGISTER_LONG_CONSTANT("XSD_NAME", XSD_NAME
, CONST_CS
| CONST_PERSISTENT
);
714 REGISTER_LONG_CONSTANT("XSD_NCNAME", XSD_NCNAME
, CONST_CS
| CONST_PERSISTENT
);
715 REGISTER_LONG_CONSTANT("XSD_ID", XSD_ID
, CONST_CS
| CONST_PERSISTENT
);
716 REGISTER_LONG_CONSTANT("XSD_IDREF", XSD_IDREF
, CONST_CS
| CONST_PERSISTENT
);
717 REGISTER_LONG_CONSTANT("XSD_IDREFS", XSD_IDREFS
, CONST_CS
| CONST_PERSISTENT
);
718 REGISTER_LONG_CONSTANT("XSD_ENTITY", XSD_ENTITY
, CONST_CS
| CONST_PERSISTENT
);
719 REGISTER_LONG_CONSTANT("XSD_ENTITIES", XSD_ENTITIES
, CONST_CS
| CONST_PERSISTENT
);
720 REGISTER_LONG_CONSTANT("XSD_INTEGER", XSD_INTEGER
, CONST_CS
| CONST_PERSISTENT
);
721 REGISTER_LONG_CONSTANT("XSD_NONPOSITIVEINTEGER", XSD_NONPOSITIVEINTEGER
, CONST_CS
| CONST_PERSISTENT
);
722 REGISTER_LONG_CONSTANT("XSD_NEGATIVEINTEGER", XSD_NEGATIVEINTEGER
, CONST_CS
| CONST_PERSISTENT
);
723 REGISTER_LONG_CONSTANT("XSD_LONG", XSD_LONG
, CONST_CS
| CONST_PERSISTENT
);
724 REGISTER_LONG_CONSTANT("XSD_INT", XSD_INT
, CONST_CS
| CONST_PERSISTENT
);
725 REGISTER_LONG_CONSTANT("XSD_SHORT", XSD_SHORT
, CONST_CS
| CONST_PERSISTENT
);
726 REGISTER_LONG_CONSTANT("XSD_BYTE", XSD_BYTE
, CONST_CS
| CONST_PERSISTENT
);
727 REGISTER_LONG_CONSTANT("XSD_NONNEGATIVEINTEGER", XSD_NONNEGATIVEINTEGER
, CONST_CS
| CONST_PERSISTENT
);
728 REGISTER_LONG_CONSTANT("XSD_UNSIGNEDLONG", XSD_UNSIGNEDLONG
, CONST_CS
| CONST_PERSISTENT
);
729 REGISTER_LONG_CONSTANT("XSD_UNSIGNEDINT", XSD_UNSIGNEDINT
, CONST_CS
| CONST_PERSISTENT
);
730 REGISTER_LONG_CONSTANT("XSD_UNSIGNEDSHORT", XSD_UNSIGNEDSHORT
, CONST_CS
| CONST_PERSISTENT
);
731 REGISTER_LONG_CONSTANT("XSD_UNSIGNEDBYTE", XSD_UNSIGNEDBYTE
, CONST_CS
| CONST_PERSISTENT
);
732 REGISTER_LONG_CONSTANT("XSD_POSITIVEINTEGER", XSD_POSITIVEINTEGER
, CONST_CS
| CONST_PERSISTENT
);
733 REGISTER_LONG_CONSTANT("XSD_NMTOKENS", XSD_NMTOKENS
, CONST_CS
| CONST_PERSISTENT
);
734 REGISTER_LONG_CONSTANT("XSD_ANYTYPE", XSD_ANYTYPE
, CONST_CS
| CONST_PERSISTENT
);
735 REGISTER_LONG_CONSTANT("XSD_ANYXML", XSD_ANYXML
, CONST_CS
| CONST_PERSISTENT
);
737 REGISTER_LONG_CONSTANT("APACHE_MAP", APACHE_MAP
, CONST_CS
| CONST_PERSISTENT
);
739 REGISTER_LONG_CONSTANT("SOAP_ENC_OBJECT", SOAP_ENC_OBJECT
, CONST_CS
| CONST_PERSISTENT
);
740 REGISTER_LONG_CONSTANT("SOAP_ENC_ARRAY", SOAP_ENC_ARRAY
, CONST_CS
| CONST_PERSISTENT
);
742 REGISTER_LONG_CONSTANT("XSD_1999_TIMEINSTANT", XSD_1999_TIMEINSTANT
, CONST_CS
| CONST_PERSISTENT
);
744 REGISTER_STRING_CONSTANT("XSD_NAMESPACE", XSD_NAMESPACE
, CONST_CS
| CONST_PERSISTENT
);
745 REGISTER_STRING_CONSTANT("XSD_1999_NAMESPACE", XSD_1999_NAMESPACE
, CONST_CS
| CONST_PERSISTENT
);
747 REGISTER_LONG_CONSTANT("SOAP_SINGLE_ELEMENT_ARRAYS", SOAP_SINGLE_ELEMENT_ARRAYS
, CONST_CS
| CONST_PERSISTENT
);
748 REGISTER_LONG_CONSTANT("SOAP_WAIT_ONE_WAY_CALLS", SOAP_WAIT_ONE_WAY_CALLS
, CONST_CS
| CONST_PERSISTENT
);
749 REGISTER_LONG_CONSTANT("SOAP_USE_XSI_ARRAY_TYPE", SOAP_USE_XSI_ARRAY_TYPE
, CONST_CS
| CONST_PERSISTENT
);
751 REGISTER_LONG_CONSTANT("WSDL_CACHE_NONE", WSDL_CACHE_NONE
, CONST_CS
| CONST_PERSISTENT
);
752 REGISTER_LONG_CONSTANT("WSDL_CACHE_DISK", WSDL_CACHE_DISK
, CONST_CS
| CONST_PERSISTENT
);
753 REGISTER_LONG_CONSTANT("WSDL_CACHE_MEMORY", WSDL_CACHE_MEMORY
, CONST_CS
| CONST_PERSISTENT
);
754 REGISTER_LONG_CONSTANT("WSDL_CACHE_BOTH", WSDL_CACHE_BOTH
, CONST_CS
| CONST_PERSISTENT
);
756 old_error_handler
= zend_error_cb
;
757 zend_error_cb
= soap_error_handler
;
762 PHP_MINFO_FUNCTION(soap
)
764 php_info_print_table_start();
765 php_info_print_table_row(2, "Soap Client", "enabled");
766 php_info_print_table_row(2, "Soap Server", "enabled");
767 php_info_print_table_end();
768 DISPLAY_INI_ENTRIES();
772 /* {{{ proto object SoapParam::SoapParam ( mixed data, string name)
773 SoapParam constructor */
774 PHP_METHOD(SoapParam
, SoapParam
)
780 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "zs", &data
, &name
, &name_length
) == FAILURE
) {
783 if (name_length
== 0) {
784 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid parameter name");
788 add_property_stringl(this_ptr
, "param_name", name
, name_length
, 1);
789 add_property_zval(this_ptr
, "param_data", data
);
794 /* {{{ proto object SoapHeader::SoapHeader ( string namespace, string name [, mixed data [, bool mustUnderstand [, mixed actor]]])
795 SoapHeader constructor */
796 PHP_METHOD(SoapHeader
, SoapHeader
)
798 zval
*data
= NULL
, *actor
= NULL
;
800 int name_len
, ns_len
;
801 zend_bool must_understand
= 0;
803 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|zbz", &ns
, &ns_len
, &name
, &name_len
, &data
, &must_understand
, &actor
) == FAILURE
) {
807 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid namespace");
811 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid header name");
815 add_property_stringl(this_ptr
, "namespace", ns
, ns_len
, 1);
816 add_property_stringl(this_ptr
, "name", name
, name_len
, 1);
818 add_property_zval(this_ptr
, "data", data
);
820 add_property_bool(this_ptr
, "mustUnderstand", must_understand
);
822 } else if (Z_TYPE_P(actor
) == IS_LONG
&&
823 (Z_LVAL_P(actor
) == SOAP_ACTOR_NEXT
||
824 Z_LVAL_P(actor
) == SOAP_ACTOR_NONE
||
825 Z_LVAL_P(actor
) == SOAP_ACTOR_UNLIMATERECEIVER
)) {
826 add_property_long(this_ptr
, "actor", Z_LVAL_P(actor
));
827 } else if (Z_TYPE_P(actor
) == IS_STRING
&& Z_STRLEN_P(actor
) > 0) {
828 add_property_stringl(this_ptr
, "actor", Z_STRVAL_P(actor
), Z_STRLEN_P(actor
), 1);
830 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid actor");
834 /* {{{ proto object SoapFault::SoapFault ( string faultcode, string faultstring [, string faultactor [, mixed detail [, string faultname [, mixed headerfault]]]])
835 SoapFault constructor */
836 PHP_METHOD(SoapFault
, SoapFault
)
838 char *fault_string
= NULL
, *fault_code
= NULL
, *fault_actor
= NULL
, *name
= NULL
, *fault_code_ns
= NULL
;
839 int fault_string_len
, fault_actor_len
= 0, name_len
= 0, fault_code_len
= 0;
840 zval
*code
= NULL
, *details
= NULL
, *headerfault
= NULL
;
842 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "zs|s!z!s!z",
844 &fault_string
, &fault_string_len
,
845 &fault_actor
, &fault_actor_len
,
846 &details
, &name
, &name_len
, &headerfault
) == FAILURE
) {
850 if (Z_TYPE_P(code
) == IS_NULL
) {
851 } else if (Z_TYPE_P(code
) == IS_STRING
) {
852 fault_code
= Z_STRVAL_P(code
);
853 fault_code_len
= Z_STRLEN_P(code
);
854 } else if (Z_TYPE_P(code
) == IS_ARRAY
&& zend_hash_num_elements(Z_ARRVAL_P(code
)) == 2) {
855 zval
**t_ns
, **t_code
;
857 zend_hash_internal_pointer_reset(Z_ARRVAL_P(code
));
858 zend_hash_get_current_data(Z_ARRVAL_P(code
), (void**)&t_ns
);
859 zend_hash_move_forward(Z_ARRVAL_P(code
));
860 zend_hash_get_current_data(Z_ARRVAL_P(code
), (void**)&t_code
);
861 if (Z_TYPE_PP(t_ns
) == IS_STRING
&& Z_TYPE_PP(t_code
) == IS_STRING
) {
862 fault_code_ns
= Z_STRVAL_PP(t_ns
);
863 fault_code
= Z_STRVAL_PP(t_code
);
864 fault_code_len
= Z_STRLEN_PP(t_code
);
866 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid fault code");
870 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid fault code");
873 if (fault_code
!= NULL
&& fault_code_len
== 0) {
874 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid fault code");
877 if (name
!= NULL
&& name_len
== 0) {
881 set_soap_fault(this_ptr
, fault_code_ns
, fault_code
, fault_string
, fault_actor
, details
, name TSRMLS_CC
);
882 if (headerfault
!= NULL
) {
883 add_property_zval(this_ptr
, "headerfault", headerfault
);
889 /* {{{ proto object SoapFault::SoapFault ( string faultcode, string faultstring [, string faultactor [, mixed detail [, string faultname [, mixed headerfault]]]])
890 SoapFault constructor */
891 PHP_METHOD(SoapFault
, __toString
)
893 zval
*faultcode
, *faultstring
, *file
, *line
, *trace
;
899 if (zend_parse_parameters_none() == FAILURE
) {
903 faultcode
= zend_read_property(soap_fault_class_entry
, this_ptr
, "faultcode", sizeof("faultcode")-1, 1 TSRMLS_CC
);
904 faultstring
= zend_read_property(soap_fault_class_entry
, this_ptr
, "faultstring", sizeof("faultstring")-1, 1 TSRMLS_CC
);
905 file
= zend_read_property(soap_fault_class_entry
, this_ptr
, "file", sizeof("file")-1, 1 TSRMLS_CC
);
906 line
= zend_read_property(soap_fault_class_entry
, this_ptr
, "line", sizeof("line")-1, 1 TSRMLS_CC
);
908 ZVAL_STRINGL(&fname
, "gettraceasstring", sizeof("gettraceasstring")-1, 0);
910 fci
.size
= sizeof(fci
);
911 fci
.function_table
= &Z_OBJCE_P(getThis())->function_table
;
912 fci
.function_name
= &fname
;
913 fci
.symbol_table
= NULL
;
914 fci
.object_ptr
= getThis();
915 fci
.retval_ptr_ptr
= &trace
;
918 fci
.no_separation
= 1;
920 zend_call_function(&fci
, NULL TSRMLS_CC
);
922 len
= spprintf(&str
, 0, "SoapFault exception: [%s] %s in %s:%ld\nStack trace:\n%s",
923 Z_STRVAL_P(faultcode
), Z_STRVAL_P(faultstring
), Z_STRVAL_P(file
), Z_LVAL_P(line
),
924 Z_STRLEN_P(trace
) ? Z_STRVAL_P(trace
) : "#0 {main}\n");
926 zval_ptr_dtor(&trace
);
928 RETURN_STRINGL(str
, len
, 0);
932 /* {{{ proto object SoapVar::SoapVar ( mixed data, int encoding [, string type_name [, string type_namespace [, string node_name [, string node_namespace]]]])
933 SoapVar constructor */
934 PHP_METHOD(SoapVar
, SoapVar
)
937 char *stype
= NULL
, *ns
= NULL
, *name
= NULL
, *namens
= NULL
;
938 int stype_len
= 0, ns_len
= 0, name_len
= 0, namens_len
= 0;
940 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z!z|ssss", &data
, &type
, &stype
, &stype_len
, &ns
, &ns_len
, &name
, &name_len
, &namens
, &namens_len
) == FAILURE
) {
944 if (Z_TYPE_P(type
) == IS_NULL
) {
945 add_property_long(this_ptr
, "enc_type", UNKNOWN_TYPE
);
947 if (zend_hash_index_exists(&SOAP_GLOBAL(defEncIndex
), Z_LVAL_P(type
))) {
948 add_property_long(this_ptr
, "enc_type", Z_LVAL_P(type
));
950 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid type ID");
956 add_property_zval(this_ptr
, "enc_value", data
);
959 if (stype
&& stype_len
> 0) {
960 add_property_stringl(this_ptr
, "enc_stype", stype
, stype_len
, 1);
962 if (ns
&& ns_len
> 0) {
963 add_property_stringl(this_ptr
, "enc_ns", ns
, ns_len
, 1);
965 if (name
&& name_len
> 0) {
966 add_property_stringl(this_ptr
, "enc_name", name
, name_len
, 1);
968 if (namens
&& namens_len
> 0) {
969 add_property_stringl(this_ptr
, "enc_namens", namens
, namens_len
, 1);
975 static HashTable
* soap_create_typemap(sdlPtr sdl
, HashTable
*ht TSRMLS_DC
)
979 HashPosition pos1
, pos2
;
980 HashTable
*typemap
= NULL
;
982 zend_hash_internal_pointer_reset_ex(ht
, &pos1
);
983 while (zend_hash_get_current_data_ex(ht
, (void**)&tmp
, &pos1
) == SUCCESS
) {
984 char *type_name
= NULL
;
985 char *type_ns
= NULL
;
987 zval
*to_zval
= NULL
;
988 encodePtr enc
, new_enc
;
990 if (Z_TYPE_PP(tmp
) != IS_ARRAY
) {
991 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Wrong 'typemap' option");
994 ht2
= Z_ARRVAL_PP(tmp
);
996 zend_hash_internal_pointer_reset_ex(ht2
, &pos2
);
997 while (zend_hash_get_current_data_ex(ht2
, (void**)&tmp
, &pos2
) == SUCCESS
) {
999 unsigned int name_len
;
1002 zend_hash_get_current_key_ex(ht2
, &name
, &name_len
, &index
, 0, &pos2
);
1004 if (name_len
== sizeof("type_name") &&
1005 strncmp(name
, "type_name", sizeof("type_name")-1) == 0) {
1006 if (Z_TYPE_PP(tmp
) == IS_STRING
) {
1007 type_name
= Z_STRVAL_PP(tmp
);
1008 } else if (Z_TYPE_PP(tmp
) != IS_NULL
) {
1010 } else if (name_len
== sizeof("type_ns") &&
1011 strncmp(name
, "type_ns", sizeof("type_ns")-1) == 0) {
1012 if (Z_TYPE_PP(tmp
) == IS_STRING
) {
1013 type_ns
= Z_STRVAL_PP(tmp
);
1014 } else if (Z_TYPE_PP(tmp
) != IS_NULL
) {
1016 } else if (name_len
== sizeof("to_xml") &&
1017 strncmp(name
, "to_xml", sizeof("to_xml")-1) == 0) {
1019 } else if (name_len
== sizeof("from_xml") &&
1020 strncmp(name
, "from_xml", sizeof("from_xml")-1) == 0) {
1024 zend_hash_move_forward_ex(ht2
, &pos2
);
1028 smart_str nscat
= {0};
1031 enc
= get_encoder(sdl
, type_ns
, type_name
);
1033 enc
= get_encoder_ex(sdl
, type_name
, strlen(type_name
));
1036 new_enc
= emalloc(sizeof(encode
));
1037 memset(new_enc
, 0, sizeof(encode
));
1040 new_enc
->details
.type
= enc
->details
.type
;
1041 new_enc
->details
.ns
= estrdup(enc
->details
.ns
);
1042 new_enc
->details
.type_str
= estrdup(enc
->details
.type_str
);
1043 new_enc
->details
.sdl_type
= enc
->details
.sdl_type
;
1045 enc
= get_conversion(UNKNOWN_TYPE
);
1046 new_enc
->details
.type
= enc
->details
.type
;
1048 new_enc
->details
.ns
= estrdup(type_ns
);
1050 new_enc
->details
.type_str
= estrdup(type_name
);
1052 new_enc
->to_xml
= enc
->to_xml
;
1053 new_enc
->to_zval
= enc
->to_zval
;
1054 new_enc
->details
.map
= emalloc(sizeof(soapMapping
));
1055 memset(new_enc
->details
.map
, 0, sizeof(soapMapping
));
1057 zval_add_ref(&to_xml
);
1058 new_enc
->details
.map
->to_xml
= to_xml
;
1059 new_enc
->to_xml
= to_xml_user
;
1060 } else if (enc
->details
.map
&& enc
->details
.map
->to_xml
) {
1061 zval_add_ref(&enc
->details
.map
->to_xml
);
1062 new_enc
->details
.map
->to_xml
= enc
->details
.map
->to_xml
;
1065 zval_add_ref(&to_zval
);
1066 new_enc
->details
.map
->to_zval
= to_zval
;
1067 new_enc
->to_zval
= to_zval_user
;
1068 } else if (enc
->details
.map
&& enc
->details
.map
->to_zval
) {
1069 zval_add_ref(&enc
->details
.map
->to_zval
);
1070 new_enc
->details
.map
->to_zval
= enc
->details
.map
->to_zval
;
1073 typemap
= emalloc(sizeof(HashTable
));
1074 zend_hash_init(typemap
, 0, NULL
, delete_encoder
, 0);
1078 smart_str_appends(&nscat
, type_ns
);
1079 smart_str_appendc(&nscat
, ':');
1081 smart_str_appends(&nscat
, type_name
);
1082 smart_str_0(&nscat
);
1083 zend_hash_update(typemap
, nscat
.c
, nscat
.len
+ 1, &new_enc
, sizeof(encodePtr
), NULL
);
1084 smart_str_free(&nscat
);
1086 zend_hash_move_forward_ex(ht
, &pos1
);
1092 /* {{{ proto object SoapServer::SoapServer ( mixed wsdl [, array options])
1093 SoapServer constructor */
1094 PHP_METHOD(SoapServer
, SoapServer
)
1096 soapServicePtr service
;
1097 zval
*wsdl
= NULL
, *options
= NULL
;
1099 int version
= SOAP_1_1
;
1101 HashTable
*typemap_ht
= NULL
;
1103 SOAP_SERVER_BEGIN_CODE();
1105 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET
, ZEND_NUM_ARGS() TSRMLS_CC
, "z|a", &wsdl
, &options
) == FAILURE
) {
1106 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Invalid parameters");
1109 if (Z_TYPE_P(wsdl
) != IS_STRING
&& Z_TYPE_P(wsdl
) != IS_NULL
) {
1110 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Invalid parameters");
1113 service
= emalloc(sizeof(soapService
));
1114 memset(service
, 0, sizeof(soapService
));
1115 service
->send_errors
= 1;
1117 cache_wsdl
= SOAP_GLOBAL(cache_enabled
) ? SOAP_GLOBAL(cache_mode
) : 0;
1119 if (options
!= NULL
) {
1120 HashTable
*ht
= Z_ARRVAL_P(options
);
1123 if (zend_hash_find(ht
, "soap_version", sizeof("soap_version"), (void**)&tmp
) == SUCCESS
) {
1124 if (Z_TYPE_PP(tmp
) == IS_LONG
&&
1125 (Z_LVAL_PP(tmp
) == SOAP_1_1
|| Z_LVAL_PP(tmp
) == SOAP_1_2
)) {
1126 version
= Z_LVAL_PP(tmp
);
1128 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "'soap_version' option must be SOAP_1_1 or SOAP_1_2");
1132 if (zend_hash_find(ht
, "uri", sizeof("uri"), (void**)&tmp
) == SUCCESS
&&
1133 Z_TYPE_PP(tmp
) == IS_STRING
) {
1134 service
->uri
= estrndup(Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
));
1135 } else if (Z_TYPE_P(wsdl
) == IS_NULL
) {
1136 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "'uri' option is required in nonWSDL mode");
1139 if (zend_hash_find(ht
, "actor", sizeof("actor"), (void**)&tmp
) == SUCCESS
&&
1140 Z_TYPE_PP(tmp
) == IS_STRING
) {
1141 service
->actor
= estrndup(Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
));
1144 if (zend_hash_find(ht
, "encoding", sizeof("encoding"), (void**)&tmp
) == SUCCESS
&&
1145 Z_TYPE_PP(tmp
) == IS_STRING
) {
1146 xmlCharEncodingHandlerPtr encoding
;
1148 encoding
= xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp
));
1149 if (encoding
== NULL
) {
1150 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Invalid 'encoding' option - '%s'", Z_STRVAL_PP(tmp
));
1152 service
->encoding
= encoding
;
1156 if (zend_hash_find(ht
, "classmap", sizeof("classmap"), (void**)&tmp
) == SUCCESS
&&
1157 Z_TYPE_PP(tmp
) == IS_ARRAY
) {
1160 ALLOC_HASHTABLE(service
->class_map
);
1161 zend_hash_init(service
->class_map
, zend_hash_num_elements((*tmp
)->value
.ht
), NULL
, ZVAL_PTR_DTOR
, 0);
1162 zend_hash_copy(service
->class_map
, (*tmp
)->value
.ht
, (copy_ctor_func_t
) zval_add_ref
, (void *) &ztmp
, sizeof(zval
*));
1165 if (zend_hash_find(ht
, "typemap", sizeof("typemap"), (void**)&tmp
) == SUCCESS
&&
1166 Z_TYPE_PP(tmp
) == IS_ARRAY
&&
1167 zend_hash_num_elements(Z_ARRVAL_PP(tmp
)) > 0) {
1168 typemap_ht
= Z_ARRVAL_PP(tmp
);
1171 if (zend_hash_find(ht
, "features", sizeof("features"), (void**)&tmp
) == SUCCESS
&&
1172 Z_TYPE_PP(tmp
) == IS_LONG
) {
1173 service
->features
= Z_LVAL_PP(tmp
);
1176 if (zend_hash_find(ht
, "cache_wsdl", sizeof("cache_wsdl"), (void**)&tmp
) == SUCCESS
&&
1177 Z_TYPE_PP(tmp
) == IS_LONG
) {
1178 cache_wsdl
= Z_LVAL_PP(tmp
);
1181 if (zend_hash_find(ht
, "send_errors", sizeof("send_errors"), (void**)&tmp
) == SUCCESS
&&
1182 (Z_TYPE_PP(tmp
) == IS_BOOL
|| Z_TYPE_PP(tmp
) == IS_LONG
)) {
1183 service
->send_errors
= Z_LVAL_PP(tmp
);
1186 } else if (Z_TYPE_P(wsdl
) == IS_NULL
) {
1187 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "'uri' option is required in nonWSDL mode");
1190 service
->version
= version
;
1191 service
->type
= SOAP_FUNCTIONS
;
1192 service
->soap_functions
.functions_all
= FALSE
;
1193 service
->soap_functions
.ft
= emalloc(sizeof(HashTable
));
1194 zend_hash_init(service
->soap_functions
.ft
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
1196 if (Z_TYPE_P(wsdl
) != IS_NULL
) {
1197 service
->sdl
= get_sdl(this_ptr
, Z_STRVAL_P(wsdl
), cache_wsdl TSRMLS_CC
);
1198 if (service
->uri
== NULL
) {
1199 if (service
->sdl
->target_ns
) {
1200 service
->uri
= estrdup(service
->sdl
->target_ns
);
1203 service
->uri
= estrdup("http://unknown-uri/");
1209 service
->typemap
= soap_create_typemap(service
->sdl
, typemap_ht TSRMLS_CC
);
1212 ret
= zend_list_insert(service
, le_service TSRMLS_CC
);
1213 add_property_resource(this_ptr
, "service", ret
);
1215 SOAP_SERVER_END_CODE();
1220 /* {{{ proto object SoapServer::setPersistence ( int mode )
1221 Sets persistence mode of SoapServer */
1222 PHP_METHOD(SoapServer
, setPersistence
)
1224 soapServicePtr service
;
1227 SOAP_SERVER_BEGIN_CODE();
1229 FETCH_THIS_SERVICE(service
);
1231 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &value
) != FAILURE
) {
1232 if (service
->type
== SOAP_CLASS
) {
1233 if (value
== SOAP_PERSISTENCE_SESSION
||
1234 value
== SOAP_PERSISTENCE_REQUEST
) {
1235 service
->soap_class
.persistance
= value
;
1237 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Tried to set persistence with bogus value (%ld)", value
);
1241 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Tried to set persistence when you are using you SOAP SERVER in function mode, no persistence needed");
1246 SOAP_SERVER_END_CODE();
1251 /* {{{ proto void SoapServer::setClass(string class_name [, mixed args])
1252 Sets class which will handle SOAP requests */
1253 PHP_METHOD(SoapServer
, setClass
)
1255 soapServicePtr service
;
1257 zend_class_entry
**ce
;
1259 int classname_len
, found
, num_args
= 0;
1260 zval
***argv
= NULL
;
1262 SOAP_SERVER_BEGIN_CODE();
1264 FETCH_THIS_SERVICE(service
);
1266 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s*", &classname
, &classname_len
, &argv
, &num_args
) == FAILURE
) {
1270 found
= zend_lookup_class(classname
, classname_len
, &ce TSRMLS_CC
);
1272 if (found
!= FAILURE
) {
1273 service
->type
= SOAP_CLASS
;
1274 service
->soap_class
.ce
= *ce
;
1276 service
->soap_class
.persistance
= SOAP_PERSISTENCE_REQUEST
;
1277 service
->soap_class
.argc
= num_args
;
1278 if (service
->soap_class
.argc
> 0) {
1280 service
->soap_class
.argv
= safe_emalloc(sizeof(zval
), service
->soap_class
.argc
, 0);
1281 for (i
= 0;i
< service
->soap_class
.argc
;i
++) {
1282 service
->soap_class
.argv
[i
] = *(argv
[i
]);
1283 zval_add_ref(&service
->soap_class
.argv
[i
]);
1287 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Tried to set a non existant class (%s)", classname
);
1295 SOAP_SERVER_END_CODE();
1300 /* {{{ proto void SoapServer::setObject(object)
1301 Sets object which will handle SOAP requests */
1302 PHP_METHOD(SoapServer
, setObject
)
1304 soapServicePtr service
;
1307 SOAP_SERVER_BEGIN_CODE();
1309 FETCH_THIS_SERVICE(service
);
1311 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "o", &obj
) == FAILURE
) {
1315 service
->type
= SOAP_OBJECT
;
1317 MAKE_STD_ZVAL(service
->soap_object
);
1318 MAKE_COPY_ZVAL(&obj
, service
->soap_object
);
1320 SOAP_SERVER_END_CODE();
1325 /* {{{ proto array SoapServer::getFunctions(void)
1326 Returns list of defined functions */
1327 PHP_METHOD(SoapServer
, getFunctions
)
1329 soapServicePtr service
;
1330 HashTable
*ft
= NULL
;
1332 SOAP_SERVER_BEGIN_CODE();
1334 if (zend_parse_parameters_none() == FAILURE
) {
1338 FETCH_THIS_SERVICE(service
);
1340 array_init(return_value
);
1341 if (service
->type
== SOAP_OBJECT
) {
1342 ft
= &(Z_OBJCE_P(service
->soap_object
)->function_table
);
1343 } else if (service
->type
== SOAP_CLASS
) {
1344 ft
= &service
->soap_class
.ce
->function_table
;
1345 } else if (service
->soap_functions
.functions_all
== TRUE
) {
1346 ft
= EG(function_table
);
1347 } else if (service
->soap_functions
.ft
!= NULL
) {
1351 zend_hash_internal_pointer_reset_ex(service
->soap_functions
.ft
, &pos
);
1352 while (zend_hash_get_current_data_ex(service
->soap_functions
.ft
, (void **)&name
, &pos
) != FAILURE
) {
1353 add_next_index_string(return_value
, Z_STRVAL_PP(name
), 1);
1354 zend_hash_move_forward_ex(service
->soap_functions
.ft
, &pos
);
1360 zend_hash_internal_pointer_reset_ex(ft
, &pos
);
1361 while (zend_hash_get_current_data_ex(ft
, (void **)&f
, &pos
) != FAILURE
) {
1362 if ((service
->type
!= SOAP_OBJECT
&& service
->type
!= SOAP_CLASS
) || (f
->common
.fn_flags
& ZEND_ACC_PUBLIC
)) {
1363 add_next_index_string(return_value
, f
->common
.function_name
, 1);
1365 zend_hash_move_forward_ex(ft
, &pos
);
1369 SOAP_SERVER_END_CODE();
1374 /* {{{ proto void SoapServer::addFunction(mixed functions)
1375 Adds one or several functions those will handle SOAP requests */
1376 PHP_METHOD(SoapServer
, addFunction
)
1378 soapServicePtr service
;
1379 zval
*function_name
, *function_copy
;
1382 SOAP_SERVER_BEGIN_CODE();
1384 FETCH_THIS_SERVICE(service
);
1386 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &function_name
) == FAILURE
) {
1390 /* TODO: could use zend_is_callable here */
1392 if (function_name
->type
== IS_ARRAY
) {
1393 if (service
->type
== SOAP_FUNCTIONS
) {
1394 zval
**tmp_function
, *function_copy
;
1396 if (service
->soap_functions
.ft
== NULL
) {
1397 service
->soap_functions
.functions_all
= FALSE
;
1398 service
->soap_functions
.ft
= emalloc(sizeof(HashTable
));
1399 zend_hash_init(service
->soap_functions
.ft
, zend_hash_num_elements(Z_ARRVAL_P(function_name
)), NULL
, ZVAL_PTR_DTOR
, 0);
1402 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(function_name
), &pos
);
1403 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(function_name
), (void **)&tmp_function
, &pos
) != FAILURE
) {
1408 if (Z_TYPE_PP(tmp_function
) != IS_STRING
) {
1409 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Tried to add a function that isn't a string");
1413 key_len
= Z_STRLEN_PP(tmp_function
);
1414 key
= emalloc(key_len
+ 1);
1415 zend_str_tolower_copy(key
, Z_STRVAL_PP(tmp_function
), key_len
);
1417 if (zend_hash_find(EG(function_table
), key
, key_len
+1, (void**)&f
) == FAILURE
) {
1418 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Tried to add a non existant function '%s'", Z_STRVAL_PP(tmp_function
));
1422 MAKE_STD_ZVAL(function_copy
);
1423 ZVAL_STRING(function_copy
, f
->common
.function_name
, 1);
1424 zend_hash_update(service
->soap_functions
.ft
, key
, key_len
+1, &function_copy
, sizeof(zval
*), NULL
);
1427 zend_hash_move_forward_ex(Z_ARRVAL_P(function_name
), &pos
);
1430 } else if (function_name
->type
== IS_STRING
) {
1435 key_len
= Z_STRLEN_P(function_name
);
1436 key
= emalloc(key_len
+ 1);
1437 zend_str_tolower_copy(key
, Z_STRVAL_P(function_name
), key_len
);
1439 if (zend_hash_find(EG(function_table
), key
, key_len
+1, (void**)&f
) == FAILURE
) {
1440 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Tried to add a non existant function '%s'", Z_STRVAL_P(function_name
));
1443 if (service
->soap_functions
.ft
== NULL
) {
1444 service
->soap_functions
.functions_all
= FALSE
;
1445 service
->soap_functions
.ft
= emalloc(sizeof(HashTable
));
1446 zend_hash_init(service
->soap_functions
.ft
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
1449 MAKE_STD_ZVAL(function_copy
);
1450 ZVAL_STRING(function_copy
, f
->common
.function_name
, 1);
1451 zend_hash_update(service
->soap_functions
.ft
, key
, key_len
+1, &function_copy
, sizeof(zval
*), NULL
);
1453 } else if (function_name
->type
== IS_LONG
) {
1454 if (Z_LVAL_P(function_name
) == SOAP_FUNCTIONS_ALL
) {
1455 if (service
->soap_functions
.ft
!= NULL
) {
1456 zend_hash_destroy(service
->soap_functions
.ft
);
1457 efree(service
->soap_functions
.ft
);
1458 service
->soap_functions
.ft
= NULL
;
1460 service
->soap_functions
.functions_all
= TRUE
;
1462 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid value passed");
1467 SOAP_SERVER_END_CODE();
1472 /* {{{ proto void SoapServer::handle ( [string soap_request])
1473 Handles a SOAP request */
1474 PHP_METHOD(SoapServer
, handle
)
1476 int soap_version
, old_soap_version
;
1477 sdlPtr old_sdl
= NULL
;
1478 soapServicePtr service
;
1479 xmlDocPtr doc_request
=NULL
, doc_return
;
1480 zval function_name
, **params
, *soap_obj
, *retval
;
1481 char *fn_name
, cont_len
[30];
1482 int num_params
= 0, size
, i
, call_status
= 0;
1484 HashTable
*function_table
;
1485 soapHeader
*soap_headers
= NULL
;
1486 sdlFunctionPtr function
;
1489 xmlCharEncodingHandlerPtr old_encoding
;
1490 HashTable
*old_class_map
, *old_typemap
;
1493 SOAP_SERVER_BEGIN_CODE();
1495 FETCH_THIS_SERVICE(service
);
1496 SOAP_GLOBAL(soap_version
) = service
->version
;
1498 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s", &arg
, &arg_len
) == FAILURE
) {
1502 if (SG(request_info
).request_method
&&
1503 strcmp(SG(request_info
).request_method
, "GET") == 0 &&
1504 SG(request_info
).query_string
&&
1505 stricmp(SG(request_info
).query_string
, "wsdl") == 0) {
1509 char *hdr = emalloc(sizeof("Location: ")+strlen(service->sdl->source));
1510 strcpy(hdr,"Location: ");
1511 strcat(hdr,service->sdl->source);
1512 sapi_add_header(hdr, sizeof("Location: ")+strlen(service->sdl->source)-1, 1);
1515 zval readfile
, readfile_ret
, *param
;
1517 INIT_ZVAL(readfile
);
1518 INIT_ZVAL(readfile_ret
);
1519 MAKE_STD_ZVAL(param
);
1521 sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
1522 ZVAL_STRING(param
, service
->sdl
->source
, 1);
1523 ZVAL_STRING(&readfile
, "readfile", 1);
1524 if (call_user_function(EG(function_table
), NULL
, &readfile
, &readfile_ret
, 1, ¶m TSRMLS_CC
) == FAILURE
) {
1525 soap_server_fault("Server", "Couldn't find WSDL", NULL
, NULL
, NULL TSRMLS_CC
);
1528 zval_ptr_dtor(¶m
);
1529 zval_dtor(&readfile
);
1530 zval_dtor(&readfile_ret
);
1532 SOAP_SERVER_END_CODE();
1535 soap_server_fault("Server", "WSDL generation is not supported yet", NULL
, NULL
, NULL TSRMLS_CC
);
1537 sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8"), 1);
1538 PUTS("<?xml version=\"1.0\" ?>\n<definitions\n");
1539 PUTS(" xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n");
1540 PUTS(" targetNamespace=\"");
1543 PUTS("</definitions>");
1545 SOAP_SERVER_END_CODE();
1550 ALLOC_INIT_ZVAL(retval
);
1552 if (php_output_start_default(TSRMLS_C
) != SUCCESS
) {
1553 php_error_docref(NULL TSRMLS_CC
, E_ERROR
,"ob_start failed");
1556 if (ZEND_NUM_ARGS() == 0) {
1557 if (SG(request_info
).raw_post_data
) {
1558 char *post_data
= SG(request_info
).raw_post_data
;
1559 int post_data_length
= SG(request_info
).raw_post_data_length
;
1560 zval
**server_vars
, **encoding
;
1562 zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC
);
1563 if (zend_hash_find(&EG(symbol_table
), "_SERVER", sizeof("_SERVER"), (void **) &server_vars
) == SUCCESS
&&
1564 Z_TYPE_PP(server_vars
) == IS_ARRAY
&&
1565 zend_hash_find(Z_ARRVAL_PP(server_vars
), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) &encoding
)==SUCCESS
&&
1566 Z_TYPE_PP(encoding
) == IS_STRING
) {
1572 if ((strcmp(Z_STRVAL_PP(encoding
),"gzip") == 0 ||
1573 strcmp(Z_STRVAL_PP(encoding
),"x-gzip") == 0) &&
1574 zend_hash_exists(EG(function_table
), "gzinflate", sizeof("gzinflate"))) {
1575 ZVAL_STRING(&func
, "gzinflate", 0);
1577 ZVAL_STRINGL(params
[0], post_data
+10, post_data_length
-10, 0);
1578 INIT_PZVAL(params
[0]);
1579 } else if (strcmp(Z_STRVAL_PP(encoding
),"deflate") == 0 &&
1580 zend_hash_exists(EG(function_table
), "gzuncompress", sizeof("gzuncompress"))) {
1581 ZVAL_STRING(&func
, "gzuncompress", 0);
1583 ZVAL_STRINGL(params
[0], post_data
, post_data_length
, 0);
1584 INIT_PZVAL(params
[0]);
1586 php_error_docref(NULL TSRMLS_CC
, E_WARNING
,"Request is compressed with unknown compression '%s'",Z_STRVAL_PP(encoding
));
1589 if (call_user_function(CG(function_table
), (zval
**)NULL
, &func
, &retval
, 1, params TSRMLS_CC
) == SUCCESS
&&
1590 Z_TYPE(retval
) == IS_STRING
) {
1591 doc_request
= soap_xmlParseMemory(Z_STRVAL(retval
),Z_STRLEN(retval
));
1594 php_error_docref(NULL TSRMLS_CC
, E_WARNING
,"Can't uncompress compressed request");
1598 doc_request
= soap_xmlParseMemory(post_data
, post_data_length
);
1601 zval_ptr_dtor(&retval
);
1605 doc_request
= soap_xmlParseMemory(arg
,arg_len
);
1608 if (doc_request
== NULL
) {
1609 soap_server_fault("Client", "Bad Request", NULL
, NULL
, NULL TSRMLS_CC
);
1611 if (xmlGetIntSubset(doc_request
) != NULL
) {
1612 xmlNodePtr env
= get_node(doc_request
->children
,"Envelope");
1613 if (env
&& env
->ns
) {
1614 if (strcmp((char*)env
->ns
->href
, SOAP_1_1_ENV_NAMESPACE
) == 0) {
1615 SOAP_GLOBAL(soap_version
) = SOAP_1_1
;
1616 } else if (strcmp((char*)env
->ns
->href
,SOAP_1_2_ENV_NAMESPACE
) == 0) {
1617 SOAP_GLOBAL(soap_version
) = SOAP_1_2
;
1620 xmlFreeDoc(doc_request
);
1621 soap_server_fault("Server", "DTD are not supported by SOAP", NULL
, NULL
, NULL TSRMLS_CC
);
1624 old_sdl
= SOAP_GLOBAL(sdl
);
1625 SOAP_GLOBAL(sdl
) = service
->sdl
;
1626 old_encoding
= SOAP_GLOBAL(encoding
);
1627 SOAP_GLOBAL(encoding
) = service
->encoding
;
1628 old_class_map
= SOAP_GLOBAL(class_map
);
1629 SOAP_GLOBAL(class_map
) = service
->class_map
;
1630 old_typemap
= SOAP_GLOBAL(typemap
);
1631 SOAP_GLOBAL(typemap
) = service
->typemap
;
1632 old_features
= SOAP_GLOBAL(features
);
1633 SOAP_GLOBAL(features
) = service
->features
;
1634 old_soap_version
= SOAP_GLOBAL(soap_version
);
1635 function
= deserialize_function_call(service
->sdl
, doc_request
, service
->actor
, &function_name
, &num_params
, ¶ms
, &soap_version
, &soap_headers TSRMLS_CC
);
1636 xmlFreeDoc(doc_request
);
1638 if (EG(exception
)) {
1639 php_output_discard(TSRMLS_C
);
1640 if (Z_TYPE_P(EG(exception
)) == IS_OBJECT
&&
1641 instanceof_function(Z_OBJCE_P(EG(exception
)), soap_fault_class_entry TSRMLS_CC
)) {
1642 soap_server_fault_ex(function
, EG(exception
), NULL TSRMLS_CC
);
1647 service
->soap_headers_ptr
= &soap_headers
;
1650 if (service
->type
== SOAP_OBJECT
) {
1651 soap_obj
= service
->soap_object
;
1652 function_table
= &((Z_OBJCE_P(soap_obj
))->function_table
);
1653 } else if (service
->type
== SOAP_CLASS
) {
1654 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
1655 /* If persistent then set soap_obj from from the previous created session (if available) */
1656 if (service
->soap_class
.persistance
== SOAP_PERSISTENCE_SESSION
) {
1659 if (PS(session_status
) != php_session_active
&&
1660 PS(session_status
) != php_session_disabled
) {
1661 php_session_start(TSRMLS_C
);
1664 /* Find the soap object and assign */
1665 if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars
)), "_bogus_session_name", sizeof("_bogus_session_name"), (void **) &tmp_soap
) == SUCCESS
&&
1666 Z_TYPE_PP(tmp_soap
) == IS_OBJECT
&&
1667 Z_OBJCE_PP(tmp_soap
) == service
->soap_class
.ce
) {
1668 soap_obj
= *tmp_soap
;
1672 /* If new session or something wierd happned */
1673 if (soap_obj
== NULL
) {
1676 MAKE_STD_ZVAL(tmp_soap
);
1677 object_init_ex(tmp_soap
, service
->soap_class
.ce
);
1679 /* Call constructor */
1680 if (zend_hash_exists(&Z_OBJCE_P(tmp_soap
)->function_table
, ZEND_CONSTRUCTOR_FUNC_NAME
, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME
))) {
1681 zval c_ret
, constructor
;
1684 INIT_ZVAL(constructor
);
1686 ZVAL_STRING(&constructor
, ZEND_CONSTRUCTOR_FUNC_NAME
, 1);
1687 if (call_user_function(NULL
, &tmp_soap
, &constructor
, &c_ret
, service
->soap_class
.argc
, service
->soap_class
.argv TSRMLS_CC
) == FAILURE
) {
1688 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Error calling constructor");
1690 if (EG(exception
)) {
1691 php_output_discard(TSRMLS_C
);
1692 if (Z_TYPE_P(EG(exception
)) == IS_OBJECT
&&
1693 instanceof_function(Z_OBJCE_P(EG(exception
)), soap_fault_class_entry TSRMLS_CC
)) {
1694 soap_server_fault_ex(function
, EG(exception
), NULL TSRMLS_CC
);
1696 zval_dtor(&constructor
);
1698 zval_ptr_dtor(&tmp_soap
);
1701 zval_dtor(&constructor
);
1704 int class_name_len
= strlen(service
->soap_class
.ce
->name
);
1705 char *class_name
= emalloc(class_name_len
+1);
1707 memcpy(class_name
, service
->soap_class
.ce
->name
,class_name_len
+1);
1708 if (zend_hash_exists(&Z_OBJCE_P(tmp_soap
)->function_table
, php_strtolower(class_name
, class_name_len
), class_name_len
+1)) {
1709 zval c_ret
, constructor
;
1712 INIT_ZVAL(constructor
);
1714 ZVAL_STRING(&constructor
, service
->soap_class
.ce
->name
, 1);
1715 if (call_user_function(NULL
, &tmp_soap
, &constructor
, &c_ret
, service
->soap_class
.argc
, service
->soap_class
.argv TSRMLS_CC
) == FAILURE
) {
1716 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Error calling constructor");
1719 if (EG(exception
)) {
1720 php_output_discard(TSRMLS_C
);
1721 if (Z_TYPE_P(EG(exception
)) == IS_OBJECT
&&
1722 instanceof_function(Z_OBJCE_P(EG(exception
)), soap_fault_class_entry TSRMLS_CC
)) {
1723 soap_server_fault_ex(function
, EG(exception
), NULL TSRMLS_CC
);
1725 zval_dtor(&constructor
);
1728 zval_ptr_dtor(&tmp_soap
);
1732 zval_dtor(&constructor
);
1737 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
1738 /* If session then update session hash with new object */
1739 if (service
->soap_class
.persistance
== SOAP_PERSISTENCE_SESSION
) {
1741 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
) {
1742 soap_obj
= *tmp_soap_pp
;
1745 soap_obj
= tmp_soap
;
1748 soap_obj
= tmp_soap
;
1752 function_table
= &((Z_OBJCE_P(soap_obj
))->function_table
);
1754 if (service
->soap_functions
.functions_all
== TRUE
) {
1755 function_table
= EG(function_table
);
1757 function_table
= service
->soap_functions
.ft
;
1763 /* Process soap headers */
1764 if (soap_headers
!= NULL
) {
1765 soapHeader
*header
= soap_headers
;
1766 while (header
!= NULL
) {
1767 soapHeader
*h
= header
;
1769 header
= header
->next
;
1771 if (service
->sdl
&& !h
->function
&& !h
->hdr
) {
1772 if (h
->mustUnderstand
) {
1773 soap_server_fault("MustUnderstand","Header not understood", NULL
, NULL
, NULL TSRMLS_CC
);
1779 fn_name
= estrndup(Z_STRVAL(h
->function_name
),Z_STRLEN(h
->function_name
));
1780 if (zend_hash_exists(function_table
, php_strtolower(fn_name
, Z_STRLEN(h
->function_name
)), Z_STRLEN(h
->function_name
) + 1) ||
1781 ((service
->type
== SOAP_CLASS
|| service
->type
== SOAP_OBJECT
) &&
1782 zend_hash_exists(function_table
, ZEND_CALL_FUNC_NAME
, sizeof(ZEND_CALL_FUNC_NAME
)))) {
1783 if (service
->type
== SOAP_CLASS
|| service
->type
== SOAP_OBJECT
) {
1784 call_status
= call_user_function(NULL
, &soap_obj
, &h
->function_name
, &h
->retval
, h
->num_params
, h
->parameters TSRMLS_CC
);
1786 call_status
= call_user_function(EG(function_table
), NULL
, &h
->function_name
, &h
->retval
, h
->num_params
, h
->parameters TSRMLS_CC
);
1788 if (call_status
!= SUCCESS
) {
1789 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Function '%s' call failed", Z_STRVAL(h
->function_name
));
1792 if (Z_TYPE(h
->retval
) == IS_OBJECT
&&
1793 instanceof_function(Z_OBJCE(h
->retval
), soap_fault_class_entry TSRMLS_CC
)) {
1794 zval
*headerfault
= NULL
, **tmp
;
1796 if (zend_hash_find(Z_OBJPROP(h
->retval
), "headerfault", sizeof("headerfault"), (void**)&tmp
) == SUCCESS
&&
1797 Z_TYPE_PP(tmp
) != IS_NULL
) {
1800 php_output_discard(TSRMLS_C
);
1801 soap_server_fault_ex(function
, &h
->retval
, h TSRMLS_CC
);
1803 if (service
->type
== SOAP_CLASS
&& soap_obj
) {zval_ptr_dtor(&soap_obj
);}
1805 } else if (EG(exception
)) {
1806 php_output_discard(TSRMLS_C
);
1807 if (Z_TYPE_P(EG(exception
)) == IS_OBJECT
&&
1808 instanceof_function(Z_OBJCE_P(EG(exception
)), soap_fault_class_entry TSRMLS_CC
)) {
1809 zval
*headerfault
= NULL
, **tmp
;
1811 if (zend_hash_find(Z_OBJPROP_P(EG(exception
)), "headerfault", sizeof("headerfault"), (void**)&tmp
) == SUCCESS
&&
1812 Z_TYPE_PP(tmp
) != IS_NULL
) {
1815 soap_server_fault_ex(function
, EG(exception
), h TSRMLS_CC
);
1818 if (service
->type
== SOAP_CLASS
&& soap_obj
) {zval_ptr_dtor(&soap_obj
);}
1821 } else if (h
->mustUnderstand
) {
1822 soap_server_fault("MustUnderstand","Header not understood", NULL
, NULL
, NULL TSRMLS_CC
);
1828 fn_name
= estrndup(Z_STRVAL(function_name
),Z_STRLEN(function_name
));
1829 if (zend_hash_exists(function_table
, php_strtolower(fn_name
, Z_STRLEN(function_name
)), Z_STRLEN(function_name
) + 1) ||
1830 ((service
->type
== SOAP_CLASS
|| service
->type
== SOAP_OBJECT
) &&
1831 zend_hash_exists(function_table
, ZEND_CALL_FUNC_NAME
, sizeof(ZEND_CALL_FUNC_NAME
)))) {
1832 if (service
->type
== SOAP_CLASS
|| service
->type
== SOAP_OBJECT
) {
1833 call_status
= call_user_function(NULL
, &soap_obj
, &function_name
, retval
, num_params
, params TSRMLS_CC
);
1834 if (service
->type
== SOAP_CLASS
) {
1835 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
1836 if (service
->soap_class
.persistance
!= SOAP_PERSISTENCE_SESSION
) {
1837 zval_ptr_dtor(&soap_obj
);
1841 zval_ptr_dtor(&soap_obj
);
1846 call_status
= call_user_function(EG(function_table
), NULL
, &function_name
, retval
, num_params
, params TSRMLS_CC
);
1849 php_error(E_ERROR
, "Function '%s' doesn't exist", Z_STRVAL(function_name
));
1853 if (EG(exception
)) {
1854 php_output_discard(TSRMLS_C
);
1855 if (Z_TYPE_P(EG(exception
)) == IS_OBJECT
&&
1856 instanceof_function(Z_OBJCE_P(EG(exception
)), soap_fault_class_entry TSRMLS_CC
)) {
1857 soap_server_fault_ex(function
, EG(exception
), NULL TSRMLS_CC
);
1859 if (service
->type
== SOAP_CLASS
) {
1860 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
1861 if (soap_obj
&& service
->soap_class
.persistance
!= SOAP_PERSISTENCE_SESSION
) {
1865 zval_ptr_dtor(&soap_obj
);
1871 if (call_status
== SUCCESS
) {
1872 char *response_name
;
1874 if (Z_TYPE_P(retval
) == IS_OBJECT
&&
1875 instanceof_function(Z_OBJCE_P(retval
), soap_fault_class_entry TSRMLS_CC
)) {
1876 php_output_discard(TSRMLS_C
);
1877 soap_server_fault_ex(function
, retval
, NULL TSRMLS_CC
);
1881 if (function
&& function
->responseName
) {
1882 response_name
= estrdup(function
->responseName
);
1884 response_name
= emalloc(Z_STRLEN(function_name
) + sizeof("Response"));
1885 memcpy(response_name
,Z_STRVAL(function_name
),Z_STRLEN(function_name
));
1886 memcpy(response_name
+Z_STRLEN(function_name
),"Response",sizeof("Response"));
1888 doc_return
= serialize_response_call(function
, response_name
, service
->uri
, retval
, soap_headers
, soap_version TSRMLS_CC
);
1889 efree(response_name
);
1891 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Function '%s' call failed", Z_STRVAL(function_name
));
1895 if (EG(exception
)) {
1896 php_output_discard(TSRMLS_C
);
1897 if (Z_TYPE_P(EG(exception
)) == IS_OBJECT
&&
1898 instanceof_function(Z_OBJCE_P(EG(exception
)), soap_fault_class_entry TSRMLS_CC
)) {
1899 soap_server_fault_ex(function
, EG(exception
), NULL TSRMLS_CC
);
1901 if (service
->type
== SOAP_CLASS
) {
1902 #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
1903 if (soap_obj
&& service
->soap_class
.persistance
!= SOAP_PERSISTENCE_SESSION
) {
1907 zval_ptr_dtor(&soap_obj
);
1914 php_output_discard(TSRMLS_C
);
1917 /* xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); */
1918 xmlDocDumpMemory(doc_return
, &buf
, &size
);
1921 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Dump memory failed");
1924 if (soap_version
== SOAP_1_2
) {
1925 sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
1927 sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
1930 xmlFreeDoc(doc_return
);
1932 if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
1933 sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
1935 snprintf(cont_len
, sizeof(cont_len
), "Content-Length: %d", size
);
1936 sapi_add_header(cont_len
, strlen(cont_len
), 1);
1938 php_write(buf
, size TSRMLS_CC
);
1941 sapi_add_header("HTTP/1.1 202 Accepted", sizeof("HTTP/1.1 202 Accepted")-1, 1);
1942 sapi_add_header("Content-Length: 0", sizeof("Content-Length: 0")-1, 1);
1946 SOAP_GLOBAL(soap_version
) = old_soap_version
;
1947 SOAP_GLOBAL(encoding
) = old_encoding
;
1948 SOAP_GLOBAL(sdl
) = old_sdl
;
1949 SOAP_GLOBAL(class_map
) = old_class_map
;
1950 SOAP_GLOBAL(typemap
) = old_typemap
;
1951 SOAP_GLOBAL(features
) = old_features
;
1953 /* Free soap headers */
1954 zval_ptr_dtor(&retval
);
1955 while (soap_headers
!= NULL
) {
1956 soapHeader
*h
= soap_headers
;
1959 soap_headers
= soap_headers
->next
;
1960 if (h
->parameters
) {
1963 zval_ptr_dtor(&h
->parameters
[--i
]);
1965 efree(h
->parameters
);
1967 zval_dtor(&h
->function_name
);
1968 zval_dtor(&h
->retval
);
1971 service
->soap_headers_ptr
= NULL
;
1974 if (num_params
> 0) {
1975 for (i
= 0; i
< num_params
;i
++) {
1976 zval_ptr_dtor(¶ms
[i
]);
1980 zval_dtor(&function_name
);
1982 SOAP_SERVER_END_CODE();
1987 /* {{{ proto SoapServer::fault ( staring code, string string [, string actor [, mixed details [, string name]]] )
1988 Issue SoapFault indicating an error */
1989 PHP_METHOD(SoapServer
, fault
)
1991 char *code
, *string
, *actor
=NULL
, *name
=NULL
;
1992 int code_len
, string_len
, actor_len
= 0, name_len
= 0;
1993 zval
* details
= NULL
;
1994 soapServicePtr service
;
1995 xmlCharEncodingHandlerPtr old_encoding
;
1997 SOAP_SERVER_BEGIN_CODE();
1998 FETCH_THIS_SERVICE(service
);
1999 old_encoding
= SOAP_GLOBAL(encoding
);
2000 SOAP_GLOBAL(encoding
) = service
->encoding
;
2002 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|szs",
2003 &code
, &code_len
, &string
, &string_len
, &actor
, &actor_len
, &details
,
2004 &name
, &name_len
) == FAILURE
) {
2008 soap_server_fault(code
, string
, actor
, details
, name TSRMLS_CC
);
2010 SOAP_GLOBAL(encoding
) = old_encoding
;
2011 SOAP_SERVER_END_CODE();
2015 PHP_METHOD(SoapServer
, addSoapHeader
)
2017 soapServicePtr service
;
2021 SOAP_SERVER_BEGIN_CODE();
2023 FETCH_THIS_SERVICE(service
);
2025 if (!service
|| !service
->soap_headers_ptr
) {
2026 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "The SoapServer::addSoapHeader function may be called only during SOAP request processing");
2030 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "O", &fault
, soap_header_class_entry
) == FAILURE
) {
2034 p
= service
->soap_headers_ptr
;
2035 while (*p
!= NULL
) {
2038 *p
= emalloc(sizeof(soapHeader
));
2039 memset(*p
, 0, sizeof(soapHeader
));
2040 ZVAL_NULL(&(*p
)->function_name
);
2041 (*p
)->retval
= *fault
;
2042 zval_copy_ctor(&(*p
)->retval
);
2044 SOAP_SERVER_END_CODE();
2047 static void soap_server_fault_ex(sdlFunctionPtr function
, zval
* fault
, soapHeader
*hdr TSRMLS_DC
)
2053 xmlDocPtr doc_return
;
2055 int use_http_error_status
= 1;
2057 soap_version
= SOAP_GLOBAL(soap_version
);
2059 doc_return
= serialize_response_call(function
, NULL
, NULL
, fault
, hdr
, soap_version TSRMLS_CC
);
2061 xmlDocDumpMemory(doc_return
, &buf
, &size
);
2063 zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC
);
2064 if (PG(http_globals
)[TRACK_VARS_SERVER
] &&
2065 zend_hash_find(PG(http_globals
)[TRACK_VARS_SERVER
]->value
.ht
, "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &agent_name
) == SUCCESS
&&
2066 Z_TYPE_PP(agent_name
) == IS_STRING
) {
2067 if (strncmp(Z_STRVAL_PP(agent_name
), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) {
2068 use_http_error_status
= 0;
2072 Want to return HTTP 500 but apache wants to over write
2073 our fault code with their own handling... Figure this out later
2075 if (use_http_error_status
) {
2076 sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error")-1, 1);
2078 if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
2079 sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
2081 snprintf(cont_len
, sizeof(cont_len
), "Content-Length: %d", size
);
2082 sapi_add_header(cont_len
, strlen(cont_len
), 1);
2084 if (soap_version
== SOAP_1_2
) {
2085 sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
2087 sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
2090 php_write(buf
, size TSRMLS_CC
);
2092 xmlFreeDoc(doc_return
);
2094 zend_clear_exception(TSRMLS_C
);
2097 static void soap_server_fault(char* code
, char* string
, char *actor
, zval
* details
, char* name TSRMLS_DC
)
2103 set_soap_fault(&ret
, NULL
, code
, string
, actor
, details
, name TSRMLS_CC
);
2104 /* TODO: Which function */
2105 soap_server_fault_ex(NULL
, &ret
, NULL TSRMLS_CC
);
2109 static void soap_error_handler(int error_num
, const char *error_filename
, const uint error_lineno
, const char *format
, va_list args
)
2111 zend_bool _old_in_compilation
, _old_in_execution
;
2112 zend_execute_data
*_old_current_execute_data
;
2113 int _old_http_response_code
;
2114 char *_old_http_status_line
;
2117 _old_in_compilation
= CG(in_compilation
);
2118 _old_in_execution
= EG(in_execution
);
2119 _old_current_execute_data
= EG(current_execute_data
);
2120 _old_http_response_code
= SG(sapi_headers
).http_response_code
;
2121 _old_http_status_line
= SG(sapi_headers
).http_status_line
;
2123 if (!SOAP_GLOBAL(use_soap_error_handler
) || !EG(objects_store
).object_buckets
) {
2124 call_old_error_handler(error_num
, error_filename
, error_lineno
, format
, args
);
2128 if (SOAP_GLOBAL(error_object
) &&
2129 Z_TYPE_P(SOAP_GLOBAL(error_object
)) == IS_OBJECT
&&
2130 instanceof_function(Z_OBJCE_P(SOAP_GLOBAL(error_object
)), soap_class_entry TSRMLS_CC
)) {
2132 int use_exceptions
= 0;
2134 if (zend_hash_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object
)), "_exceptions", sizeof("_exceptions"), (void **) &tmp
) != SUCCESS
||
2135 Z_TYPE_PP(tmp
) != IS_BOOL
|| Z_LVAL_PP(tmp
) != 0) {
2139 if ((error_num
== E_USER_ERROR
||
2140 error_num
== E_COMPILE_ERROR
||
2141 error_num
== E_CORE_ERROR
||
2142 error_num
== E_ERROR
||
2143 error_num
== E_PARSE
) &&
2145 zval
*fault
, *exception
;
2146 char* code
= SOAP_GLOBAL(error_code
);
2149 zval outbuf
, outbuflen
;
2153 zend_object_store_bucket
*old_objects
;
2154 int old
= PG(display_errors
);
2157 INIT_ZVAL(outbuflen
);
2159 va_copy(argcopy
, args
);
2160 buffer_len
= vslprintf(buffer
, sizeof(buffer
)-1, format
, argcopy
);
2163 buffer_len
= vslprintf(buffer
, sizeof(buffer
)-1, format
, args
);
2165 buffer
[sizeof(buffer
)-1]=0;
2166 if (buffer_len
> sizeof(buffer
) - 1 || buffer_len
< 0) {
2167 buffer_len
= sizeof(buffer
) - 1;
2173 fault
= add_soap_fault(SOAP_GLOBAL(error_object
), code
, buffer
, NULL
, NULL TSRMLS_CC
);
2174 MAKE_STD_ZVAL(exception
);
2175 MAKE_COPY_ZVAL(&fault
, exception
);
2176 zend_throw_exception_object(exception TSRMLS_CC
);
2178 old_objects
= EG(objects_store
).object_buckets
;
2179 EG(objects_store
).object_buckets
= NULL
;
2180 PG(display_errors
) = 0;
2181 SG(sapi_headers
).http_status_line
= NULL
;
2183 call_old_error_handler(error_num
, error_filename
, error_lineno
, format
, args
);
2185 CG(in_compilation
) = _old_in_compilation
;
2186 EG(in_execution
) = _old_in_execution
;
2187 EG(current_execute_data
) = _old_current_execute_data
;
2188 if (SG(sapi_headers
).http_status_line
) {
2189 efree(SG(sapi_headers
).http_status_line
);
2191 SG(sapi_headers
).http_status_line
= _old_http_status_line
;
2192 SG(sapi_headers
).http_response_code
= _old_http_response_code
;
2194 EG(objects_store
).object_buckets
= old_objects
;
2195 PG(display_errors
) = old
;
2197 } else if (!use_exceptions
||
2198 !SOAP_GLOBAL(error_code
) ||
2199 strcmp(SOAP_GLOBAL(error_code
),"WSDL") != 0) {
2200 /* Ignore libxml warnings during WSDL parsing */
2201 call_old_error_handler(error_num
, error_filename
, error_lineno
, format
, args
);
2204 int old
= PG(display_errors
);
2211 if (error_num
== E_USER_ERROR
||
2212 error_num
== E_COMPILE_ERROR
||
2213 error_num
== E_CORE_ERROR
||
2214 error_num
== E_ERROR
||
2215 error_num
== E_PARSE
) {
2217 char* code
= SOAP_GLOBAL(error_code
);
2219 zval
*outbuf
= NULL
;
2221 soapServicePtr service
;
2226 if (SOAP_GLOBAL(error_object
) &&
2227 Z_TYPE_P(SOAP_GLOBAL(error_object
)) == IS_OBJECT
&&
2228 instanceof_function(Z_OBJCE_P(SOAP_GLOBAL(error_object
)), soap_server_class_entry TSRMLS_CC
) &&
2229 zend_hash_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object
)), "service", sizeof("service"), (void **)&tmp
) != FAILURE
&&
2230 (service
= (soapServicePtr
)zend_fetch_resource(tmp TSRMLS_CC
, -1, "service", NULL
, 1, le_service
)) &&
2231 !service
->send_errors
) {
2232 strcpy(buffer
, "Internal Error");
2237 INIT_ZVAL(outbuflen
);
2240 va_copy(argcopy
, args
);
2241 buffer_len
= vslprintf(buffer
, sizeof(buffer
)-1, format
, argcopy
);
2244 buffer_len
= vslprintf(buffer
, sizeof(buffer
)-1, format
, args
);
2246 buffer
[sizeof(buffer
)-1]=0;
2247 if (buffer_len
> sizeof(buffer
) - 1 || buffer_len
< 0) {
2248 buffer_len
= sizeof(buffer
) - 1;
2251 /* Get output buffer and send as fault detials */
2252 if (php_output_get_length(&outbuflen TSRMLS_CC
) != FAILURE
&& Z_LVAL(outbuflen
) != 0) {
2253 ALLOC_INIT_ZVAL(outbuf
);
2254 php_output_get_contents(outbuf TSRMLS_CC
);
2256 php_output_discard(TSRMLS_C
);
2259 INIT_ZVAL(fault_obj
);
2260 set_soap_fault(&fault_obj
, NULL
, code
, buffer
, NULL
, outbuf
, NULL TSRMLS_CC
);
2264 PG(display_errors
) = 0;
2265 SG(sapi_headers
).http_status_line
= NULL
;
2267 call_old_error_handler(error_num
, error_filename
, error_lineno
, format
, args
);
2269 CG(in_compilation
) = _old_in_compilation
;
2270 EG(in_execution
) = _old_in_execution
;
2271 EG(current_execute_data
) = _old_current_execute_data
;
2272 if (SG(sapi_headers
).http_status_line
) {
2273 efree(SG(sapi_headers
).http_status_line
);
2275 SG(sapi_headers
).http_status_line
= _old_http_status_line
;
2276 SG(sapi_headers
).http_response_code
= _old_http_response_code
;
2278 PG(display_errors
) = old
;
2281 soap_server_fault_ex(NULL
, &fault_obj
, NULL TSRMLS_CC
);
2287 PHP_FUNCTION(use_soap_error_handler
)
2289 zend_bool handler
= 1;
2291 ZVAL_BOOL(return_value
, SOAP_GLOBAL(use_soap_error_handler
));
2292 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|b", &handler
) == SUCCESS
) {
2293 SOAP_GLOBAL(use_soap_error_handler
) = handler
;
2297 PHP_FUNCTION(is_soap_fault
)
2301 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &fault
) == SUCCESS
&&
2302 Z_TYPE_P(fault
) == IS_OBJECT
&&
2303 instanceof_function(Z_OBJCE_P(fault
), soap_fault_class_entry TSRMLS_CC
)) {
2309 /* SoapClient functions */
2311 /* {{{ proto object SoapClient::SoapClient ( mixed wsdl [, array options])
2312 SoapClient constructor */
2313 PHP_METHOD(SoapClient
, SoapClient
)
2316 zval
*wsdl
, *options
= NULL
;
2317 int soap_version
= SOAP_1_1
;
2318 php_stream_context
*context
= NULL
;
2321 HashTable
*typemap_ht
= NULL
;
2323 SOAP_CLIENT_BEGIN_CODE();
2325 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET
, ZEND_NUM_ARGS() TSRMLS_CC
, "z|a", &wsdl
, &options
) == FAILURE
) {
2326 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Invalid parameters");
2329 if (Z_TYPE_P(wsdl
) != IS_STRING
&& Z_TYPE_P(wsdl
) != IS_NULL
) {
2330 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "$wsdl must be string or null");
2333 cache_wsdl
= SOAP_GLOBAL(cache_enabled
) ? SOAP_GLOBAL(cache_mode
) : 0;
2335 if (options
!= NULL
) {
2336 HashTable
*ht
= Z_ARRVAL_P(options
);
2339 if (Z_TYPE_P(wsdl
) == IS_NULL
) {
2340 /* Fetching non-WSDL mode options */
2341 if (zend_hash_find(ht
, "uri", sizeof("uri"), (void**)&tmp
) == SUCCESS
&&
2342 Z_TYPE_PP(tmp
) == IS_STRING
) {
2343 add_property_stringl(this_ptr
, "uri", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2345 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "'uri' option is required in nonWSDL mode");
2348 if (zend_hash_find(ht
, "style", sizeof("style"), (void**)&tmp
) == SUCCESS
&&
2349 Z_TYPE_PP(tmp
) == IS_LONG
&&
2350 (Z_LVAL_PP(tmp
) == SOAP_RPC
|| Z_LVAL_PP(tmp
) == SOAP_DOCUMENT
)) {
2351 add_property_long(this_ptr
, "style", Z_LVAL_PP(tmp
));
2354 if (zend_hash_find(ht
, "use", sizeof("use"), (void**)&tmp
) == SUCCESS
&&
2355 Z_TYPE_PP(tmp
) == IS_LONG
&&
2356 (Z_LVAL_PP(tmp
) == SOAP_LITERAL
|| Z_LVAL_PP(tmp
) == SOAP_ENCODED
)) {
2357 add_property_long(this_ptr
, "use", Z_LVAL_PP(tmp
));
2361 if (zend_hash_find(ht
, "stream_context", sizeof("stream_context"), (void**)&tmp
) == SUCCESS
&&
2362 Z_TYPE_PP(tmp
) == IS_RESOURCE
) {
2363 context
= php_stream_context_from_zval(*tmp
, 1);
2364 zend_list_addref(context
->rsrc_id
);
2367 if (zend_hash_find(ht
, "location", sizeof("location"), (void**)&tmp
) == SUCCESS
&&
2368 Z_TYPE_PP(tmp
) == IS_STRING
) {
2369 add_property_stringl(this_ptr
, "location", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2370 } else if (Z_TYPE_P(wsdl
) == IS_NULL
) {
2371 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "'location' option is required in nonWSDL mode");
2374 if (zend_hash_find(ht
, "soap_version", sizeof("soap_version"), (void**)&tmp
) == SUCCESS
) {
2375 if (Z_TYPE_PP(tmp
) == IS_LONG
||
2376 (Z_LVAL_PP(tmp
) == SOAP_1_1
&& Z_LVAL_PP(tmp
) == SOAP_1_2
)) {
2377 soap_version
= Z_LVAL_PP(tmp
);
2380 if (zend_hash_find(ht
, "login", sizeof("login"), (void**)&tmp
) == SUCCESS
&&
2381 Z_TYPE_PP(tmp
) == IS_STRING
) {
2382 add_property_stringl(this_ptr
, "_login", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2383 if (zend_hash_find(ht
, "password", sizeof("password"), (void**)&tmp
) == SUCCESS
&&
2384 Z_TYPE_PP(tmp
) == IS_STRING
) {
2385 add_property_stringl(this_ptr
, "_password", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2387 if (zend_hash_find(ht
, "authentication", sizeof("authentication"), (void**)&tmp
) == SUCCESS
&&
2388 Z_TYPE_PP(tmp
) == IS_LONG
&&
2389 Z_LVAL_PP(tmp
) == SOAP_AUTHENTICATION_DIGEST
) {
2390 add_property_null(this_ptr
, "_digest");
2393 if (zend_hash_find(ht
, "proxy_host", sizeof("proxy_host"), (void**)&tmp
) == SUCCESS
&&
2394 Z_TYPE_PP(tmp
) == IS_STRING
) {
2395 add_property_stringl(this_ptr
, "_proxy_host", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2396 if (zend_hash_find(ht
, "proxy_port", sizeof("proxy_port"), (void**)&tmp
) == SUCCESS
) {
2397 convert_to_long(*tmp
);
2398 add_property_long(this_ptr
, "_proxy_port", Z_LVAL_PP(tmp
));
2400 if (zend_hash_find(ht
, "proxy_login", sizeof("proxy_login"), (void**)&tmp
) == SUCCESS
&&
2401 Z_TYPE_PP(tmp
) == IS_STRING
) {
2402 add_property_stringl(this_ptr
, "_proxy_login", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2403 if (zend_hash_find(ht
, "proxy_password", sizeof("proxy_password"), (void**)&tmp
) == SUCCESS
&&
2404 Z_TYPE_PP(tmp
) == IS_STRING
) {
2405 add_property_stringl(this_ptr
, "_proxy_password", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2409 if (zend_hash_find(ht
, "local_cert", sizeof("local_cert"), (void**)&tmp
) == SUCCESS
&&
2410 Z_TYPE_PP(tmp
) == IS_STRING
) {
2412 context
= php_stream_context_alloc(TSRMLS_C
);
2414 php_stream_context_set_option(context
, "ssl", "local_cert", *tmp
);
2415 if (zend_hash_find(ht
, "passphrase", sizeof("passphrase"), (void**)&tmp
) == SUCCESS
&&
2416 Z_TYPE_PP(tmp
) == IS_STRING
) {
2417 php_stream_context_set_option(context
, "ssl", "passphrase", *tmp
);
2420 if (zend_hash_find(ht
, "trace", sizeof("trace"), (void**)&tmp
) == SUCCESS
&&
2421 (Z_TYPE_PP(tmp
) == IS_BOOL
|| Z_TYPE_PP(tmp
) == IS_LONG
) &&
2422 Z_LVAL_PP(tmp
) == 1) {
2423 add_property_long(this_ptr
, "trace", 1);
2426 if (zend_hash_find(ht
, "exceptions", sizeof("exceptions"), (void**)&tmp
) == SUCCESS
&&
2427 (Z_TYPE_PP(tmp
) == IS_BOOL
|| Z_TYPE_PP(tmp
) == IS_LONG
) &&
2428 Z_LVAL_PP(tmp
) == 0) {
2429 add_property_bool(this_ptr
, "_exceptions", 0);
2432 if (zend_hash_find(ht
, "compression", sizeof("compression"), (void**)&tmp
) == SUCCESS
&&
2433 Z_TYPE_PP(tmp
) == IS_LONG
&&
2434 zend_hash_exists(EG(function_table
), "gzinflate", sizeof("gzinflate")) &&
2435 zend_hash_exists(EG(function_table
), "gzdeflate", sizeof("gzdeflate")) &&
2436 zend_hash_exists(EG(function_table
), "gzuncompress", sizeof("gzuncompress")) &&
2437 zend_hash_exists(EG(function_table
), "gzcompress", sizeof("gzcompress")) &&
2438 zend_hash_exists(EG(function_table
), "gzencode", sizeof("gzencode"))) {
2439 add_property_long(this_ptr
, "compression", Z_LVAL_PP(tmp
));
2441 if (zend_hash_find(ht
, "encoding", sizeof("encoding"), (void**)&tmp
) == SUCCESS
&&
2442 Z_TYPE_PP(tmp
) == IS_STRING
) {
2443 xmlCharEncodingHandlerPtr encoding
;
2445 encoding
= xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp
));
2446 if (encoding
== NULL
) {
2447 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Invalid 'encoding' option - '%s'", Z_STRVAL_PP(tmp
));
2449 xmlCharEncCloseFunc(encoding
);
2450 add_property_stringl(this_ptr
, "_encoding", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2453 if (zend_hash_find(ht
, "classmap", sizeof("classmap"), (void**)&tmp
) == SUCCESS
&&
2454 Z_TYPE_PP(tmp
) == IS_ARRAY
) {
2457 MAKE_STD_ZVAL(class_map
);
2458 MAKE_COPY_ZVAL(tmp
, class_map
);
2459 Z_DELREF_P(class_map
);
2461 add_property_zval(this_ptr
, "_classmap", class_map
);
2464 if (zend_hash_find(ht
, "typemap", sizeof("typemap"), (void**)&tmp
) == SUCCESS
&&
2465 Z_TYPE_PP(tmp
) == IS_ARRAY
&&
2466 zend_hash_num_elements(Z_ARRVAL_PP(tmp
)) > 0) {
2467 typemap_ht
= Z_ARRVAL_PP(tmp
);
2470 if (zend_hash_find(ht
, "features", sizeof("features"), (void**)&tmp
) == SUCCESS
&&
2471 Z_TYPE_PP(tmp
) == IS_LONG
) {
2472 add_property_long(this_ptr
, "_features", Z_LVAL_PP(tmp
));
2475 if (zend_hash_find(ht
, "connection_timeout", sizeof("connection_timeout"), (void**)&tmp
) == SUCCESS
) {
2476 convert_to_long(*tmp
);
2477 if (Z_LVAL_PP(tmp
) > 0) {
2478 add_property_long(this_ptr
, "_connection_timeout", Z_LVAL_PP(tmp
));
2483 add_property_resource(this_ptr
, "_stream_context", context
->rsrc_id
);
2486 if (zend_hash_find(ht
, "cache_wsdl", sizeof("cache_wsdl"), (void**)&tmp
) == SUCCESS
&&
2487 Z_TYPE_PP(tmp
) == IS_LONG
) {
2488 cache_wsdl
= Z_LVAL_PP(tmp
);
2491 if (zend_hash_find(ht
, "user_agent", sizeof("user_agent"), (void**)&tmp
) == SUCCESS
&&
2492 Z_TYPE_PP(tmp
) == IS_STRING
) {
2493 add_property_stringl(this_ptr
, "_user_agent", Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
2496 if (zend_hash_find(ht
, "keep_alive", sizeof("keep_alive"), (void**)&tmp
) == SUCCESS
&&
2497 (Z_TYPE_PP(tmp
) == IS_BOOL
|| Z_TYPE_PP(tmp
) == IS_LONG
) && Z_LVAL_PP(tmp
) == 0) {
2498 add_property_long(this_ptr
, "_keep_alive", 0);
2500 } else if (Z_TYPE_P(wsdl
) == IS_NULL
) {
2501 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "'location' and 'uri' options are required in nonWSDL mode");
2504 add_property_long(this_ptr
, "_soap_version", soap_version
);
2506 if (Z_TYPE_P(wsdl
) != IS_NULL
) {
2507 int old_soap_version
, ret
;
2509 old_soap_version
= SOAP_GLOBAL(soap_version
);
2510 SOAP_GLOBAL(soap_version
) = soap_version
;
2512 sdl
= get_sdl(this_ptr
, Z_STRVAL_P(wsdl
), cache_wsdl TSRMLS_CC
);
2513 ret
= zend_list_insert(sdl
, le_sdl TSRMLS_CC
);
2515 add_property_resource(this_ptr
, "sdl", ret
);
2517 SOAP_GLOBAL(soap_version
) = old_soap_version
;
2521 HashTable
*typemap
= soap_create_typemap(sdl
, typemap_ht TSRMLS_CC
);
2525 ret
= zend_list_insert(typemap
, le_typemap TSRMLS_CC
);
2526 add_property_resource(this_ptr
, "typemap", ret
);
2529 SOAP_CLIENT_END_CODE();
2533 static int do_request(zval
*this_ptr
, xmlDoc
*request
, char *location
, char *action
, int version
, int one_way
, zval
*response TSRMLS_DC
)
2538 zval func
, param0
, param1
, param2
, param3
, param4
;
2543 INIT_ZVAL(*response
);
2545 xmlDocDumpMemory(request
, (xmlChar
**)&buf
, &buf_size
);
2547 add_soap_fault(this_ptr
, "HTTP", "Error build soap request", NULL
, NULL TSRMLS_CC
);
2551 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "trace", sizeof("trace"), (void **) &trace
) == SUCCESS
&&
2552 Z_LVAL_PP(trace
) > 0) {
2553 add_property_stringl(this_ptr
, "__last_request", buf
, buf_size
, 1);
2557 ZVAL_STRINGL(&func
,"__doRequest",sizeof("__doRequest")-1,0);
2559 params
[0] = ¶m0
;
2560 ZVAL_STRINGL(params
[0], buf
, buf_size
, 0);
2562 params
[1] = ¶m1
;
2563 if (location
== NULL
) {
2564 ZVAL_NULL(params
[1]);
2566 ZVAL_STRING(params
[1], location
, 0);
2569 params
[2] = ¶m2
;
2570 if (action
== NULL
) {
2571 ZVAL_NULL(params
[2]);
2573 ZVAL_STRING(params
[2], action
, 0);
2576 params
[3] = ¶m3
;
2577 ZVAL_LONG(params
[3], version
);
2580 params
[4] = ¶m4
;
2581 ZVAL_LONG(params
[4], one_way
);
2583 if (call_user_function(NULL
, &this_ptr
, &func
, response
, 5, params TSRMLS_CC
) != SUCCESS
) {
2584 add_soap_fault(this_ptr
, "Client", "SoapClient::__doRequest() failed", NULL
, NULL TSRMLS_CC
);
2586 } else if (Z_TYPE_P(response
) != IS_STRING
) {
2587 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__soap_fault", sizeof("__soap_fault"), (void **) &fault
) == FAILURE
) {
2588 add_soap_fault(this_ptr
, "Client", "SoapClient::__doRequest() returned non string value", NULL
, NULL TSRMLS_CC
);
2591 } else if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "trace", sizeof("trace"), (void **) &trace
) == SUCCESS
&&
2592 Z_LVAL_PP(trace
) > 0) {
2593 add_property_stringl(this_ptr
, "__last_response", Z_STRVAL_P(response
), Z_STRLEN_P(response
), 1);
2596 if (ret
&& zend_hash_find(Z_OBJPROP_P(this_ptr
), "__soap_fault", sizeof("__soap_fault"), (void **) &fault
) == SUCCESS
) {
2602 static void do_soap_call(zval
* this_ptr
,
2611 HashTable
* soap_headers
,
2612 zval
* output_headers
2618 sdlPtr old_sdl
= NULL
;
2620 xmlDocPtr request
= NULL
;
2624 xmlCharEncodingHandlerPtr old_encoding
;
2625 HashTable
*old_class_map
;
2627 HashTable
*old_typemap
, *typemap
= NULL
;
2629 SOAP_CLIENT_BEGIN_CODE();
2631 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "trace", sizeof("trace"), (void **) &trace
) == SUCCESS
2632 && Z_LVAL_PP(trace
) > 0) {
2633 zend_hash_del(Z_OBJPROP_P(this_ptr
), "__last_request", sizeof("__last_request"));
2634 zend_hash_del(Z_OBJPROP_P(this_ptr
), "__last_response", sizeof("__last_response"));
2636 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "_soap_version", sizeof("_soap_version"), (void **) &tmp
) == SUCCESS
2637 && Z_LVAL_PP(tmp
) == SOAP_1_2
) {
2638 soap_version
= SOAP_1_2
;
2640 soap_version
= SOAP_1_1
;
2643 if (location
== NULL
) {
2644 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "location", sizeof("location"),(void **) &tmp
) == SUCCESS
&&
2645 Z_TYPE_PP(tmp
) == IS_STRING
) {
2646 location
= Z_STRVAL_PP(tmp
);
2650 if (FIND_SDL_PROPERTY(this_ptr
,tmp
) != FAILURE
) {
2651 FETCH_SDL_RES(sdl
,tmp
);
2653 if (FIND_TYPEMAP_PROPERTY(this_ptr
,tmp
) != FAILURE
) {
2654 FETCH_TYPEMAP_RES(typemap
,tmp
);
2657 clear_soap_fault(this_ptr TSRMLS_CC
);
2659 SOAP_GLOBAL(soap_version
) = soap_version
;
2660 old_sdl
= SOAP_GLOBAL(sdl
);
2661 SOAP_GLOBAL(sdl
) = sdl
;
2662 old_encoding
= SOAP_GLOBAL(encoding
);
2663 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "_encoding", sizeof("_encoding"), (void **) &tmp
) == SUCCESS
&&
2664 Z_TYPE_PP(tmp
) == IS_STRING
) {
2665 SOAP_GLOBAL(encoding
) = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp
));
2667 SOAP_GLOBAL(encoding
) = NULL
;
2669 old_class_map
= SOAP_GLOBAL(class_map
);
2670 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "_classmap", sizeof("_classmap"), (void **) &tmp
) == SUCCESS
&&
2671 Z_TYPE_PP(tmp
) == IS_ARRAY
) {
2672 SOAP_GLOBAL(class_map
) = (*tmp
)->value
.ht
;
2674 SOAP_GLOBAL(class_map
) = NULL
;
2676 old_typemap
= SOAP_GLOBAL(typemap
);
2677 SOAP_GLOBAL(typemap
) = typemap
;
2678 old_features
= SOAP_GLOBAL(features
);
2679 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "_features", sizeof("_features"), (void **) &tmp
) == SUCCESS
&&
2680 Z_TYPE_PP(tmp
) == IS_LONG
) {
2681 SOAP_GLOBAL(features
) = Z_LVAL_PP(tmp
);
2683 SOAP_GLOBAL(features
) = 0;
2687 fn
= get_function(sdl
, function
);
2689 sdlBindingPtr binding
= fn
->binding
;
2692 if (fn
->responseName
== NULL
&&
2693 fn
->responseParameters
== NULL
&&
2694 soap_headers
== NULL
) {
2698 if (location
== NULL
) {
2699 location
= binding
->location
;
2701 if (binding
->bindingType
== BINDING_SOAP
) {
2702 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)fn
->bindingAttributes
;
2703 request
= serialize_function_call(this_ptr
, fn
, NULL
, fnb
->input
.ns
, real_args
, arg_count
, soap_version
, soap_headers TSRMLS_CC
);
2704 ret
= do_request(this_ptr
, request
, location
, fnb
->soapAction
, soap_version
, one_way
, &response TSRMLS_CC
);
2706 request
= serialize_function_call(this_ptr
, fn
, NULL
, sdl
->target_ns
, real_args
, arg_count
, soap_version
, soap_headers TSRMLS_CC
);
2707 ret
= do_request(this_ptr
, request
, location
, NULL
, soap_version
, one_way
, &response TSRMLS_CC
);
2710 xmlFreeDoc(request
);
2712 if (ret
&& Z_TYPE(response
) == IS_STRING
) {
2714 ret
= parse_packet_soap(this_ptr
, Z_STRVAL(response
), Z_STRLEN(response
), fn
, NULL
, return_value
, output_headers TSRMLS_CC
);
2718 zval_dtor(&response
);
2721 smart_str error
= {0};
2722 smart_str_appends(&error
,"Function (\"");
2723 smart_str_appends(&error
,function
);
2724 smart_str_appends(&error
,"\") is not a valid method for this service");
2725 smart_str_0(&error
);
2726 add_soap_fault(this_ptr
, "Client", error
.c
, NULL
, NULL TSRMLS_CC
);
2727 smart_str_free(&error
);
2731 smart_str action
= {0};
2733 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "uri", sizeof("uri"), (void *)&uri
) == FAILURE
) {
2734 add_soap_fault(this_ptr
, "Client", "Error finding \"uri\" property", NULL
, NULL TSRMLS_CC
);
2735 } else if (location
== NULL
) {
2736 add_soap_fault(this_ptr
, "Client", "Error could not find \"location\" property", NULL
, NULL TSRMLS_CC
);
2738 if (call_uri
== NULL
) {
2739 call_uri
= Z_STRVAL_PP(uri
);
2741 request
= serialize_function_call(this_ptr
, NULL
, function
, call_uri
, real_args
, arg_count
, soap_version
, soap_headers TSRMLS_CC
);
2743 if (soap_action
== NULL
) {
2744 smart_str_appends(&action
, call_uri
);
2745 smart_str_appendc(&action
, '#');
2746 smart_str_appends(&action
, function
);
2748 smart_str_appends(&action
, soap_action
);
2750 smart_str_0(&action
);
2752 ret
= do_request(this_ptr
, request
, location
, action
.c
, soap_version
, 0, &response TSRMLS_CC
);
2754 smart_str_free(&action
);
2755 xmlFreeDoc(request
);
2757 if (ret
&& Z_TYPE(response
) == IS_STRING
) {
2759 ret
= parse_packet_soap(this_ptr
, Z_STRVAL(response
), Z_STRLEN(response
), NULL
, function
, return_value
, output_headers TSRMLS_CC
);
2763 zval_dtor(&response
);
2769 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__soap_fault", sizeof("__soap_fault"), (void **) &fault
) == SUCCESS
) {
2770 *return_value
= **fault
;
2771 zval_copy_ctor(return_value
);
2773 *return_value
= *add_soap_fault(this_ptr
, "Client", "Unknown Error", NULL
, NULL TSRMLS_CC
);
2774 zval_copy_ctor(return_value
);
2778 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__soap_fault", sizeof("__soap_fault"), (void **) &fault
) == SUCCESS
) {
2779 *return_value
= **fault
;
2780 zval_copy_ctor(return_value
);
2784 if (!EG(exception
) &&
2785 Z_TYPE_P(return_value
) == IS_OBJECT
&&
2786 instanceof_function(Z_OBJCE_P(return_value
), soap_fault_class_entry TSRMLS_CC
) &&
2787 (zend_hash_find(Z_OBJPROP_P(this_ptr
), "_exceptions", sizeof("_exceptions"), (void **) &tmp
) != SUCCESS
||
2788 Z_TYPE_PP(tmp
) != IS_BOOL
|| Z_LVAL_PP(tmp
) != 0)) {
2791 MAKE_STD_ZVAL(exception
);
2792 MAKE_COPY_ZVAL(&return_value
, exception
);
2793 zend_throw_exception_object(exception TSRMLS_CC
);
2796 if (SOAP_GLOBAL(encoding
) != NULL
) {
2797 xmlCharEncCloseFunc(SOAP_GLOBAL(encoding
));
2799 SOAP_GLOBAL(features
) = old_features
;
2800 SOAP_GLOBAL(typemap
) = old_typemap
;
2801 SOAP_GLOBAL(class_map
) = old_class_map
;
2802 SOAP_GLOBAL(encoding
) = old_encoding
;
2803 SOAP_GLOBAL(sdl
) = old_sdl
;
2804 SOAP_CLIENT_END_CODE();
2807 static void verify_soap_headers_array(HashTable
*ht TSRMLS_DC
)
2811 zend_hash_internal_pointer_reset(ht
);
2812 while (zend_hash_get_current_data(ht
, (void**)&tmp
) == SUCCESS
) {
2813 if (Z_TYPE_PP(tmp
) != IS_OBJECT
||
2814 !instanceof_function(Z_OBJCE_PP(tmp
), soap_header_class_entry TSRMLS_CC
)) {
2815 php_error_docref(NULL TSRMLS_CC
, E_ERROR
, "Invalid SOAP header");
2817 zend_hash_move_forward(ht
);
2822 /* {{{ proto mixed SoapClient::__call ( string function_name, array arguments [, array options [, array input_headers [, array output_headers]]])
2823 Calls a SOAP function */
2824 PHP_METHOD(SoapClient
, __call
)
2826 char *function
, *location
=NULL
, *soap_action
= NULL
, *uri
= NULL
;
2827 int function_len
, i
= 0;
2828 HashTable
* soap_headers
= NULL
;
2829 zval
*options
= NULL
;
2830 zval
*headers
= NULL
;
2831 zval
*output_headers
= NULL
;
2833 zval
**real_args
= NULL
;
2837 zend_bool free_soap_headers
= 0;
2841 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa|a!zz",
2842 &function
, &function_len
, &args
, &options
, &headers
, &output_headers
) == FAILURE
) {
2847 HashTable
*hto
= Z_ARRVAL_P(options
);
2848 if (zend_hash_find(hto
, "location", sizeof("location"), (void**)&tmp
) == SUCCESS
&&
2849 Z_TYPE_PP(tmp
) == IS_STRING
) {
2850 location
= Z_STRVAL_PP(tmp
);
2853 if (zend_hash_find(hto
, "soapaction", sizeof("soapaction"), (void**)&tmp
) == SUCCESS
&&
2854 Z_TYPE_PP(tmp
) == IS_STRING
) {
2855 soap_action
= Z_STRVAL_PP(tmp
);
2858 if (zend_hash_find(hto
, "uri", sizeof("uri"), (void**)&tmp
) == SUCCESS
&&
2859 Z_TYPE_PP(tmp
) == IS_STRING
) {
2860 uri
= Z_STRVAL_PP(tmp
);
2864 if (headers
== NULL
|| Z_TYPE_P(headers
) == IS_NULL
) {
2865 } else if (Z_TYPE_P(headers
) == IS_ARRAY
) {
2866 soap_headers
= Z_ARRVAL_P(headers
);
2867 verify_soap_headers_array(soap_headers TSRMLS_CC
);
2868 free_soap_headers
= 0;
2869 } else if (Z_TYPE_P(headers
) == IS_OBJECT
&&
2870 instanceof_function(Z_OBJCE_P(headers
), soap_header_class_entry TSRMLS_CC
)) {
2871 soap_headers
= emalloc(sizeof(HashTable
));
2872 zend_hash_init(soap_headers
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
2873 zend_hash_next_index_insert(soap_headers
, &headers
, sizeof(zval
*), NULL
);
2874 Z_ADDREF_P(headers
);
2875 free_soap_headers
= 1;
2877 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid SOAP header");
2881 /* Add default headers */
2882 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__default_headers", sizeof("__default_headers"), (void **) &tmp
)==SUCCESS
) {
2883 HashTable
*default_headers
= Z_ARRVAL_P(*tmp
);
2885 if (!free_soap_headers
) {
2886 HashTable
*t
= emalloc(sizeof(HashTable
));
2887 zend_hash_init(t
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
2888 zend_hash_copy(t
, soap_headers
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
2890 free_soap_headers
= 1;
2892 zend_hash_internal_pointer_reset(default_headers
);
2893 while (zend_hash_get_current_data(default_headers
, (void**)&tmp
) == SUCCESS
) {
2895 zend_hash_next_index_insert(soap_headers
, tmp
, sizeof(zval
*), NULL
);
2896 zend_hash_move_forward(default_headers
);
2899 soap_headers
= Z_ARRVAL_P(*tmp
);
2900 free_soap_headers
= 0;
2904 arg_count
= zend_hash_num_elements(Z_ARRVAL_P(args
));
2906 if (arg_count
> 0) {
2907 real_args
= safe_emalloc(sizeof(zval
*), arg_count
, 0);
2908 for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args
), &pos
);
2909 zend_hash_get_current_data_ex(Z_ARRVAL_P(args
), (void **) ¶m
, &pos
) == SUCCESS
;
2910 zend_hash_move_forward_ex(Z_ARRVAL_P(args
), &pos
)) {
2911 /*zval_add_ref(param);*/
2912 real_args
[i
++] = *param
;
2915 if (output_headers
) {
2916 array_init(output_headers
);
2918 do_soap_call(this_ptr
, function
, function_len
, arg_count
, real_args
, return_value
, location
, soap_action
, uri
, soap_headers
, output_headers TSRMLS_CC
);
2919 if (arg_count
> 0) {
2923 if (soap_headers
&& free_soap_headers
) {
2924 zend_hash_destroy(soap_headers
);
2925 efree(soap_headers
);
2931 /* {{{ proto array SoapClient::__getFunctions ( void )
2932 Returns list of SOAP functions */
2933 PHP_METHOD(SoapClient
, __getFunctions
)
2938 FETCH_THIS_SDL(sdl
);
2940 if (zend_parse_parameters_none() == FAILURE
) {
2945 smart_str buf
= {0};
2946 sdlFunctionPtr
*function
;
2948 array_init(return_value
);
2949 zend_hash_internal_pointer_reset_ex(&sdl
->functions
, &pos
);
2950 while (zend_hash_get_current_data_ex(&sdl
->functions
, (void **)&function
, &pos
) != FAILURE
) {
2951 function_to_string((*function
), &buf
);
2952 add_next_index_stringl(return_value
, buf
.c
, buf
.len
, 1);
2953 smart_str_free(&buf
);
2954 zend_hash_move_forward_ex(&sdl
->functions
, &pos
);
2961 /* {{{ proto array SoapClient::__getTypes ( void )
2962 Returns list of SOAP types */
2963 PHP_METHOD(SoapClient
, __getTypes
)
2968 FETCH_THIS_SDL(sdl
);
2970 if (zend_parse_parameters_none() == FAILURE
) {
2976 smart_str buf
= {0};
2978 array_init(return_value
);
2980 zend_hash_internal_pointer_reset_ex(sdl
->types
, &pos
);
2981 while (zend_hash_get_current_data_ex(sdl
->types
, (void **)&type
, &pos
) != FAILURE
) {
2982 type_to_string((*type
), &buf
, 0);
2983 add_next_index_stringl(return_value
, buf
.c
, buf
.len
, 1);
2984 smart_str_free(&buf
);
2985 zend_hash_move_forward_ex(sdl
->types
, &pos
);
2993 /* {{{ proto string SoapClient::__getLastRequest ( void )
2994 Returns last SOAP request */
2995 PHP_METHOD(SoapClient
, __getLastRequest
)
2999 if (zend_parse_parameters_none() == FAILURE
) {
3003 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__last_request", sizeof("__last_request"), (void **)&tmp
) == SUCCESS
) {
3004 RETURN_STRINGL(Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
3011 /* {{{ proto object SoapClient::__getLastResponse ( void )
3012 Returns last SOAP response */
3013 PHP_METHOD(SoapClient
, __getLastResponse
)
3017 if (zend_parse_parameters_none() == FAILURE
) {
3021 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__last_response", sizeof("__last_response"), (void **)&tmp
) == SUCCESS
) {
3022 RETURN_STRINGL(Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
3029 /* {{{ proto string SoapClient::__getLastRequestHeaders(void)
3030 Returns last SOAP request headers */
3031 PHP_METHOD(SoapClient
, __getLastRequestHeaders
)
3035 if (zend_parse_parameters_none() == FAILURE
) {
3039 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__last_request_headers", sizeof("__last_request_headers"), (void **)&tmp
) == SUCCESS
) {
3040 RETURN_STRINGL(Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
3047 /* {{{ proto string SoapClient::__getLastResponseHeaders(void)
3048 Returns last SOAP response headers */
3049 PHP_METHOD(SoapClient
, __getLastResponseHeaders
)
3053 if (zend_parse_parameters_none() == FAILURE
) {
3057 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__last_response_headers", sizeof("__last_response_headers"), (void **)&tmp
) == SUCCESS
) {
3058 RETURN_STRINGL(Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
3065 /* {{{ proto string SoapClient::__doRequest()
3066 SoapClient::__doRequest() */
3067 PHP_METHOD(SoapClient
, __doRequest
)
3069 char *buf
, *location
, *action
;
3070 int buf_size
, location_size
, action_size
;
3074 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sssl|l",
3076 &location
, &location_size
,
3077 &action
, &action_size
,
3078 &version
, &one_way
) == FAILURE
) {
3081 if (SOAP_GLOBAL(features
) & SOAP_WAIT_ONE_WAY_CALLS
) {
3085 if (make_http_soap_request(this_ptr
, buf
, buf_size
, location
, action
, version
, NULL
, NULL TSRMLS_CC
)) {
3086 RETURN_EMPTY_STRING();
3088 } else if (make_http_soap_request(this_ptr
, buf
, buf_size
, location
, action
, version
,
3089 &Z_STRVAL_P(return_value
), &Z_STRLEN_P(return_value
) TSRMLS_CC
)) {
3090 return_value
->type
= IS_STRING
;
3097 /* {{{ proto void SoapClient::__setCookie(string name [, strung value])
3098 Sets cookie thet will sent with SOAP request.
3099 The call to this function will effect all folowing calls of SOAP methods.
3100 If value is not specified cookie is removed. */
3101 PHP_METHOD(SoapClient
, __setCookie
)
3105 int name_len
, val_len
= 0;
3108 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|s", &name
, &name_len
, &val
, &val_len
) == FAILURE
) {
3113 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "_cookies", sizeof("_cookies"), (void **)&cookies
) == SUCCESS
) {
3114 zend_hash_del(Z_ARRVAL_PP(cookies
), name
, name_len
+1);
3119 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "_cookies", sizeof("_cookies"), (void **)&cookies
) == FAILURE
) {
3122 MAKE_STD_ZVAL(tmp_cookies
);
3123 array_init(tmp_cookies
);
3124 zend_hash_update(Z_OBJPROP_P(this_ptr
), "_cookies", sizeof("_cookies"), &tmp_cookies
, sizeof(zval
*), (void **)&cookies
);
3127 ALLOC_INIT_ZVAL(zcookie
);
3128 array_init(zcookie
);
3129 add_index_stringl(zcookie
, 0, val
, val_len
, 1);
3130 add_assoc_zval_ex(*cookies
, name
, name_len
+1, zcookie
);
3135 /* {{{ proto void SoapClient::__setSoapHeaders(array SoapHeaders)
3136 Sets SOAP headers for subsequent calls (replaces any previous
3138 If no value is specified, all of the headers are removed. */
3139 PHP_METHOD(SoapClient
, __setSoapHeaders
)
3141 zval
*headers
= NULL
;
3143 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|z", &headers
) == FAILURE
) {
3147 if (headers
== NULL
|| Z_TYPE_P(headers
) == IS_NULL
) {
3148 zend_hash_del(Z_OBJPROP_P(this_ptr
), "__default_headers", sizeof("__default_headers"));
3149 } else if (Z_TYPE_P(headers
) == IS_ARRAY
) {
3150 zval
*default_headers
;
3152 verify_soap_headers_array(Z_ARRVAL_P(headers
) TSRMLS_CC
);
3153 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "__default_headers", sizeof("__default_headers"), (void **) &default_headers
)==FAILURE
) {
3154 add_property_zval(this_ptr
, "__default_headers", headers
);
3156 } else if (Z_TYPE_P(headers
) == IS_OBJECT
&&
3157 instanceof_function(Z_OBJCE_P(headers
), soap_header_class_entry TSRMLS_CC
)) {
3158 zval
*default_headers
;
3159 ALLOC_INIT_ZVAL(default_headers
);
3160 array_init(default_headers
);
3161 Z_ADDREF_P(headers
);
3162 add_next_index_zval(default_headers
, headers
);
3163 Z_DELREF_P(default_headers
);
3164 add_property_zval(this_ptr
, "__default_headers", default_headers
);
3166 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Invalid SOAP header");
3174 /* {{{ proto string SoapClient::__setLocation([string new_location])
3175 Sets the location option (the endpoint URL that will be touched by the
3176 following SOAP requests).
3177 If new_location is not specified or null then SoapClient will use endpoint
3179 The function returns old value of location options. */
3180 PHP_METHOD(SoapClient
, __setLocation
)
3182 char *location
= NULL
;
3183 int location_len
= 0;
3186 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s", &location
, &location_len
) == FAILURE
) {
3190 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "location", sizeof("location"),(void **) &tmp
) == SUCCESS
&& Z_TYPE_PP(tmp
) == IS_STRING
) {
3191 RETVAL_STRINGL(Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), 1);
3196 if (location
&& location_len
) {
3197 add_property_stringl(this_ptr
, "location", location
, location_len
, 1);
3199 zend_hash_del(Z_OBJPROP_P(this_ptr
), "location", sizeof("location"));
3204 static void clear_soap_fault(zval
*obj TSRMLS_DC
)
3206 if (obj
!= NULL
&& obj
->type
== IS_OBJECT
) {
3207 zend_hash_del(Z_OBJPROP_P(obj
), "__soap_fault", sizeof("__soap_fault"));
3211 zval
* add_soap_fault(zval
*obj
, char *fault_code
, char *fault_string
, char *fault_actor
, zval
*fault_detail TSRMLS_DC
)
3214 ALLOC_INIT_ZVAL(fault
);
3215 set_soap_fault(fault
, NULL
, fault_code
, fault_string
, fault_actor
, fault_detail
, NULL TSRMLS_CC
);
3218 add_property_zval(obj
, "__soap_fault", fault
);
3222 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
)
3224 if (Z_TYPE_P(obj
) != IS_OBJECT
) {
3225 object_init_ex(obj
, soap_fault_class_entry
);
3228 add_property_string(obj
, "faultstring", fault_string
? fault_string
: "", 1);
3229 zend_update_property_string(zend_exception_get_default(TSRMLS_C
), obj
, "message", sizeof("message")-1, (fault_string
? fault_string
: "") TSRMLS_CC
);
3231 if (fault_code
!= NULL
) {
3232 int soap_version
= SOAP_GLOBAL(soap_version
);
3234 if (fault_code_ns
) {
3235 add_property_string(obj
, "faultcode", fault_code
, 1);
3236 add_property_string(obj
, "faultcodens", fault_code_ns
, 1);
3238 if (soap_version
== SOAP_1_1
) {
3239 add_property_string(obj
, "faultcode", fault_code
, 1);
3240 if (strcmp(fault_code
,"Client") == 0 ||
3241 strcmp(fault_code
,"Server") == 0 ||
3242 strcmp(fault_code
,"VersionMismatch") == 0 ||
3243 strcmp(fault_code
,"MustUnderstand") == 0) {
3244 add_property_string(obj
, "faultcodens", SOAP_1_1_ENV_NAMESPACE
, 1);
3246 } else if (soap_version
== SOAP_1_2
) {
3247 if (strcmp(fault_code
,"Client") == 0) {
3248 add_property_string(obj
, "faultcode", "Sender", 1);
3249 add_property_string(obj
, "faultcodens", SOAP_1_2_ENV_NAMESPACE
, 1);
3250 } else if (strcmp(fault_code
,"Server") == 0) {
3251 add_property_string(obj
, "faultcode", "Receiver", 1);
3252 add_property_string(obj
, "faultcodens", SOAP_1_2_ENV_NAMESPACE
, 1);
3253 } else if (strcmp(fault_code
,"VersionMismatch") == 0 ||
3254 strcmp(fault_code
,"MustUnderstand") == 0 ||
3255 strcmp(fault_code
,"DataEncodingUnknown") == 0) {
3256 add_property_string(obj
, "faultcode", fault_code
, 1);
3257 add_property_string(obj
, "faultcodens", SOAP_1_2_ENV_NAMESPACE
, 1);
3259 add_property_string(obj
, "faultcode", fault_code
, 1);
3264 if (fault_actor
!= NULL
) {
3265 add_property_string(obj
, "faultactor", fault_actor
, 1);
3267 if (fault_detail
!= NULL
) {
3268 add_property_zval(obj
, "detail", fault_detail
);
3271 add_property_string(obj
, "_name", name
, 1);
3275 static void deserialize_parameters(xmlNodePtr params
, sdlFunctionPtr function
, int *num_params
, zval
***parameters TSRMLS_DC
)
3277 int cur_param
= 0,num_of_params
= 0;
3278 zval
**tmp_parameters
= NULL
;
3280 if (function
!= NULL
) {
3285 if (function
->requestParameters
== NULL
) {
3288 num_of_params
= zend_hash_num_elements(function
->requestParameters
);
3289 zend_hash_internal_pointer_reset(function
->requestParameters
);
3290 while (zend_hash_get_current_data(function
->requestParameters
, (void **)¶m
) == SUCCESS
) {
3291 if (get_node(params
, (*param
)->paramName
) != NULL
) {
3294 zend_hash_move_forward(function
->requestParameters
);
3297 tmp_parameters
= safe_emalloc(num_of_params
, sizeof(zval
*), 0);
3298 zend_hash_internal_pointer_reset(function
->requestParameters
);
3299 while (zend_hash_get_current_data(function
->requestParameters
, (void **)¶m
) == SUCCESS
) {
3300 val
= get_node(params
, (*param
)->paramName
);
3302 /* TODO: may be "nil" is not OK? */
3303 MAKE_STD_ZVAL(tmp_parameters
[cur_param
]);
3304 ZVAL_NULL(tmp_parameters
[cur_param
]);
3306 tmp_parameters
[cur_param
] = master_to_zval((*param
)->encode
, val TSRMLS_CC
);
3310 zend_hash_move_forward(function
->requestParameters
);
3312 (*parameters
) = tmp_parameters
;
3313 (*num_params
) = num_of_params
;
3322 while (trav
!= NULL
) {
3323 if (trav
->type
== XML_ELEMENT_NODE
) {
3329 if (num_of_params
== 1 &&
3331 function
->binding
&&
3332 function
->binding
->bindingType
== BINDING_SOAP
&&
3333 ((sdlSoapBindingFunctionPtr
)function
->bindingAttributes
)->style
== SOAP_DOCUMENT
&&
3334 (function
->requestParameters
== NULL
||
3335 zend_hash_num_elements(function
->requestParameters
) == 0) &&
3336 strcmp((char *)params
->name
, function
->functionName
) == 0) {
3338 } else if (num_of_params
> 0) {
3339 tmp_parameters
= safe_emalloc(num_of_params
, sizeof(zval
*), 0);
3342 while (trav
!= 0 && cur_param
< num_of_params
) {
3343 if (trav
->type
== XML_ELEMENT_NODE
) {
3345 sdlParamPtr
*param
= NULL
;
3346 if (function
!= NULL
&&
3347 zend_hash_index_find(function
->requestParameters
, cur_param
, (void **)¶m
) == FAILURE
) {
3349 soap_server_fault("Client", "Error cannot find parameter", NULL
, NULL
, NULL TSRMLS_CC
);
3351 if (param
== NULL
) {
3354 enc
= (*param
)->encode
;
3356 tmp_parameters
[cur_param
] = master_to_zval(enc
, trav TSRMLS_CC
);
3363 if (num_of_params
> cur_param
) {
3364 soap_server_fault("Client","Missing parameter", NULL
, NULL
, NULL TSRMLS_CC
);
3366 (*parameters
) = tmp_parameters
;
3367 (*num_params
) = num_of_params
;
3370 static sdlFunctionPtr
find_function(sdlPtr sdl
, xmlNodePtr func
, zval
* function_name
)
3372 sdlFunctionPtr function
;
3374 function
= get_function(sdl
, (char*)func
->name
);
3375 if (function
&& function
->binding
&& function
->binding
->bindingType
== BINDING_SOAP
) {
3376 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)function
->bindingAttributes
;
3377 if (fnb
->style
== SOAP_DOCUMENT
) {
3378 if (func
->children
!= NULL
||
3379 (function
->requestParameters
!= NULL
&&
3380 zend_hash_num_elements(function
->requestParameters
) > 0)) {
3385 if (sdl
!= NULL
&& function
== NULL
) {
3386 function
= get_doc_function(sdl
, func
);
3389 INIT_ZVAL(*function_name
);
3390 if (function
!= NULL
) {
3391 ZVAL_STRING(function_name
, (char *)function
->functionName
, 1);
3393 ZVAL_STRING(function_name
, (char *)func
->name
, 1);
3399 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
)
3401 char* envelope_ns
= NULL
;
3402 xmlNodePtr trav
,env
,head
,body
,func
;
3404 sdlFunctionPtr function
;
3408 /* Get <Envelope> element */
3410 trav
= request
->children
;
3411 while (trav
!= NULL
) {
3412 if (trav
->type
== XML_ELEMENT_NODE
) {
3413 if (env
== NULL
&& node_is_equal_ex(trav
,"Envelope",SOAP_1_1_ENV_NAMESPACE
)) {
3415 *version
= SOAP_1_1
;
3416 envelope_ns
= SOAP_1_1_ENV_NAMESPACE
;
3417 SOAP_GLOBAL(soap_version
) = SOAP_1_1
;
3418 } else if (env
== NULL
&& node_is_equal_ex(trav
,"Envelope",SOAP_1_2_ENV_NAMESPACE
)) {
3420 *version
= SOAP_1_2
;
3421 envelope_ns
= SOAP_1_2_ENV_NAMESPACE
;
3422 SOAP_GLOBAL(soap_version
) = SOAP_1_2
;
3424 soap_server_fault("VersionMismatch", "Wrong Version", NULL
, NULL
, NULL TSRMLS_CC
);
3430 soap_server_fault("Client", "looks like we got XML without \"Envelope\" element", NULL
, NULL
, NULL TSRMLS_CC
);
3433 attr
= env
->properties
;
3434 while (attr
!= NULL
) {
3435 if (attr
->ns
== NULL
) {
3436 soap_server_fault("Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL
, NULL
, NULL TSRMLS_CC
);
3437 } else if (attr_is_equal_ex(attr
,"encodingStyle",SOAP_1_2_ENV_NAMESPACE
)) {
3438 if (*version
== SOAP_1_2
) {
3439 soap_server_fault("Client", "encodingStyle cannot be specified on the Envelope", NULL
, NULL
, NULL TSRMLS_CC
);
3440 } else if (strcmp((char*)attr
->children
->content
,SOAP_1_1_ENC_NAMESPACE
) != 0) {
3441 soap_server_fault("Client", "Unknown data encoding style", NULL
, NULL
, NULL TSRMLS_CC
);
3447 /* Get <Header> element */
3449 trav
= env
->children
;
3450 while (trav
!= NULL
&& trav
->type
!= XML_ELEMENT_NODE
) {
3453 if (trav
!= NULL
&& node_is_equal_ex(trav
,"Header",envelope_ns
)) {
3458 /* Get <Body> element */
3460 while (trav
!= NULL
&& trav
->type
!= XML_ELEMENT_NODE
) {
3463 if (trav
!= NULL
&& node_is_equal_ex(trav
,"Body",envelope_ns
)) {
3467 while (trav
!= NULL
&& trav
->type
!= XML_ELEMENT_NODE
) {
3471 soap_server_fault("Client", "Body must be present in a SOAP envelope", NULL
, NULL
, NULL TSRMLS_CC
);
3473 attr
= body
->properties
;
3474 while (attr
!= NULL
) {
3475 if (attr
->ns
== NULL
) {
3476 if (*version
== SOAP_1_2
) {
3477 soap_server_fault("Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL
, NULL
, NULL TSRMLS_CC
);
3479 } else if (attr_is_equal_ex(attr
,"encodingStyle",SOAP_1_2_ENV_NAMESPACE
)) {
3480 if (*version
== SOAP_1_2
) {
3481 soap_server_fault("Client", "encodingStyle cannot be specified on the Body", NULL
, NULL
, NULL TSRMLS_CC
);
3482 } else if (strcmp((char*)attr
->children
->content
,SOAP_1_1_ENC_NAMESPACE
) != 0) {
3483 soap_server_fault("Client", "Unknown data encoding style", NULL
, NULL
, NULL TSRMLS_CC
);
3489 if (trav
!= NULL
&& *version
== SOAP_1_2
) {
3490 soap_server_fault("Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL
, NULL
, NULL TSRMLS_CC
);
3494 trav
= body
->children
;
3495 while (trav
!= NULL
) {
3496 if (trav
->type
== XML_ELEMENT_NODE
) {
3499 soap_server_fault("Client", "looks like we got \"Body\" with several functions call", NULL, NULL, NULL TSRMLS_CC);
3503 break; /* FIXME: the rest of body is ignored */
3508 function
= get_doc_function(sdl
, NULL
);
3509 if (function
!= NULL
) {
3510 INIT_ZVAL(*function_name
);
3511 ZVAL_STRING(function_name
, (char *)function
->functionName
, 1);
3513 soap_server_fault("Client", "looks like we got \"Body\" without function call", NULL
, NULL
, NULL TSRMLS_CC
);
3516 if (*version
== SOAP_1_1
) {
3517 attr
= get_attribute_ex(func
->properties
,"encodingStyle",SOAP_1_1_ENV_NAMESPACE
);
3518 if (attr
&& strcmp((char*)attr
->children
->content
,SOAP_1_1_ENC_NAMESPACE
) != 0) {
3519 soap_server_fault("Client","Unknown Data Encoding Style", NULL
, NULL
, NULL TSRMLS_CC
);
3522 attr
= get_attribute_ex(func
->properties
,"encodingStyle",SOAP_1_2_ENV_NAMESPACE
);
3523 if (attr
&& strcmp((char*)attr
->children
->content
,SOAP_1_2_ENC_NAMESPACE
) != 0) {
3524 soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL
, NULL
, NULL TSRMLS_CC
);
3527 function
= find_function(sdl
, func
, function_name
);
3528 if (sdl
!= NULL
&& function
== NULL
) {
3529 if (*version
== SOAP_1_2
) {
3530 soap_server_fault("rpc:ProcedureNotPresent","Procedure not present", NULL
, NULL
, NULL TSRMLS_CC
);
3532 php_error(E_ERROR
, "Procedure '%s' not present", func
->name
);
3539 soapHeader
*h
, *last
= NULL
;
3541 attr
= head
->properties
;
3542 while (attr
!= NULL
) {
3543 if (attr
->ns
== NULL
) {
3544 soap_server_fault("Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL
, NULL
, NULL TSRMLS_CC
);
3545 } else if (attr_is_equal_ex(attr
,"encodingStyle",SOAP_1_2_ENV_NAMESPACE
)) {
3546 if (*version
== SOAP_1_2
) {
3547 soap_server_fault("Client", "encodingStyle cannot be specified on the Header", NULL
, NULL
, NULL TSRMLS_CC
);
3548 } else if (strcmp((char*)attr
->children
->content
,SOAP_1_1_ENC_NAMESPACE
) != 0) {
3549 soap_server_fault("Client", "Unknown data encoding style", NULL
, NULL
, NULL TSRMLS_CC
);
3554 trav
= head
->children
;
3555 while (trav
!= NULL
) {
3556 if (trav
->type
== XML_ELEMENT_NODE
) {
3557 xmlNodePtr hdr_func
= trav
;
3558 int mustUnderstand
= 0;
3560 if (*version
== SOAP_1_1
) {
3561 attr
= get_attribute_ex(hdr_func
->properties
,"encodingStyle",SOAP_1_1_ENV_NAMESPACE
);
3562 if (attr
&& strcmp((char*)attr
->children
->content
,SOAP_1_1_ENC_NAMESPACE
) != 0) {
3563 soap_server_fault("Client","Unknown Data Encoding Style", NULL
, NULL
, NULL TSRMLS_CC
);
3565 attr
= get_attribute_ex(hdr_func
->properties
,"actor",envelope_ns
);
3567 if (strcmp((char*)attr
->children
->content
,SOAP_1_1_ACTOR_NEXT
) != 0 &&
3568 (actor
== NULL
|| strcmp((char*)attr
->children
->content
,actor
) != 0)) {
3572 } else if (*version
== SOAP_1_2
) {
3573 attr
= get_attribute_ex(hdr_func
->properties
,"encodingStyle",SOAP_1_2_ENV_NAMESPACE
);
3574 if (attr
&& strcmp((char*)attr
->children
->content
,SOAP_1_2_ENC_NAMESPACE
) != 0) {
3575 soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL
, NULL
, NULL TSRMLS_CC
);
3577 attr
= get_attribute_ex(hdr_func
->properties
,"role",envelope_ns
);
3579 if (strcmp((char*)attr
->children
->content
,SOAP_1_2_ACTOR_UNLIMATERECEIVER
) != 0 &&
3580 strcmp((char*)attr
->children
->content
,SOAP_1_2_ACTOR_NEXT
) != 0 &&
3581 (actor
== NULL
|| strcmp((char*)attr
->children
->content
,actor
) != 0)) {
3586 attr
= get_attribute_ex(hdr_func
->properties
,"mustUnderstand",envelope_ns
);
3588 if (strcmp((char*)attr
->children
->content
,"1") == 0 ||
3589 strcmp((char*)attr
->children
->content
,"true") == 0) {
3591 } else if (strcmp((char*)attr
->children
->content
,"0") == 0 ||
3592 strcmp((char*)attr
->children
->content
,"false") == 0) {
3595 soap_server_fault("Client","mustUnderstand value is not boolean", NULL
, NULL
, NULL TSRMLS_CC
);
3598 h
= emalloc(sizeof(soapHeader
));
3599 memset(h
, 0, sizeof(soapHeader
));
3600 h
->mustUnderstand
= mustUnderstand
;
3601 h
->function
= find_function(sdl
, hdr_func
, &h
->function_name
);
3602 if (!h
->function
&& sdl
&& function
&& function
->binding
&& function
->binding
->bindingType
== BINDING_SOAP
) {
3603 sdlSoapBindingFunctionHeaderPtr
*hdr
;
3604 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)function
->bindingAttributes
;
3605 if (fnb
->input
.headers
) {
3606 smart_str key
= {0};
3609 smart_str_appends(&key
, (char*)hdr_func
->ns
->href
);
3610 smart_str_appendc(&key
, ':');
3612 smart_str_appendl(&key
, Z_STRVAL(h
->function_name
), Z_STRLEN(h
->function_name
));
3614 if (zend_hash_find(fnb
->input
.headers
, key
.c
, key
.len
+1, (void**)&hdr
) == SUCCESS
) {
3617 smart_str_free(&key
);
3622 h
->parameters
= emalloc(sizeof(zval
*));
3623 h
->parameters
[0] = master_to_zval(h
->hdr
->encode
, hdr_func TSRMLS_CC
);
3625 if (h
->function
&& h
->function
->binding
&& h
->function
->binding
->bindingType
== BINDING_SOAP
) {
3626 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)h
->function
->bindingAttributes
;
3627 if (fnb
->style
== SOAP_RPC
) {
3628 hdr_func
= hdr_func
->children
;
3631 deserialize_parameters(hdr_func
, h
->function
, &h
->num_params
, &h
->parameters TSRMLS_CC
);
3633 INIT_ZVAL(h
->retval
);
3646 if (function
&& function
->binding
&& function
->binding
->bindingType
== BINDING_SOAP
) {
3647 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)function
->bindingAttributes
;
3648 if (fnb
->style
== SOAP_RPC
) {
3649 func
= func
->children
;
3652 func
= func
->children
;
3654 deserialize_parameters(func
, function
, num_params
, parameters TSRMLS_CC
);
3661 static int serialize_response_call2(xmlNodePtr body
, sdlFunctionPtr function
, char *function_name
, char *uri
, zval
*ret
, int version
, int main TSRMLS_DC
)
3663 xmlNodePtr method
= NULL
, param
;
3664 sdlParamPtr parameter
= NULL
;
3669 if (function
!= NULL
&& function
->binding
->bindingType
== BINDING_SOAP
) {
3670 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)function
->bindingAttributes
;
3673 use
= fnb
->output
.use
;
3674 if (style
== SOAP_RPC
) {
3675 ns
= encode_add_ns(body
, fnb
->output
.ns
);
3676 if (function
->responseName
) {
3677 method
= xmlNewChild(body
, ns
, BAD_CAST(function
->responseName
), NULL
);
3678 } else if (function
->responseParameters
) {
3679 method
= xmlNewChild(body
, ns
, BAD_CAST(function
->functionName
), NULL
);
3683 style
= main
?SOAP_RPC
:SOAP_DOCUMENT
;
3684 use
= main
?SOAP_ENCODED
:SOAP_LITERAL
;
3685 if (style
== SOAP_RPC
) {
3686 ns
= encode_add_ns(body
, uri
);
3687 method
= xmlNewChild(body
, ns
, BAD_CAST(function_name
), NULL
);
3691 if (function
!= NULL
) {
3692 if (function
->responseParameters
) {
3693 param_count
= zend_hash_num_elements(function
->responseParameters
);
3701 if (param_count
== 1) {
3702 parameter
= get_param(function
, NULL
, 0, TRUE
);
3704 if (style
== SOAP_RPC
) {
3705 xmlNode
*rpc_result
;
3706 if (main
&& version
== SOAP_1_2
) {
3707 xmlNs
*rpc_ns
= xmlNewNs(body
, BAD_CAST(RPC_SOAP12_NAMESPACE
), BAD_CAST(RPC_SOAP12_NS_PREFIX
));
3708 rpc_result
= xmlNewChild(method
, rpc_ns
, BAD_CAST("result"), NULL
);
3709 param
= serialize_parameter(parameter
, ret
, 0, "return", use
, method TSRMLS_CC
);
3710 xmlNodeSetContent(rpc_result
,param
->name
);
3712 param
= serialize_parameter(parameter
, ret
, 0, "return", use
, method TSRMLS_CC
);
3715 param
= serialize_parameter(parameter
, ret
, 0, "return", use
, body TSRMLS_CC
);
3716 if (function
&& function
->binding
->bindingType
== BINDING_SOAP
) {
3717 if (parameter
&& parameter
->element
) {
3718 ns
= encode_add_ns(param
, parameter
->element
->namens
);
3719 xmlNodeSetName(param
, BAD_CAST(parameter
->element
->name
));
3720 xmlSetNs(param
, ns
);
3722 } else if (strcmp((char*)param
->name
,"return") == 0) {
3723 ns
= encode_add_ns(param
, uri
);
3724 xmlNodeSetName(param
, BAD_CAST(function_name
));
3725 xmlSetNs(param
, ns
);
3728 } else if (param_count
> 1 && Z_TYPE_P(ret
) == IS_ARRAY
) {
3733 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ret
), &pos
);
3734 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(ret
), (void **)&data
, &pos
) != FAILURE
) {
3735 char *param_name
= NULL
;
3736 unsigned int param_name_len
;
3737 ulong param_index
= i
;
3739 zend_hash_get_current_key_ex(Z_ARRVAL_P(ret
), ¶m_name
, ¶m_name_len
, ¶m_index
, 0, &pos
);
3740 parameter
= get_param(function
, param_name
, param_index
, TRUE
);
3741 if (style
== SOAP_RPC
) {
3742 param
= serialize_parameter(parameter
, *data
, i
, param_name
, use
, method TSRMLS_CC
);
3744 param
= serialize_parameter(parameter
, *data
, i
, param_name
, use
, body TSRMLS_CC
);
3745 if (function
&& function
->binding
->bindingType
== BINDING_SOAP
) {
3746 if (parameter
&& parameter
->element
) {
3747 ns
= encode_add_ns(param
, parameter
->element
->namens
);
3748 xmlNodeSetName(param
, BAD_CAST(parameter
->element
->name
));
3749 xmlSetNs(param
, ns
);
3754 zend_hash_move_forward_ex(Z_ARRVAL_P(ret
), &pos
);
3758 if (use
== SOAP_ENCODED
&& version
== SOAP_1_2
&& method
!= NULL
) {
3759 xmlSetNsProp(method
, body
->ns
, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE
));
3764 static xmlDocPtr
serialize_response_call(sdlFunctionPtr function
, char *function_name
, char *uri
, zval
*ret
, soapHeader
* headers
, int version TSRMLS_DC
)
3767 xmlNodePtr envelope
= NULL
, body
, param
;
3769 int use
= SOAP_LITERAL
;
3770 xmlNodePtr head
= NULL
;
3774 doc
= xmlNewDoc(BAD_CAST("1.0"));
3775 doc
->charset
= XML_CHAR_ENCODING_UTF8
;
3776 doc
->encoding
= xmlCharStrdup("UTF-8");
3778 if (version
== SOAP_1_1
) {
3779 envelope
= xmlNewDocNode(doc
, NULL
, BAD_CAST("Envelope"), NULL
);
3780 ns
= xmlNewNs(envelope
, BAD_CAST(SOAP_1_1_ENV_NAMESPACE
), BAD_CAST(SOAP_1_1_ENV_NS_PREFIX
));
3781 xmlSetNs(envelope
,ns
);
3782 } else if (version
== SOAP_1_2
) {
3783 envelope
= xmlNewDocNode(doc
, NULL
, BAD_CAST("Envelope"), NULL
);
3784 ns
= xmlNewNs(envelope
, BAD_CAST(SOAP_1_2_ENV_NAMESPACE
), BAD_CAST(SOAP_1_2_ENV_NS_PREFIX
));
3785 xmlSetNs(envelope
,ns
);
3787 soap_server_fault("Server", "Unknown SOAP version", NULL
, NULL
, NULL TSRMLS_CC
);
3789 xmlDocSetRootElement(doc
, envelope
);
3791 if (Z_TYPE_P(ret
) == IS_OBJECT
&&
3792 instanceof_function(Z_OBJCE_P(ret
), soap_fault_class_entry TSRMLS_CC
)) {
3796 sdlFaultPtr fault
= NULL
;
3797 char *fault_ns
= NULL
;
3799 prop
= Z_OBJPROP_P(ret
);
3802 zend_hash_find(prop
, "headerfault", sizeof("headerfault"), (void**)&tmp
) == SUCCESS
) {
3803 encodePtr hdr_enc
= NULL
;
3804 int hdr_use
= SOAP_LITERAL
;
3805 zval
*hdr_ret
= *tmp
;
3806 char *hdr_ns
= headers
->hdr
?headers
->hdr
->ns
:NULL
;
3807 char *hdr_name
= Z_STRVAL(headers
->function_name
);
3809 head
= xmlNewChild(envelope
, ns
, BAD_CAST("Header"), NULL
);
3810 if (Z_TYPE_P(hdr_ret
) == IS_OBJECT
&&
3811 instanceof_function(Z_OBJCE_P(hdr_ret
), soap_header_class_entry TSRMLS_CC
)) {
3812 HashTable
* ht
= Z_OBJPROP_P(hdr_ret
);
3813 sdlSoapBindingFunctionHeaderPtr
*hdr
;
3814 smart_str key
= {0};
3816 if (zend_hash_find(ht
, "namespace", sizeof("namespace"), (void**)&tmp
) == SUCCESS
&&
3817 Z_TYPE_PP(tmp
) == IS_STRING
) {
3818 smart_str_appendl(&key
, Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
));
3819 smart_str_appendc(&key
, ':');
3820 hdr_ns
= Z_STRVAL_PP(tmp
);
3822 if (zend_hash_find(ht
, "name", sizeof("name"), (void**)&tmp
) == SUCCESS
&&
3823 Z_TYPE_PP(tmp
) == IS_STRING
) {
3824 smart_str_appendl(&key
, Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
));
3825 hdr_name
= Z_STRVAL_PP(tmp
);
3828 if (headers
->hdr
&& headers
->hdr
->headerfaults
&&
3829 zend_hash_find(headers
->hdr
->headerfaults
, key
.c
, key
.len
+1, (void**)&hdr
) == SUCCESS
) {
3830 hdr_enc
= (*hdr
)->encode
;
3831 hdr_use
= (*hdr
)->use
;
3833 smart_str_free(&key
);
3834 if (zend_hash_find(ht
, "data", sizeof("data"), (void**)&tmp
) == SUCCESS
) {
3841 if (headers
->function
) {
3842 if (serialize_response_call2(head
, headers
->function
, Z_STRVAL(headers
->function_name
), uri
, hdr_ret
, version
, 0 TSRMLS_CC
) == SOAP_ENCODED
) {
3846 xmlNodePtr xmlHdr
= master_to_xml(hdr_enc
, hdr_ret
, hdr_use
, head TSRMLS_CC
);
3848 xmlNodeSetName(xmlHdr
, BAD_CAST(hdr_name
));
3851 xmlNsPtr nsptr
= encode_add_ns(xmlHdr
, hdr_ns
);
3852 xmlSetNs(xmlHdr
, nsptr
);
3857 body
= xmlNewChild(envelope
, ns
, BAD_CAST("Body"), NULL
);
3858 param
= xmlNewChild(body
, ns
, BAD_CAST("Fault"), NULL
);
3860 if (zend_hash_find(prop
, "faultcodens", sizeof("faultcodens"), (void**)&tmp
) == SUCCESS
&& Z_TYPE_PP(tmp
) == IS_STRING
) {
3861 fault_ns
= Z_STRVAL_PP(tmp
);
3864 if (zend_hash_find(prop
, "_name", sizeof("_name"), (void**)&tmp
) == SUCCESS
&& Z_TYPE_PP(tmp
) == IS_STRING
) {
3865 sdlFaultPtr
*tmp_fault
;
3866 if (function
&& function
->faults
&&
3867 zend_hash_find(function
->faults
, Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
)+1, (void**)&tmp_fault
) == SUCCESS
) {
3869 if (function
->binding
&&
3870 function
->binding
->bindingType
== BINDING_SOAP
&&
3871 fault
->bindingAttributes
) {
3872 sdlSoapBindingFunctionFaultPtr fb
= (sdlSoapBindingFunctionFaultPtr
)fault
->bindingAttributes
;
3874 if (fault_ns
== NULL
) {
3879 } else if (function
&& function
->faults
&&
3880 zend_hash_num_elements(function
->faults
) == 1) {
3882 zend_hash_internal_pointer_reset(function
->faults
);
3883 zend_hash_get_current_data(function
->faults
, (void**)&fault
);
3884 fault
= *(sdlFaultPtr
*)fault
;
3885 if (function
->binding
&&
3886 function
->binding
->bindingType
== BINDING_SOAP
&&
3887 fault
->bindingAttributes
) {
3888 sdlSoapBindingFunctionFaultPtr fb
= (sdlSoapBindingFunctionFaultPtr
)fault
->bindingAttributes
;
3890 if (fault_ns
== NULL
) {
3896 if (fault_ns
== NULL
&&
3899 zend_hash_num_elements(fault
->details
) == 1) {
3902 zend_hash_internal_pointer_reset(fault
->details
);
3903 zend_hash_get_current_data(fault
->details
, (void**)&sparam
);
3904 sparam
= *(sdlParamPtr
*)sparam
;
3905 if (sparam
->element
) {
3906 fault_ns
= sparam
->element
->namens
;
3910 if (version
== SOAP_1_1
) {
3911 if (zend_hash_find(prop
, "faultcode", sizeof("faultcode"), (void**)&tmp
) == SUCCESS
) {
3913 xmlNodePtr node
= xmlNewNode(NULL
, BAD_CAST("faultcode"));
3914 char *str
= php_escape_html_entities((unsigned char*)Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), &new_len
, 0, 0, NULL TSRMLS_CC
);
3915 xmlAddChild(param
, node
);
3917 xmlNsPtr nsptr
= encode_add_ns(node
, fault_ns
);
3918 xmlChar
*code
= xmlBuildQName(BAD_CAST(str
), nsptr
->prefix
, NULL
, 0);
3919 xmlNodeSetContent(node
, code
);
3922 xmlNodeSetContentLen(node
, BAD_CAST(str
), new_len
);
3926 if (zend_hash_find(prop
, "faultstring", sizeof("faultstring"), (void**)&tmp
) == SUCCESS
) {
3927 xmlNodePtr node
= master_to_xml(get_conversion(IS_STRING
), *tmp
, SOAP_LITERAL
, param TSRMLS_CC
);
3928 xmlNodeSetName(node
, BAD_CAST("faultstring"));
3930 if (zend_hash_find(prop
, "faultactor", sizeof("faultactor"), (void**)&tmp
) == SUCCESS
) {
3931 xmlNodePtr node
= master_to_xml(get_conversion(IS_STRING
), *tmp
, SOAP_LITERAL
, param TSRMLS_CC
);
3932 xmlNodeSetName(node
, BAD_CAST("faultactor"));
3934 detail_name
= "detail";
3936 if (zend_hash_find(prop
, "faultcode", sizeof("faultcode"), (void**)&tmp
) == SUCCESS
) {
3938 xmlNodePtr node
= xmlNewChild(param
, ns
, BAD_CAST("Code"), NULL
);
3939 char *str
= php_escape_html_entities((unsigned char*)Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
), &new_len
, 0, 0, NULL TSRMLS_CC
);
3940 node
= xmlNewChild(node
, ns
, BAD_CAST("Value"), NULL
);
3942 xmlNsPtr nsptr
= encode_add_ns(node
, fault_ns
);
3943 xmlChar
*code
= xmlBuildQName(BAD_CAST(str
), nsptr
->prefix
, NULL
, 0);
3944 xmlNodeSetContent(node
, code
);
3947 xmlNodeSetContentLen(node
, BAD_CAST(str
), new_len
);
3951 if (zend_hash_find(prop
, "faultstring", sizeof("faultstring"), (void**)&tmp
) == SUCCESS
) {
3952 xmlNodePtr node
= xmlNewChild(param
, ns
, BAD_CAST("Reason"), NULL
);
3953 node
= master_to_xml(get_conversion(IS_STRING
), *tmp
, SOAP_LITERAL
, node TSRMLS_CC
);
3954 xmlNodeSetName(node
, BAD_CAST("Text"));
3957 detail_name
= SOAP_1_2_ENV_NS_PREFIX
":Detail";
3959 if (fault
&& fault
->details
&& zend_hash_num_elements(fault
->details
) == 1) {
3961 zval
*detail
= NULL
;
3965 if (zend_hash_find(prop
, "detail", sizeof("detail"), (void**)&tmp
) == SUCCESS
&&
3966 Z_TYPE_PP(tmp
) != IS_NULL
) {
3969 node
= xmlNewNode(NULL
, BAD_CAST(detail_name
));
3970 xmlAddChild(param
, node
);
3972 zend_hash_internal_pointer_reset(fault
->details
);
3973 zend_hash_get_current_data(fault
->details
, (void**)&sparam
);
3974 sparam
= *(sdlParamPtr
*)sparam
;
3977 Z_TYPE_P(detail
) == IS_OBJECT
&&
3979 zend_hash_num_elements(Z_OBJPROP_P(detail
)) == 1 &&
3980 zend_hash_find(Z_OBJPROP_P(detail
), sparam
->element
->name
, strlen(sparam
->element
->name
)+1, (void**)&tmp
) == SUCCESS
) {
3984 x
= serialize_parameter(sparam
, detail
, 1, NULL
, use
, node TSRMLS_CC
);
3987 function
->binding
&&
3988 function
->binding
->bindingType
== BINDING_SOAP
&&
3989 function
->bindingAttributes
) {
3990 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)function
->bindingAttributes
;
3991 if (fnb
->style
== SOAP_RPC
&& !sparam
->element
) {
3992 if (fault
->bindingAttributes
) {
3993 sdlSoapBindingFunctionFaultPtr fb
= (sdlSoapBindingFunctionFaultPtr
)fault
->bindingAttributes
;
3995 xmlNsPtr ns
= encode_add_ns(x
, fb
->ns
);
4000 if (sparam
->element
) {
4001 ns
= encode_add_ns(x
, sparam
->element
->namens
);
4002 xmlNodeSetName(x
, BAD_CAST(sparam
->element
->name
));
4007 if (use
== SOAP_ENCODED
&& version
== SOAP_1_2
) {
4008 xmlSetNsProp(x
, envelope
->ns
, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE
));
4010 } else if (zend_hash_find(prop
, "detail", sizeof("detail"), (void**)&tmp
) == SUCCESS
&&
4011 Z_TYPE_PP(tmp
) != IS_NULL
) {
4012 serialize_zval(*tmp
, NULL
, detail_name
, use
, param TSRMLS_CC
);
4019 head
= xmlNewChild(envelope
, ns
, BAD_CAST("Header"), NULL
);
4022 if (Z_TYPE(h
->retval
) != IS_NULL
) {
4023 encodePtr hdr_enc
= NULL
;
4024 int hdr_use
= SOAP_LITERAL
;
4025 zval
*hdr_ret
= &h
->retval
;
4026 char *hdr_ns
= h
->hdr
?h
->hdr
->ns
:NULL
;
4027 char *hdr_name
= Z_STRVAL(h
->function_name
);
4030 if (Z_TYPE(h
->retval
) == IS_OBJECT
&&
4031 instanceof_function(Z_OBJCE(h
->retval
), soap_header_class_entry TSRMLS_CC
)) {
4032 HashTable
* ht
= Z_OBJPROP(h
->retval
);
4034 sdlSoapBindingFunctionHeaderPtr
*hdr
;
4035 smart_str key
= {0};
4037 if (zend_hash_find(ht
, "namespace", sizeof("namespace"), (void**)&tmp
) == SUCCESS
&&
4038 Z_TYPE_PP(tmp
) == IS_STRING
) {
4039 smart_str_appendl(&key
, Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
));
4040 smart_str_appendc(&key
, ':');
4041 hdr_ns
= Z_STRVAL_PP(tmp
);
4043 if (zend_hash_find(ht
, "name", sizeof("name"), (void**)&tmp
) == SUCCESS
&&
4044 Z_TYPE_PP(tmp
) == IS_STRING
) {
4045 smart_str_appendl(&key
, Z_STRVAL_PP(tmp
), Z_STRLEN_PP(tmp
));
4046 hdr_name
= Z_STRVAL_PP(tmp
);
4049 if (function
&& function
->binding
&& function
->binding
->bindingType
== BINDING_SOAP
) {
4050 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)function
->bindingAttributes
;
4052 if (fnb
->output
.headers
&&
4053 zend_hash_find(fnb
->output
.headers
, key
.c
, key
.len
+1, (void**)&hdr
) == SUCCESS
) {
4054 hdr_enc
= (*hdr
)->encode
;
4055 hdr_use
= (*hdr
)->use
;
4058 smart_str_free(&key
);
4059 if (zend_hash_find(ht
, "data", sizeof("data"), (void**)&tmp
) == SUCCESS
) {
4067 if (serialize_response_call2(head
, h
->function
, Z_STRVAL(h
->function_name
), uri
, hdr_ret
, version
, 0 TSRMLS_CC
) == SOAP_ENCODED
) {
4071 xmlNodePtr xmlHdr
= master_to_xml(hdr_enc
, hdr_ret
, hdr_use
, head TSRMLS_CC
);
4073 xmlNodeSetName(xmlHdr
, BAD_CAST(hdr_name
));
4076 xmlNsPtr nsptr
= encode_add_ns(xmlHdr
,hdr_ns
);
4077 xmlSetNs(xmlHdr
, nsptr
);
4084 if (head
->children
== NULL
) {
4085 xmlUnlinkNode(head
);
4090 body
= xmlNewChild(envelope
, ns
, BAD_CAST("Body"), NULL
);
4092 if (serialize_response_call2(body
, function
, function_name
, uri
, ret
, version
, 1 TSRMLS_CC
) == SOAP_ENCODED
) {
4098 if (use
== SOAP_ENCODED
) {
4099 xmlNewNs(envelope
, BAD_CAST(XSD_NAMESPACE
), BAD_CAST(XSD_NS_PREFIX
));
4100 if (version
== SOAP_1_1
) {
4101 xmlNewNs(envelope
, BAD_CAST(SOAP_1_1_ENC_NAMESPACE
), BAD_CAST(SOAP_1_1_ENC_NS_PREFIX
));
4102 xmlSetNsProp(envelope
, envelope
->ns
, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_1_ENC_NAMESPACE
));
4103 } else if (version
== SOAP_1_2
) {
4104 xmlNewNs(envelope
, BAD_CAST(SOAP_1_2_ENC_NAMESPACE
), BAD_CAST(SOAP_1_2_ENC_NS_PREFIX
));
4110 if (function
&& function
->responseName
== NULL
&&
4111 body
->children
== NULL
&& head
== NULL
) {
4118 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
)
4121 xmlNodePtr envelope
= NULL
, body
, method
= NULL
, head
= NULL
;
4123 zval
**zstyle
, **zuse
;
4125 HashTable
*hdrs
= NULL
;
4129 doc
= xmlNewDoc(BAD_CAST("1.0"));
4130 doc
->encoding
= xmlCharStrdup("UTF-8");
4131 doc
->charset
= XML_CHAR_ENCODING_UTF8
;
4132 if (version
== SOAP_1_1
) {
4133 envelope
= xmlNewDocNode(doc
, NULL
, BAD_CAST("Envelope"), NULL
);
4134 ns
= xmlNewNs(envelope
, BAD_CAST(SOAP_1_1_ENV_NAMESPACE
), BAD_CAST(SOAP_1_1_ENV_NS_PREFIX
));
4135 xmlSetNs(envelope
, ns
);
4136 } else if (version
== SOAP_1_2
) {
4137 envelope
= xmlNewDocNode(doc
, NULL
, BAD_CAST("Envelope"), NULL
);
4138 ns
= xmlNewNs(envelope
, BAD_CAST(SOAP_1_2_ENV_NAMESPACE
), BAD_CAST(SOAP_1_2_ENV_NS_PREFIX
));
4139 xmlSetNs(envelope
, ns
);
4141 soap_error0(E_ERROR
, "Unknown SOAP version");
4143 xmlDocSetRootElement(doc
, envelope
);
4146 head
= xmlNewChild(envelope
, ns
, BAD_CAST("Header"), NULL
);
4149 body
= xmlNewChild(envelope
, ns
, BAD_CAST("Body"), NULL
);
4151 if (function
&& function
->binding
->bindingType
== BINDING_SOAP
) {
4152 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)function
->bindingAttributes
;
4154 hdrs
= fnb
->input
.headers
;
4156 /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
4157 /*style = SOAP_RPC;*/
4158 use
= fnb
->input
.use
;
4159 if (style
== SOAP_RPC
) {
4160 ns
= encode_add_ns(body
, fnb
->input
.ns
);
4161 if (function
->requestName
) {
4162 method
= xmlNewChild(body
, ns
, BAD_CAST(function
->requestName
), NULL
);
4164 method
= xmlNewChild(body
, ns
, BAD_CAST(function
->functionName
), NULL
);
4168 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "style", sizeof("style"), (void **)&zstyle
) == SUCCESS
) {
4169 style
= Z_LVAL_PP(zstyle
);
4173 /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
4174 /*style = SOAP_RPC;*/
4175 if (style
== SOAP_RPC
) {
4176 ns
= encode_add_ns(body
, uri
);
4177 if (function_name
) {
4178 method
= xmlNewChild(body
, ns
, BAD_CAST(function_name
), NULL
);
4179 } else if (function
&& function
->requestName
) {
4180 method
= xmlNewChild(body
, ns
, BAD_CAST(function
->requestName
), NULL
);
4181 } else if (function
&& function
->functionName
) {
4182 method
= xmlNewChild(body
, ns
, BAD_CAST(function
->functionName
), NULL
);
4190 if (zend_hash_find(Z_OBJPROP_P(this_ptr
), "use", sizeof("use"), (void **)&zuse
) == SUCCESS
&&
4191 Z_LVAL_PP(zuse
) == SOAP_LITERAL
) {
4198 for (i
= 0;i
< arg_count
;i
++) {
4200 sdlParamPtr parameter
= get_param(function
, NULL
, i
, FALSE
);
4202 if (style
== SOAP_RPC
) {
4203 param
= serialize_parameter(parameter
, arguments
[i
], i
, NULL
, use
, method TSRMLS_CC
);
4204 } else if (style
== SOAP_DOCUMENT
) {
4205 param
= serialize_parameter(parameter
, arguments
[i
], i
, NULL
, use
, body TSRMLS_CC
);
4206 if (function
&& function
->binding
->bindingType
== BINDING_SOAP
) {
4207 if (parameter
&& parameter
->element
) {
4208 ns
= encode_add_ns(param
, parameter
->element
->namens
);
4209 xmlNodeSetName(param
, BAD_CAST(parameter
->element
->name
));
4210 xmlSetNs(param
, ns
);
4216 if (function
&& function
->requestParameters
) {
4217 int n
= zend_hash_num_elements(function
->requestParameters
);
4219 if (n
> arg_count
) {
4220 for (i
= arg_count
; i
< n
; i
++) {
4222 sdlParamPtr parameter
= get_param(function
, NULL
, i
, FALSE
);
4224 if (style
== SOAP_RPC
) {
4225 param
= serialize_parameter(parameter
, NULL
, i
, NULL
, use
, method TSRMLS_CC
);
4226 } else if (style
== SOAP_DOCUMENT
) {
4227 param
= serialize_parameter(parameter
, NULL
, i
, NULL
, use
, body TSRMLS_CC
);
4228 if (function
&& function
->binding
->bindingType
== BINDING_SOAP
) {
4229 if (parameter
&& parameter
->element
) {
4230 ns
= encode_add_ns(param
, parameter
->element
->namens
);
4231 xmlNodeSetName(param
, BAD_CAST(parameter
->element
->name
));
4232 xmlSetNs(param
, ns
);
4243 zend_hash_internal_pointer_reset(soap_headers
);
4244 while (zend_hash_get_current_data(soap_headers
,(void**)&header
) == SUCCESS
) {
4245 HashTable
*ht
= Z_OBJPROP_PP(header
);
4246 zval
**name
, **ns
, **tmp
;
4248 if (zend_hash_find(ht
, "name", sizeof("name"), (void**)&name
) == SUCCESS
&&
4249 Z_TYPE_PP(name
) == IS_STRING
&&
4250 zend_hash_find(ht
, "namespace", sizeof("namespace"), (void**)&ns
) == SUCCESS
&&
4251 Z_TYPE_PP(ns
) == IS_STRING
) {
4254 int hdr_use
= SOAP_LITERAL
;
4255 encodePtr enc
= NULL
;
4258 smart_str key
= {0};
4259 sdlSoapBindingFunctionHeaderPtr
*hdr
;
4261 smart_str_appendl(&key
, Z_STRVAL_PP(ns
), Z_STRLEN_PP(ns
));
4262 smart_str_appendc(&key
, ':');
4263 smart_str_appendl(&key
, Z_STRVAL_PP(name
), Z_STRLEN_PP(name
));
4265 if (zend_hash_find(hdrs
, key
.c
, key
.len
+1,(void**)&hdr
) == SUCCESS
) {
4266 hdr_use
= (*hdr
)->use
;
4267 enc
= (*hdr
)->encode
;
4268 if (hdr_use
== SOAP_ENCODED
) {
4272 smart_str_free(&key
);
4275 if (zend_hash_find(ht
, "data", sizeof("data"), (void**)&tmp
) == SUCCESS
) {
4276 h
= master_to_xml(enc
, *tmp
, hdr_use
, head TSRMLS_CC
);
4277 xmlNodeSetName(h
, BAD_CAST(Z_STRVAL_PP(name
)));
4279 h
= xmlNewNode(NULL
, BAD_CAST(Z_STRVAL_PP(name
)));
4280 xmlAddChild(head
, h
);
4282 nsptr
= encode_add_ns(h
, Z_STRVAL_PP(ns
));
4285 if (zend_hash_find(ht
, "mustUnderstand", sizeof("mustUnderstand"), (void**)&tmp
) == SUCCESS
&&
4286 Z_TYPE_PP(tmp
) == IS_BOOL
&& Z_LVAL_PP(tmp
)) {
4287 if (version
== SOAP_1_1
) {
4288 xmlSetProp(h
, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX
":mustUnderstand"), BAD_CAST("1"));
4290 xmlSetProp(h
, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX
":mustUnderstand"), BAD_CAST("true"));
4293 if (zend_hash_find(ht
, "actor", sizeof("actor"), (void**)&tmp
) == SUCCESS
) {
4294 if (Z_TYPE_PP(tmp
) == IS_STRING
) {
4295 if (version
== SOAP_1_1
) {
4296 xmlSetProp(h
, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX
":actor"), BAD_CAST(Z_STRVAL_PP(tmp
)));
4298 xmlSetProp(h
, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX
":role"), BAD_CAST(Z_STRVAL_PP(tmp
)));
4300 } else if (Z_TYPE_PP(tmp
) == IS_LONG
) {
4301 if (version
== SOAP_1_1
) {
4302 if (Z_LVAL_PP(tmp
) == SOAP_ACTOR_NEXT
) {
4303 xmlSetProp(h
, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX
":actor"), BAD_CAST(SOAP_1_1_ACTOR_NEXT
));
4306 if (Z_LVAL_PP(tmp
) == SOAP_ACTOR_NEXT
) {
4307 xmlSetProp(h
, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX
":role"), BAD_CAST(SOAP_1_2_ACTOR_NEXT
));
4308 } else if (Z_LVAL_PP(tmp
) == SOAP_ACTOR_NONE
) {
4309 xmlSetProp(h
, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX
":role"), BAD_CAST(SOAP_1_2_ACTOR_NONE
));
4310 } else if (Z_LVAL_PP(tmp
) == SOAP_ACTOR_UNLIMATERECEIVER
) {
4311 xmlSetProp(h
, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX
":role"), BAD_CAST(SOAP_1_2_ACTOR_UNLIMATERECEIVER
));
4317 zend_hash_move_forward(soap_headers
);
4321 if (use
== SOAP_ENCODED
) {
4322 xmlNewNs(envelope
, BAD_CAST(XSD_NAMESPACE
), BAD_CAST(XSD_NS_PREFIX
));
4323 if (version
== SOAP_1_1
) {
4324 xmlNewNs(envelope
, BAD_CAST(SOAP_1_1_ENC_NAMESPACE
), BAD_CAST(SOAP_1_1_ENC_NS_PREFIX
));
4325 xmlSetNsProp(envelope
, envelope
->ns
, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_1_ENC_NAMESPACE
));
4326 } else if (version
== SOAP_1_2
) {
4327 xmlNewNs(envelope
, BAD_CAST(SOAP_1_2_ENC_NAMESPACE
), BAD_CAST(SOAP_1_2_ENC_NS_PREFIX
));
4329 xmlSetNsProp(method
, envelope
->ns
, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE
));
4339 static xmlNodePtr
serialize_parameter(sdlParamPtr param
, zval
*param_val
, int index
, char *name
, int style
, xmlNodePtr parent TSRMLS_DC
)
4342 xmlNodePtr xmlParam
;
4343 char paramNameBuf
[10];
4346 Z_TYPE_P(param_val
) == IS_OBJECT
&&
4347 Z_OBJCE_P(param_val
) == soap_param_class_entry
) {
4351 if (zend_hash_find(Z_OBJPROP_P(param_val
), "param_name", sizeof("param_name"), (void **)¶m_name
) == SUCCESS
&&
4352 zend_hash_find(Z_OBJPROP_P(param_val
), "param_data", sizeof("param_data"), (void **)¶m_data
) == SUCCESS
) {
4353 param_val
= *param_data
;
4354 name
= Z_STRVAL_PP(param_name
);
4358 if (param
!= NULL
&& param
->paramName
!= NULL
) {
4359 paramName
= param
->paramName
;
4362 paramName
= paramNameBuf
;
4363 snprintf(paramName
, sizeof(paramNameBuf
), "param%d",index
);
4369 xmlParam
= serialize_zval(param_val
, param
, paramName
, style
, parent TSRMLS_CC
);
4374 static xmlNodePtr
serialize_zval(zval
*val
, sdlParamPtr param
, char *paramName
, int style
, xmlNodePtr parent TSRMLS_DC
)
4376 xmlNodePtr xmlParam
;
4380 if (param
!= NULL
) {
4381 enc
= param
->encode
;
4383 if (param
->element
) {
4384 if (param
->element
->fixed
) {
4385 ZVAL_STRING(&defval
, param
->element
->fixed
, 0);
4387 } else if (param
->element
->def
&& !param
->element
->nillable
) {
4388 ZVAL_STRING(&defval
, param
->element
->def
, 0);
4396 xmlParam
= master_to_xml(enc
, val
, style
, parent TSRMLS_CC
);
4397 if (!strcmp((char*)xmlParam
->name
, "BOGUS")) {
4398 xmlNodeSetName(xmlParam
, BAD_CAST(paramName
));
4403 static sdlParamPtr
get_param(sdlFunctionPtr function
, char *param_name
, int index
, int response
)
4408 if (function
== NULL
) {
4412 if (response
== FALSE
) {
4413 ht
= function
->requestParameters
;
4415 ht
= function
->responseParameters
;
4422 if (param_name
!= NULL
) {
4423 if (zend_hash_find(ht
, param_name
, strlen(param_name
), (void **)&tmp
) != FAILURE
) {
4428 zend_hash_internal_pointer_reset_ex(ht
, &pos
);
4429 while (zend_hash_get_current_data_ex(ht
, (void **)&tmp
, &pos
) != FAILURE
) {
4430 if ((*tmp
)->paramName
&& strcmp(param_name
, (*tmp
)->paramName
) == 0) {
4433 zend_hash_move_forward_ex(ht
, &pos
);
4437 if (zend_hash_index_find(ht
, index
, (void **)&tmp
) != FAILURE
) {
4444 static sdlFunctionPtr
get_function(sdlPtr sdl
, const char *function_name
)
4446 sdlFunctionPtr
*tmp
;
4448 int len
= strlen(function_name
);
4449 char *str
= estrndup(function_name
,len
);
4450 php_strtolower(str
,len
);
4452 if (zend_hash_find(&sdl
->functions
, str
, len
+1, (void **)&tmp
) != FAILURE
) {
4455 } else if (sdl
->requests
!= NULL
&& zend_hash_find(sdl
->requests
, str
, len
+1, (void **)&tmp
) != FAILURE
) {
4464 static sdlFunctionPtr
get_doc_function(sdlPtr sdl
, xmlNodePtr params
)
4467 sdlFunctionPtr
*tmp
;
4470 zend_hash_internal_pointer_reset(&sdl
->functions
);
4471 while (zend_hash_get_current_data(&sdl
->functions
, (void**)&tmp
) == SUCCESS
) {
4472 if ((*tmp
)->binding
&& (*tmp
)->binding
->bindingType
== BINDING_SOAP
) {
4473 sdlSoapBindingFunctionPtr fnb
= (sdlSoapBindingFunctionPtr
)(*tmp
)->bindingAttributes
;
4474 if (fnb
->style
== SOAP_DOCUMENT
) {
4475 if (params
== NULL
) {
4476 if ((*tmp
)->requestParameters
== NULL
||
4477 zend_hash_num_elements((*tmp
)->requestParameters
) == 0) {
4480 } else if ((*tmp
)->requestParameters
!= NULL
&&
4481 zend_hash_num_elements((*tmp
)->requestParameters
) > 0) {
4483 xmlNodePtr node
= params
;
4485 zend_hash_internal_pointer_reset((*tmp
)->requestParameters
);
4486 while (zend_hash_get_current_data((*tmp
)->requestParameters
, (void**)¶m
) == SUCCESS
) {
4487 if ((*param
)->element
) {
4488 if (strcmp((*param
)->element
->name
, (char*)node
->name
) != 0) {
4492 if ((*param
)->element
->namens
!= NULL
&& node
->ns
!= NULL
) {
4493 if (strcmp((*param
)->element
->namens
, (char*)node
->ns
->href
) != 0) {
4497 } else if ((void*)(*param
)->element
->namens
!= (void*)node
->ns
) {
4501 } else if (strcmp((*param
)->paramName
, (char*)node
->name
) != 0) {
4505 zend_hash_move_forward((*tmp
)->requestParameters
);
4508 if (ok
/*&& node == NULL*/) {
4514 zend_hash_move_forward(&sdl
->functions
);
4520 static void function_to_string(sdlFunctionPtr function
, smart_str
*buf
)
4526 if (function
->responseParameters
&&
4527 zend_hash_num_elements(function
->responseParameters
) > 0) {
4528 if (zend_hash_num_elements(function
->responseParameters
) == 1) {
4529 zend_hash_internal_pointer_reset(function
->responseParameters
);
4530 zend_hash_get_current_data(function
->responseParameters
, (void**)¶m
);
4531 if ((*param
)->encode
&& (*param
)->encode
->details
.type_str
) {
4532 smart_str_appendl(buf
, (*param
)->encode
->details
.type_str
, strlen((*param
)->encode
->details
.type_str
));
4533 smart_str_appendc(buf
, ' ');
4535 smart_str_appendl(buf
, "UNKNOWN ", 8);
4539 smart_str_appendl(buf
, "list(", 5);
4540 zend_hash_internal_pointer_reset_ex(function
->responseParameters
, &pos
);
4541 while (zend_hash_get_current_data_ex(function
->responseParameters
, (void **)¶m
, &pos
) != FAILURE
) {
4543 smart_str_appendl(buf
, ", ", 2);
4545 if ((*param
)->encode
&& (*param
)->encode
->details
.type_str
) {
4546 smart_str_appendl(buf
, (*param
)->encode
->details
.type_str
, strlen((*param
)->encode
->details
.type_str
));
4548 smart_str_appendl(buf
, "UNKNOWN", 7);
4550 smart_str_appendl(buf
, " $", 2);
4551 smart_str_appendl(buf
, (*param
)->paramName
, strlen((*param
)->paramName
));
4552 zend_hash_move_forward_ex(function
->responseParameters
, &pos
);
4555 smart_str_appendl(buf
, ") ", 2);
4558 smart_str_appendl(buf
, "void ", 5);
4561 smart_str_appendl(buf
, function
->functionName
, strlen(function
->functionName
));
4563 smart_str_appendc(buf
, '(');
4564 if (function
->requestParameters
) {
4566 zend_hash_internal_pointer_reset_ex(function
->requestParameters
, &pos
);
4567 while (zend_hash_get_current_data_ex(function
->requestParameters
, (void **)¶m
, &pos
) != FAILURE
) {
4569 smart_str_appendl(buf
, ", ", 2);
4571 if ((*param
)->encode
&& (*param
)->encode
->details
.type_str
) {
4572 smart_str_appendl(buf
, (*param
)->encode
->details
.type_str
, strlen((*param
)->encode
->details
.type_str
));
4574 smart_str_appendl(buf
, "UNKNOWN", 7);
4576 smart_str_appendl(buf
, " $", 2);
4577 smart_str_appendl(buf
, (*param
)->paramName
, strlen((*param
)->paramName
));
4578 zend_hash_move_forward_ex(function
->requestParameters
, &pos
);
4582 smart_str_appendc(buf
, ')');
4586 static void model_to_string(sdlContentModelPtr model
, smart_str
*buf
, int level
)
4590 switch (model
->kind
) {
4591 case XSD_CONTENT_ELEMENT
:
4592 type_to_string(model
->u
.element
, buf
, level
);
4593 smart_str_appendl(buf
, ";\n", 2);
4595 case XSD_CONTENT_ANY
:
4596 for (i
= 0;i
< level
;i
++) {
4597 smart_str_appendc(buf
, ' ');
4599 smart_str_appendl(buf
, "<anyXML> any;\n", sizeof("<anyXML> any;\n")-1);
4601 case XSD_CONTENT_SEQUENCE
:
4602 case XSD_CONTENT_ALL
:
4603 case XSD_CONTENT_CHOICE
: {
4604 sdlContentModelPtr
*tmp
;
4606 zend_hash_internal_pointer_reset(model
->u
.content
);
4607 while (zend_hash_get_current_data(model
->u
.content
, (void**)&tmp
) == SUCCESS
) {
4608 model_to_string(*tmp
, buf
, level
);
4609 zend_hash_move_forward(model
->u
.content
);
4613 case XSD_CONTENT_GROUP
:
4614 model_to_string(model
->u
.group
->model
, buf
, level
);
4620 static void type_to_string(sdlTypePtr type
, smart_str
*buf
, int level
)
4623 smart_str spaces
= {0};
4626 for (i
= 0;i
< level
;i
++) {
4627 smart_str_appendc(&spaces
, ' ');
4629 smart_str_appendl(buf
, spaces
.c
, spaces
.len
);
4631 switch (type
->kind
) {
4632 case XSD_TYPEKIND_SIMPLE
:
4634 smart_str_appendl(buf
, type
->encode
->details
.type_str
, strlen(type
->encode
->details
.type_str
));
4635 smart_str_appendc(buf
, ' ');
4637 smart_str_appendl(buf
, "anyType ", sizeof("anyType ")-1);
4639 smart_str_appendl(buf
, type
->name
, strlen(type
->name
));
4641 case XSD_TYPEKIND_LIST
:
4642 smart_str_appendl(buf
, "list ", 5);
4643 smart_str_appendl(buf
, type
->name
, strlen(type
->name
));
4644 if (type
->elements
) {
4645 sdlTypePtr
*item_type
;
4647 smart_str_appendl(buf
, " {", 2);
4648 zend_hash_internal_pointer_reset_ex(type
->elements
, &pos
);
4649 if (zend_hash_get_current_data_ex(type
->elements
, (void **)&item_type
, &pos
) != FAILURE
) {
4650 smart_str_appendl(buf
, (*item_type
)->name
, strlen((*item_type
)->name
));
4652 smart_str_appendc(buf
, '}');
4655 case XSD_TYPEKIND_UNION
:
4656 smart_str_appendl(buf
, "union ", 6);
4657 smart_str_appendl(buf
, type
->name
, strlen(type
->name
));
4658 if (type
->elements
) {
4659 sdlTypePtr
*item_type
;
4662 smart_str_appendl(buf
, " {", 2);
4663 zend_hash_internal_pointer_reset_ex(type
->elements
, &pos
);
4664 while (zend_hash_get_current_data_ex(type
->elements
, (void **)&item_type
, &pos
) != FAILURE
) {
4666 smart_str_appendc(buf
, ',');
4669 smart_str_appendl(buf
, (*item_type
)->name
, strlen((*item_type
)->name
));
4670 zend_hash_move_forward_ex(type
->elements
, &pos
);
4672 smart_str_appendc(buf
, '}');
4675 case XSD_TYPEKIND_COMPLEX
:
4676 case XSD_TYPEKIND_RESTRICTION
:
4677 case XSD_TYPEKIND_EXTENSION
:
4679 (type
->encode
->details
.type
== IS_ARRAY
||
4680 type
->encode
->details
.type
== SOAP_ENC_ARRAY
)) {
4681 sdlAttributePtr
*attr
;
4682 sdlExtraAttributePtr
*ext
;
4684 if (type
->attributes
&&
4685 zend_hash_find(type
->attributes
, SOAP_1_1_ENC_NAMESPACE
":arrayType",
4686 sizeof(SOAP_1_1_ENC_NAMESPACE
":arrayType"),
4687 (void **)&attr
) == SUCCESS
&&
4688 zend_hash_find((*attr
)->extraAttributes
, WSDL_NAMESPACE
":arrayType", sizeof(WSDL_NAMESPACE
":arrayType"), (void **)&ext
) == SUCCESS
) {
4689 char *end
= strchr((*ext
)->val
, '[');
4692 len
= strlen((*ext
)->val
);
4694 len
= end
-(*ext
)->val
;
4697 smart_str_appendl(buf
, "anyType", sizeof("anyType")-1);
4699 smart_str_appendl(buf
, (*ext
)->val
, len
);
4701 smart_str_appendc(buf
, ' ');
4702 smart_str_appendl(buf
, type
->name
, strlen(type
->name
));
4704 smart_str_appends(buf
, end
);
4707 sdlTypePtr elementType
;
4708 if (type
->attributes
&&
4709 zend_hash_find(type
->attributes
, SOAP_1_2_ENC_NAMESPACE
":itemType",
4710 sizeof(SOAP_1_2_ENC_NAMESPACE
":itemType"),
4711 (void **)&attr
) == SUCCESS
&&
4712 zend_hash_find((*attr
)->extraAttributes
, WSDL_NAMESPACE
":itemType", sizeof(WSDL_NAMESPACE
":arrayType"), (void **)&ext
) == SUCCESS
) {
4713 smart_str_appends(buf
, (*ext
)->val
);
4714 smart_str_appendc(buf
, ' ');
4715 } else if (type
->elements
&&
4716 zend_hash_num_elements(type
->elements
) == 1 &&
4717 (zend_hash_internal_pointer_reset(type
->elements
),
4718 zend_hash_get_current_data(type
->elements
, (void**)&elementType
) == SUCCESS
) &&
4719 (elementType
= *(sdlTypePtr
*)elementType
) != NULL
&&
4720 elementType
->encode
&& elementType
->encode
->details
.type_str
) {
4721 smart_str_appends(buf
, elementType
->encode
->details
.type_str
);
4722 smart_str_appendc(buf
, ' ');
4724 smart_str_appendl(buf
, "anyType ", 8);
4726 smart_str_appendl(buf
, type
->name
, strlen(type
->name
));
4727 if (type
->attributes
&&
4728 zend_hash_find(type
->attributes
, SOAP_1_2_ENC_NAMESPACE
":arraySize",
4729 sizeof(SOAP_1_2_ENC_NAMESPACE
":arraySize"),
4730 (void **)&attr
) == SUCCESS
&&
4731 zend_hash_find((*attr
)->extraAttributes
, WSDL_NAMESPACE
":itemType", sizeof(WSDL_NAMESPACE
":arraySize"), (void **)&ext
) == SUCCESS
) {
4732 smart_str_appendc(buf
, '[');
4733 smart_str_appends(buf
, (*ext
)->val
);
4734 smart_str_appendc(buf
, ']');
4736 smart_str_appendl(buf
, "[]", 2);
4740 smart_str_appendl(buf
, "struct ", 7);
4741 smart_str_appendl(buf
, type
->name
, strlen(type
->name
));
4742 smart_str_appendc(buf
, ' ');
4743 smart_str_appendl(buf
, "{\n", 2);
4744 if ((type
->kind
== XSD_TYPEKIND_RESTRICTION
||
4745 type
->kind
== XSD_TYPEKIND_EXTENSION
) && type
->encode
) {
4746 encodePtr enc
= type
->encode
;
4747 while (enc
&& enc
->details
.sdl_type
&&
4748 enc
!= enc
->details
.sdl_type
->encode
&&
4749 enc
->details
.sdl_type
->kind
!= XSD_TYPEKIND_SIMPLE
&&
4750 enc
->details
.sdl_type
->kind
!= XSD_TYPEKIND_LIST
&&
4751 enc
->details
.sdl_type
->kind
!= XSD_TYPEKIND_UNION
) {
4752 enc
= enc
->details
.sdl_type
->encode
;
4755 smart_str_appendl(buf
, spaces
.c
, spaces
.len
);
4756 smart_str_appendc(buf
, ' ');
4757 smart_str_appendl(buf
, type
->encode
->details
.type_str
, strlen(type
->encode
->details
.type_str
));
4758 smart_str_appendl(buf
, " _;\n", 4);
4762 model_to_string(type
->model
, buf
, level
+1);
4764 if (type
->attributes
) {
4765 sdlAttributePtr
*attr
;
4767 zend_hash_internal_pointer_reset_ex(type
->attributes
, &pos
);
4768 while (zend_hash_get_current_data_ex(type
->attributes
, (void **)&attr
, &pos
) != FAILURE
) {
4769 smart_str_appendl(buf
, spaces
.c
, spaces
.len
);
4770 smart_str_appendc(buf
, ' ');
4771 if ((*attr
)->encode
&& (*attr
)->encode
->details
.type_str
) {
4772 smart_str_appends(buf
, (*attr
)->encode
->details
.type_str
);
4773 smart_str_appendc(buf
, ' ');
4775 smart_str_appendl(buf
, "UNKNOWN ", 8);
4777 smart_str_appends(buf
, (*attr
)->name
);
4778 smart_str_appendl(buf
, ";\n", 2);
4779 zend_hash_move_forward_ex(type
->attributes
, &pos
);
4782 smart_str_appendl(buf
, spaces
.c
, spaces
.len
);
4783 smart_str_appendc(buf
, '}');
4789 smart_str_free(&spaces
);
4793 static void delete_url(void *handle
)
4795 php_url_free((php_url
*)handle
);
4798 static void delete_service(void *data
)
4800 soapServicePtr service
= (soapServicePtr
)data
;
4802 if (service
->soap_functions
.ft
) {
4803 zend_hash_destroy(service
->soap_functions
.ft
);
4804 efree(service
->soap_functions
.ft
);
4807 if (service
->typemap
) {
4808 zend_hash_destroy(service
->typemap
);
4809 efree(service
->typemap
);
4812 if (service
->soap_class
.argc
) {
4814 for (i
= 0; i
< service
->soap_class
.argc
;i
++) {
4815 zval_ptr_dtor(&service
->soap_class
.argv
[i
]);
4817 efree(service
->soap_class
.argv
);
4820 if (service
->actor
) {
4821 efree(service
->actor
);
4824 efree(service
->uri
);
4827 delete_sdl(service
->sdl
);
4829 if (service
->encoding
) {
4830 xmlCharEncCloseFunc(service
->encoding
);
4832 if (service
->class_map
) {
4833 zend_hash_destroy(service
->class_map
);
4834 FREE_HASHTABLE(service
->class_map
);
4836 if (service
->soap_object
) {
4837 zval_ptr_dtor(&service
->soap_object
);
4842 static void delete_hashtable(void *data
)
4844 HashTable
*ht
= (HashTable
*)data
;
4845 zend_hash_destroy(ht
);