Отправка JSON строки через wp_remote_post()

26 авг. 2016 г., 14:52:55
Просмотры: 42.3K
Голосов: 27

Я создаю интеграцию с 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.

2
Комментарии

Вы применили этот патч к ядру? https://core.trac.wordpress.org/ticket/37700

Otto Otto
26 авг. 2016 г. 15:45:31

Интересно. Если это коммерческий плагин, то он должен работать на любой установке WP. Но раз это похоже на баг WordPress, то для меня всё ок. Большое спасибо!

a-coder a-coder
26 авг. 2016 г. 17:05:07
Все ответы на вопрос 1
2
36

Попробуйте установить параметр 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;
}
31 авг. 2018 г. 22:12:29
Комментарии

Спасение! Идеальный ответ.

Suraj Lulla Suraj Lulla
11 апр. 2022 г. 07:13:32

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

Walf Walf
10 мая 2023 г. 07:29:03