@@ -260,6 +260,7 @@ PHP_METHOD(SoapClient, __getTypes);
260
260
PHP_METHOD (SoapClient , __doRequest );
261
261
PHP_METHOD (SoapClient , __setCookie );
262
262
PHP_METHOD (SoapClient , __setLocation );
263
+ PHP_METHOD (SoapClient , __setSoapHeaders );
263
264
264
265
/* SoapVar Functions */
265
266
PHP_METHOD (SoapVar , SoapVar );
@@ -348,6 +349,7 @@ static zend_function_entry soap_client_functions[] = {
348
349
PHP_ME (SoapClient , __doRequest , NULL , 0 )
349
350
PHP_ME (SoapClient , __setCookie , NULL , 0 )
350
351
PHP_ME (SoapClient , __setLocation , NULL , 0 )
352
+ PHP_ME (SoapClient , __setSoapHeaders , NULL , 0 )
351
353
{NULL , NULL , NULL }
352
354
};
353
355
@@ -2457,6 +2459,20 @@ static void do_soap_call(zval* this_ptr,
2457
2459
SOAP_CLIENT_END_CODE ();
2458
2460
}
2459
2461
2462
+ static void verify_soap_headers_array (HashTable * ht )
2463
+ {
2464
+ zval * * tmp ;
2465
+
2466
+ zend_hash_internal_pointer_reset (ht );
2467
+ while (zend_hash_get_current_data (ht , (void * * )& tmp ) == SUCCESS ) {
2468
+ if (Z_TYPE_PP (tmp ) != IS_OBJECT ||
2469
+ Z_OBJCE_PP (tmp ) != soap_header_class_entry ) {
2470
+ php_error_docref (NULL TSRMLS_CC , E_ERROR , "Invalid SOAP header ");
2471
+ }
2472
+ zend_hash_move_forward (ht );
2473
+ }
2474
+ }
2475
+
2460
2476
2461
2477
/* {{{ proto mixed SoapClient::__call ( string function_name [, array arguments [, array options [, array input_headers [, array output_headers]]]])
2462
2478
Calls a SOAP function */
@@ -2472,6 +2488,8 @@ PHP_METHOD(SoapClient, __call)
2472
2488
zval * * real_args = NULL ;
2473
2489
zval * * param ;
2474
2490
int arg_count ;
2491
+ zval * * tmp ;
2492
+ zend_bool free_soap_headers ;
2475
2493
2476
2494
HashPosition pos ;
2477
2495
@@ -2483,8 +2501,6 @@ PHP_METHOD(SoapClient, __call)
2483
2501
if (options ) {
2484
2502
if (Z_TYPE_P (options ) == IS_ARRAY ) {
2485
2503
HashTable * ht = Z_ARRVAL_P (options );
2486
- zval * * tmp ;
2487
-
2488
2504
if (zend_hash_find (ht , "location" , sizeof ("location" ), (void * * )& tmp ) == SUCCESS &&
2489
2505
Z_TYPE_PP (tmp ) == IS_STRING ) {
2490
2506
location = Z_STRVAL_PP (tmp );
@@ -2506,27 +2522,43 @@ PHP_METHOD(SoapClient, __call)
2506
2522
2507
2523
if (headers == NULL || Z_TYPE_P (headers ) == IS_NULL ) {
2508
2524
} else if (Z_TYPE_P (headers ) == IS_ARRAY ) {
2509
- zval * * tmp ;
2510
-
2511
2525
soap_headers = Z_ARRVAL_P (headers );
2512
- zend_hash_internal_pointer_reset (soap_headers );
2513
- while (zend_hash_get_current_data (soap_headers , (void * * )& tmp ) == SUCCESS ) {
2514
- if (Z_TYPE_PP (tmp ) != IS_OBJECT ||
2515
- Z_OBJCE_PP (tmp ) != soap_header_class_entry ) {
2516
- php_error_docref (NULL TSRMLS_CC , E_ERROR , "Invalid SOAP header ");
2517
- }
2518
- zend_hash_move_forward (soap_headers );
2519
- }
2526
+ verify_soap_headers_array (soap_headers );
2527
+ free_soap_headers = 0 ;
2520
2528
} else if (Z_TYPE_P (headers ) == IS_OBJECT &&
2521
2529
Z_OBJCE_P (headers ) == soap_header_class_entry ) {
2522
- soap_headers = emalloc (sizeof (HashTable ));
2523
- zend_hash_init (soap_headers , 0 , NULL , NULL /* ZVAL_PTR_DTOR*/ , 0 );
2530
+ soap_headers = emalloc (sizeof (HashTable ));
2531
+ zend_hash_init (soap_headers , 0 , NULL , ZVAL_PTR_DTOR , 0 );
2524
2532
zend_hash_next_index_insert (soap_headers , & headers , sizeof (zval * ), NULL );
2525
- headers = NULL ;
2533
+ ZVAL_ADDREF (headers );
2534
+ free_soap_headers = 1 ;
2526
2535
} else {
2527
2536
php_error_docref (NULL TSRMLS_CC , E_ERROR , "Invalid SOAP header ");
2528
2537
}
2529
2538
2539
+ /* Add default headers */
2540
+ if (zend_hash_find (Z_OBJPROP_P (this_ptr ), "__default_headers" , sizeof ("__default_headers" ), (void * * ) & tmp )== SUCCESS ) {
2541
+ HashTable * default_headers = Z_ARRVAL_P (* tmp );
2542
+ if (soap_headers ) {
2543
+ if (!free_soap_headers ) {
2544
+ HashTable * tmp = emalloc (sizeof (HashTable ));
2545
+ zend_hash_init (tmp , 0 , NULL , ZVAL_PTR_DTOR , 0 );
2546
+ zend_hash_copy (tmp , soap_headers , (copy_ctor_func_t ) zval_add_ref , NULL , sizeof (zval * ));
2547
+ soap_headers = tmp ;
2548
+ free_soap_headers = 1 ;
2549
+ }
2550
+ zend_hash_internal_pointer_reset (default_headers );
2551
+ while (zend_hash_get_current_data (default_headers , (void * * )& tmp ) == SUCCESS ) {
2552
+ ZVAL_ADDREF (* tmp );
2553
+ zend_hash_next_index_insert (soap_headers , tmp , sizeof (zval * ), NULL );
2554
+ zend_hash_move_forward (default_headers );
2555
+ }
2556
+ } else {
2557
+ soap_headers = Z_ARRVAL_P (* tmp );
2558
+ free_soap_headers = 0 ;
2559
+ }
2560
+ }
2561
+
2530
2562
arg_count = zend_hash_num_elements (Z_ARRVAL_P (args ));
2531
2563
2532
2564
if (arg_count > 0 ) {
@@ -2546,7 +2578,7 @@ PHP_METHOD(SoapClient, __call)
2546
2578
efree (real_args );
2547
2579
}
2548
2580
2549
- if (soap_headers && ! headers ) {
2581
+ if (soap_headers && free_soap_headers ) {
2550
2582
zend_hash_destroy (soap_headers );
2551
2583
efree (soap_headers );
2552
2584
}
@@ -2728,6 +2760,44 @@ PHP_METHOD(SoapClient, __setCookie)
2728
2760
}
2729
2761
/* }}} */
2730
2762
2763
+ /* {{{ proto void SoapClient::__setSoapHeaders(array SoapHeaders)
2764
+ Sets SOAP headers for subsequent calls (replaces any previous
2765
+ values).
2766
+ If no value is specified, all of the headers are removed. */
2767
+ PHP_METHOD (SoapClient , __setSoapHeaders )
2768
+ {
2769
+ zval * headers ;
2770
+
2771
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "|z" , & headers ) == FAILURE ) {
2772
+ php_error_docref (NULL TSRMLS_CC , E_ERROR , "Invalid parameters ");
2773
+ RETURN_NULL ();
2774
+ }
2775
+
2776
+ if (headers == NULL || Z_TYPE_P (headers ) == IS_NULL ) {
2777
+ zend_hash_del (Z_OBJPROP_P (this_ptr ), "__default_headers" , sizeof ("__default_headers" ));
2778
+ } else if (Z_TYPE_P (headers ) == IS_ARRAY || Z_TYPE_P (headers ) == IS_OBJECT ) {
2779
+ zval * default_headers ;
2780
+
2781
+ verify_soap_headers_array (Z_ARRVAL_P (headers ));
2782
+ if (zend_hash_find (Z_OBJPROP_P (this_ptr ), "__default_headers" , sizeof ("__default_headers" ), (void * * ) & default_headers )== FAILURE ) {
2783
+ add_property_zval (this_ptr , "__default_headers" , headers );
2784
+ }
2785
+ } else if (Z_TYPE_P (headers ) == IS_OBJECT &&
2786
+ Z_OBJCE_P (headers ) == soap_header_class_entry ) {
2787
+ zval * default_headers ;
2788
+ ALLOC_INIT_ZVAL (default_headers );
2789
+ array_init (default_headers );
2790
+ add_next_index_zval (default_headers , headers );
2791
+ add_property_zval (this_ptr , "__default_headers" , default_headers );
2792
+ } else {
2793
+ php_error_docref (NULL TSRMLS_CC , E_ERROR , "Invalid SOAP header ");
2794
+ }
2795
+ RETURN_TRUE ;
2796
+ }
2797
+ /* }}} */
2798
+
2799
+
2800
+
2731
2801
/* {{{ proto string SoapClient::__setLocation([string new_location])
2732
2802
Sets the location option (the endpoint URL that will be touched by the
2733
2803
following SOAP requests).
@@ -2776,9 +2846,18 @@ static void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_proper
2776
2846
} else {
2777
2847
int arg_count = ZEND_NUM_ARGS ();
2778
2848
zval * * arguments = (zval * * ) safe_emalloc (sizeof (zval * ), arg_count , 0 );
2849
+ zval * * soap_headers_p
2850
+ HashTable * soap_headers ;
2779
2851
2780
2852
zend_get_parameters_array (ht , arg_count , arguments );
2781
- do_soap_call (this_ptr , function , Z_STRLEN (function_name -> element ) + 1 , arg_count , arguments , return_value , NULL , NULL , NULL , NULL , NULL TSRMLS_CC );
2853
+
2854
+ if (zend_hash_find (Z_OBJPROP_P (this_ptr ), "__default_headers" , sizeof ("__default_properties" ), (void * * ) soap_headers_p )== SUCCESS
2855
+ && Z_TYPE_P (soap_headers_p )== IS_ARRAY ) {
2856
+ soap_headers = Z_ARRVAL_P (soap_headers_p );
2857
+ } else {
2858
+ soap_headers = NULL ;
2859
+ }
2860
+ do_soap_call (this_ptr , function , Z_STRLEN (function_name -> element ) + 1 , arg_count , arguments , return_value , NULL , NULL , NULL , soap_headers , NULL TSRMLS_CC );
2782
2861
efree (arguments );
2783
2862
}
2784
2863
zval_dtor (& function_name -> element );
0 commit comments