Ошибка таймаута при успешном выполнении wp_remote_post
Что я пытаюсь сделать: Передаю POST-данные с помощью wp_remote_post.
foreach ( $articles as $article_id ) {
$postarray = array(
'method' => 'POST',
'timeout' => 5,
'redirection' => 5,
'httpversion' => '1.0',
'blocking' => true,
'headers' => array(),
'body' => array(
'article_id' => $article_id
),
'cookies' => array()
);
$response = wp_remote_post($url, $postarray);
if ( is_wp_error($response) ) {
$error_message = $response->get_error_message();
echo $error_message;
} else {
// остальная часть моего кода здесь
}
}
Я работаю с 20+ постами за один вызов. Каждый раз после завершения цикла я получаю это сообщение об ошибке:
"Операция завершена по таймауту через 5001 миллисекунд, получено 0 байт"
Странная вещь: данные фактически получены и успешно сохранены на целевом сервере $url
.
Может кто-нибудь подсказать, куда смотреть, чтобы избежать этого сообщения об ошибке?
Ссылка: wp_remote_post

Вы можете установить таймаут напрямую в аргументах $args
функции wp_remote_post()
, как показано в этом примере с developer.wordpress.org:
$response = wp_remote_post( $url, array(
'method' => 'POST',
'timeout' => 45,
'redirection' => 5,
'httpversion' => '1.0',
'blocking' => true,
'headers' => array(),
'body' => array(
'username' => 'bob',
'password' => '1234xyz'
),
'cookies' => array()
)
);
if ( is_wp_error( $response ) ) {
$error_message = $response->get_error_message();
echo "Произошла ошибка: $error_message";
} else {
echo 'Ответ:<pre>';
print_r( $response );
echo '</pre>';
}
Еще один важный момент: в этом примере таймаут установлен на 45 секунд, но во многих случаях это превысит лимит max_execution_time
в PHP, и вы получите ошибку. Но на этот раз это будет фатальная ошибка PHP (500), а не HTTP-ошибка от WordPress (так что ситуация даже ухудшится!).
Эту проблему можно решить, установив max_execution_time
в вашем php.ini. Или, если у вас не включен режим safe_mode
(что маловероятно на продакшн-сервере), можно попытаться установить это значение программно в коде, как показано ниже:
$timeout = 45;
if ( ! ini_get( 'safe_mode' ) ){
set_time_limit( $timeout + 10 );
}
$response = wp_remote_post( $url, array(
'timeout' => $timeout
) );
Здесь я установил PHP-таймаут на 10 секунд больше, чем HTTP-таймаут, просто для надежности.
Также будет хорошей практикой вернуть таймаут к его исходному значению, которое, скорее всего, можно получить через ini_get( 'max_execution_time' );

После того, как сообщение об ошибке довольно долго раздражало меня на экране, я нашел способ решить эту проблему.
Да, это проблема с таймаутом, и кодекс мне не особо помог. Поэтому я попробовал другой подход, установив фильтр:
add_filter( 'http_request_timeout', 'wp9838c_timeout_extend' );
function wp9838c_timeout_extend( $time )
{
// Таймаут по умолчанию равен 5
return 10;
}
Надеюсь, это послужит дополнительным примером для кого-то в будущем.

Всегда здорово, если ты находишь решение самостоятельно :-). Большое спасибо за то, что поделился своим решением. Не забудь вернуться, когда ограничение будет снято, и принять свой собственный ответ.
