After swoole_http_client calls addfile, the post, array is converted into an Array string, and the server cannot get the data normally.

client centos6.9, php7.1.21 use swoole_http_client through post data and upload files to the server:

$data = [
    "p1" => 1,
    "p2" => 2,
    "groups" => [20,30]
];

$cli->addFile("/home/test/photo.jpg", "photo");

$cli->post("/index.php", $data, function ($cli) {
    echo $cli->body;
});

Server centos6.9, php7.1.21, apache2.2.15 ordinary web applications: index.php

var_export($_POST);
exit;

the data typed out in the result is: ( the array is converted to "Array"! )

array(
    "p1" => 1,
    "p2" => 2,
    "groups" => "Array"
)

but what I expect is:

array(
    "p1" => 1,
    "p2" => 2,
    "groups" => array(20,30)
)   

above, where is the problem with the use, or is it the problem of swoole_http_client itself?

if you do not call the addFile file, the result is normal. It is said in the swoole document that the general post is application/x-www-form-urlencoded, and will be converted to form-data, after using addFile. Is there a problem with swoole conversion?


look at the source code of swoole: https://github.com/swoole/swo.

        //post data
        if (Z_TYPE_P(post_data) == IS_ARRAY && php_swoole_array_length(post_data) > 0)
        {
            SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(post_data), key, keylen, keytype, value)
                if (HASH_KEY_IS_STRING != keytype)
                {
                    continue;
                }
                convert_to_string(value);
                n = snprintf(header_buf, sizeof(header_buf), SW_HTTP_FORM_DATA_FORMAT_STRING, (int)(sizeof(boundary_str) - 1),
                        boundary_str, keylen, key);
                swString_append_ptr(http_client_buffer, header_buf, n);
                //Z_STRVAL_Pvaluehttp_client_buffer
                swString_append_ptr(http_client_buffer, Z_STRVAL_P(value), Z_STRLEN_P(value));
                swString_append_ptr(http_client_buffer, ZEND_STRL("\r\n"));
            SW_HASHTABLE_FOREACH_END();

            //cleanup request body
            zend_update_property_null(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestBody") TSRMLS_CC);
        }
There is no recursive parsing of the multi-dimensional array in the

source code. Instead, the value is treated as a string, and the value is encapsulated in the request by calling the Z_STRVAL_P macro.

so your problem should be here. If the file is not uploaded, the call is

https://github.com/swoole/swo.

  if (php_swoole_array_length(post_data) > 0) //if it's an empty array, http build will fail
            {
                smart_str formstr_s = { 0 };
                // sw_http_build_query post
                char *formstr = sw_http_build_query(post_data, &len, &formstr_s TSRMLS_CC);
                if (formstr == NULL)
                {
                    swoole_php_error(E_WARNING, "http_build_query failed.");
                    return SW_ERR;
                }
                http_client_append_content_length(http_client_buffer, len);
                swString_append_ptr(http_client_buffer, formstr, len);
                smart_str_free(&formstr_s);
            }
You can see the post data encapsulated by the sw_http_build_query method in the

source code. This method encapsulates the php_url_encode_hash_ex method of PHP.

Menu