10

I'm building a mailchimp integration and they require a POST call with JSON code.

No, I'm using this code that actually works:

$data = wp_remote_post($url, array(
    'headers'   => array('Content-Type' => 'application/json; charset=utf-8'),
    'body'      => json_encode($array_with_parameters),
    'method'    => 'POST'
));

But, it returns a PHP warning

Warning: http_build_query(): Parameter 1 expected to be Array or Object. Incorrect value given in ../wp-includes/Requests/Transport/cURL.php on line 507

How to avoit it?

I've tried to just use the plain array in 'body' index but MailChimp returns a JSON parsing error.

  • 1
    Have you applied this patch to core? core.trac.wordpress.org/ticket/37700 – Otto Aug 26 '16 at 12:45
  • Interesting. Is a commercial plugin, then must work on any WP installation. But since seems to be a WP bug, for me is ok. Many thanks! – a-coder Aug 26 '16 at 14:05
7

Try setting the data_format parameter in your request like so:

$data = wp_remote_post($url, array(
    'headers'     => array('Content-Type' => 'application/json; charset=utf-8'),
    'body'        => json_encode($array_with_parameters),
    'method'      => 'POST',
    'data_format' => 'body',
));

It looks like the format may be defaulting to query, in which case WordPress attempts to format the data using http_build_query, which is giving you issues since you're already formatting the body as a string. Here's the relevant check in wp-includes/class-http.php:

if (!empty($data)) {
    $data_format = $options['data_format'];

    if ($data_format === 'query') {
        $url = self::format_get($url, $data);
        $data = '';
    }
    elseif (!is_string($data)) {
        $data = http_build_query($data, null, '&');
    }
}

Since your error is coming from line 507 of wp-includes/Requests/Transport/cURL.php, we can see that this is the root call to http_build_query:

protected static function format_get($url, $data) {
    if (!empty($data)) {
        $url_parts = parse_url($url);
        if (empty($url_parts['query'])) {
            $query = $url_parts['query'] = '';
        }
        else {
            $query = $url_parts['query'];
        }

        $query .= '&' . http_build_query($data, null, '&');
        $query = trim($query, '&');

        if (empty($url_parts['query'])) {
            $url .= '?' . $query;
        }
        else {
            $url = str_replace($url_parts['query'], $query, $url);
        }
    }
    return $url;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.