Использование wp_remote_get для получения собственного URL на локальном сервере
У меня есть сайт в локальной разработке на test:8888, и я пытаюсь заставить работать следующий код в файле functions.php.
$response = wp_remote_get( 'test:8888/?p=1' );
print_r($response);
К сожалению, это выводит:
WP_Error Object ( [errors] => Array ( [http_request_failed] => Array ( [0] => A valid URL was not provided. ) ) [error_data] => Array ( ) )
Возможно ли запрашивать собственный URL при разработке на localhost?

Таймаут рекламы
Вы можете обойти таймаут, используя фильтр
add_filter( 'http_request_timeout', 'wpse35826_timeout_extd' );
function wpse35826_timeout_extd( $time )
{
// Таймаут по умолчанию равен 5
return 10;
}
Выбор правильного протокола/схемы
О проблеме с протоколом/схемой: если это ваша локальная установка, вы можете использовать условие.
function wpse35826_remote_get( $args )
{
$protocol = is_SSL() ? 'https://' : 'http://';
$response = wp_remote_get( "{$protocol}test:8888/?p=1" );
if ( is_wp_error( $response ) )
return "{$response->get_error_code()}: {$response->get_error_message()}";
return print htmlspecialchars( var_export( $response, true ) );
}
// Инициируем запрос
wpse35826_remote_get();
Если вы делаете запросы к вашему собственному локальному серверу, то могут возникнуть проблемы с проверкой SSL. WordPress использует фильтр для управления этой настройкой:
add_filter( 'https_local_ssl_verify', '__return_false' );
Этот фильтр не применяется(!) для локальных серверов, делающих запросы к серверам в интернете. Для внешних серверов используйте следующий фильтр:
add_filter( 'https_ssl_verify', '__return_false' );
Проблемы с локальными запросами
Также могут возникнуть проблемы с блокировкой локальных запросов:
add_filter( 'block_local_requests', '__return_false' );
Другие факторы, которые могут влиять на возможность выполнения локальных запросов — неправильно заданные константы в файле wp-config.php
:
WP_HTTP_BLOCK_EXTERNAL
// Если определена WP_HTTP_BLOCK_EXTERNAL, вы можете добавить хосты, которые не должны блокироваться.
WP_ACCESSIBLE_HOSTS
Если вы используете прокси:
// Позволяет определить адреса, которые не должны проходить через прокси.
// Ядро WordPress устанавливает обход как для www, так и для non-www версий.
// get_option('siteurl') и localhost по умолчанию обходятся.
WP_PROXY_BYPASS_HOSTS
Нет cURL?
Если cURL
недоступен и вы не передаете данные в файл, WordPress переключится на использование Fsocketopen()
. Из комментария в ядре, который хорошо это объясняет:
Fsocketopen имеет проблемы с 'localhost' при использовании IPv6 в определенных версиях PHP. Он пытается подключиться к ::1, что не работает, если сервер не настроен для этого. Для совместимости всегда подключайтесь к IPv4-адресу.
Суть в том, что WordPress вмешивается только если у нас указано имя хоста localhost
. В этом случае хост для fsocketopen будет установлен в '127.0.0.1'
.

'test:8888/?p=1' не является допустимым URL.
Попробуйте 'http://test:8888/?p=1' вместо этого.

который выдает этот объект WP_Error ( [errors] => Array ( [http_request_failed] => Array ( [0] => Операция завершилась по таймауту через 5001 миллисекунду, получено 0 байт ) ) [error_data] => Array ( ) )

Является ли "test:8888" действительным URL на вашей машине? Нет проблем с доступом к локальным ресурсам, но эти ресурсы должны реально существовать и быть доступными.

У меня была похожая проблема, и я решил её следующим образом:
function wpse35826_remote_get() {
// Получаем удалённый контент по указанному URL
$response = wp_remote_get( 'http://test:8888/?p=1' );
// Выводим ответ сервера
echo 'Ответ сервера:<pre>';
print_r($response);
echo '</pre>';
}
// Добавляем функцию к хуку admin_init
add_action('admin_init','wpse35826_remote_get');

Я думаю, у вас на самом деле две проблемы. Ответ Отто решил вашу первую проблему, потому что отсутствие http://
делало URL недействительным, из-за чего вы получали ошибку A valid URL was not provided
.
Вторая проблема — это нечто другое и не связанное с первой, и она вызывает ошибку Operation timed out
. Не могу сказать точно без просмотра всего вашего кода, но предполагаю, что вызов wp_remote_get()
находится внутри функции обратного вызова, зарегистрированной на хуке, который также срабатывает на странице, запрашиваемой через wp_remote_get()
. Такая ситуация создает рекурсивный цикл, который в итоге приводит к таймауту.
Вам нужно убедиться, что вызов wp_remote_get()
не выполняется на запрашиваемой странице. Это можно сделать, зарегистрировав функцию обратного вызова на другом хуке или используя условные теги, чтобы избежать вызова wp_remote_get()
на запрашиваемой странице.
Вот пример, предполагая, что вы всегда вызываете неадминистративные страницы:
if( !is_admin() )
return;
$response = wp_remote_get( 'http://test:8888/?p=1' );
print_r($response);

add_filter( 'http_request_host_is_external', '__return_true' );
add_filter( 'http_request_args', function ( $args ) {
$args['reject_unsafe_urls'] = false;
return $args;
}, 999 );
add_filter( 'https_local_ssl_verify', '__return_false' );
add_filter( 'block_local_requests', '__return_false' );
Попробуйте любой из этих фильтров... у меня сработало
