Отправка JSON строки через wp_remote_post()
Я создаю интеграцию с MailChimp, и им требуется POST-запрос с JSON-кодом.
Сейчас я использую этот код, который фактически работает:
$data = wp_remote_post($url, array(
'headers' => array('Content-Type' => 'application/json; charset=utf-8'),
'body' => json_encode($array_with_parameters),
'method' => 'POST'
));
Но он возвращает PHP предупреждение
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
Как этого избежать?
Я пробовал использовать просто массив в индексе 'body', но MailChimp возвращает ошибку парсинга JSON.

Попробуйте установить параметр data_format
в вашем запросе следующим образом:
$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',
));
Похоже, что формат по умолчанию может быть query
, в этом случае WordPress пытается форматировать данные с помощью http_build_query
, что вызывает проблемы, так как вы уже форматируете тело запроса как строку. Вот соответствующая проверка в 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, '&');
}
}
Поскольку ваша ошибка возникает в строке 507 файла wp-includes/Requests/Transport/cURL.php
, мы видим, что это основной вызов 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;
}

Теперь это в файлах wp-includes/Requests/src/Requests.php
и wp-includes/Requests/src/Transport/*.php
, но логика та же. Похоже, значение body
— это просто соглашение, код проверяет только то, что не является query
, но использование этого значения работает и будет наиболее надежным в будущем.
