php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #51634
Patch 51634-curl-multivalued-field-post.patch revision 2012-05-14 20:12 UTC by raphael dot droz+floss at gmail dot com

Patch 51634-curl-multivalued-field-post.patch for cURL related Bug #51634

Patch version 2012-05-14 20:12 UTC

Return to Bug #51634 | Download this patch
Patch Revisions:

Developer: raphael.droz+floss@gmail.com

commit 746201cfd326664990b15a0d2bb19c93e7f3e35e
Author: Raphaël Droz <raphael.droz+floss@gmail.com>
Date:   Mon May 14 22:05:00 2012 +0200

    Fixed bug #51634 : curl can't post multiple fields with the same name.
    
    When curl_setopt "CURLOPT_POSTFIELDS" is given an associative array,
    then values which are an array themselves are iterated and several
    occurrences of form-data values are sent using the same key.
    
    This allows to post both binary files and multivalued fields without
    having to rely on the PHP-centric `key[0] = val` syntax.
    
    The following will now works as expected rather than sending the "Array"
    string:
     curl_setopt($ch, CURLOPT_POSTFIELDS, array("foo" => array("bar", "baz")))

diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index 3533991..7bc3704 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -2455,11 +2455,15 @@ string_copy:
 					ulong  num_key;
 					int    numeric_key;
 
-					SEPARATE_ZVAL(current);
-					convert_to_string_ex(current);
+					// used when the value is an array itself
+					HashTable        *post_multifield;
+					// will hold each of these value
+					zval            **one_multival;
 
+					SEPARATE_ZVAL(current);
 					zend_hash_get_current_key_ex(postfields, &string_key, &string_key_len, &num_key, 0, NULL);
 
+
 					/* Pretend we have a string_key here */
 					if(!string_key) {
 						spprintf(&string_key, 0, "%ld", num_key);
@@ -2469,6 +2473,39 @@ string_copy:
 						numeric_key = 0;
 					}
 
+					/*
+					  handle the key = array('value', ...) pattern
+					  as multiselect or checkboxes allow for multiple values for one key
+					*/
+					if(Z_TYPE_PP(current) == IS_ARRAY) {
+						post_multifield = HASH_OF(*current);
+						if (!post_multifield) {
+							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS at key %s", string_key);
+							RETVAL_FALSE;
+							return 1;
+						}
+
+						for (zend_hash_internal_pointer_reset(post_multifield);
+							 zend_hash_get_current_data(post_multifield, (void **) &one_multival) == SUCCESS;
+							 zend_hash_move_forward(post_multifield)
+							 ) {
+
+							SEPARATE_ZVAL(one_multival);
+							convert_to_string_ex(one_multival);
+
+							error = curl_formadd(&first, &last,
+												 CURLFORM_COPYNAME, string_key,
+												 CURLFORM_NAMELENGTH, (long)string_key_len - 1,
+												 CURLFORM_COPYCONTENTS, Z_STRVAL_PP(one_multival),
+												 CURLFORM_CONTENTSLENGTH, (long)Z_STRLEN_PP(one_multival),
+												 CURLFORM_END);
+						}
+						continue;
+					}
+
+
+					convert_to_string_ex(current);
+
 					postval = Z_STRVAL_PP(current);
 
 					/* The arguments after _NAMELENGTH and _CONTENTSLENGTH
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 03:01:28 2024 UTC