В PHP я могу читать метаданные timed_out из контекста HTTP, как если бы я использовал поток?
Я использую file_get_contents()
с контекстом, чтобы установить значение времени ожидания. Вот мой тестовый скрипт:
<?php
$options = ['http' => ['timeout' => 1, ]];
$context = stream_context_create($options);
$url = 'http://localhost:10000/wait.php';
$response = file_get_contents($url, false, $context);
echo $response; // Empty
print_r($http_response_header);
print_r(stream_context_get_options($context));
#print_r(stream_get_meta_data($context)); // Only works with streams, not contexts
print_r(stream_context_get_params($context));
В этой демонстрации я прошу PHP подождать не более секунды. Чтобы заставить его потерпеть неудачу, я использую это wait.php
скрипт на стороне веб-сервера:
<?php
sleep(2);
?>
<html>
<body>
Hello
</body>
</html>
Результат запуска сценария извлечения:
php fetch.php
PHP Warning: file_get_contents(http://localhost:10000/wait.php): failed to open stream: HTTP request failed! in .../fetch.php on line 6
Array
(
[0] => HTTP/1.0 200 OK
[1] => Host: localhost:10000
[2] => Connection: close
[3] => X-Powered-By: PHP/7.0.22-0ubuntu0.16.04.1
[4] => Content-type: text/html; charset=UTF-8
)
Array
(
[http] => Array
(
[timeout] => 1
)
)
Array
(
[options] => Array
(
[http] => Array
(
[timeout] => 1
)
)
)
Я хотел бы найти способ определить, истекло ли время операции HTTP. Предупреждение дает мне сообщение "не удалось открыть поток: не удалось выполнить HTTP-запрос", но это не очень удобно. Единственный другой вывод - это параметры контекста, которые я сам установил.
Идеальным способом было бы запустить что-то вроде stream_get_meta_data()
но это работает только в потоках, а не в контекстах. Так что я мог бы использовать fopen()
называть конечную точку, но я представляю file_get_contents()
обычно оптимизируется немного лучше, чем ручное извлечение содержимого конечных точек в чанках, поэтому я хотел бы сейчас придерживаться моего текущего подхода.
В настоящее время, если я получу пустое тело, и если истекшее время похоже на настройку тайм-аута, я сгенерирую исключение тайм-аута. Однако это не очень аккуратно - можно ли вместо этого получить флаг метаданных по тайм-ауту?