Более быстрая альтернатива file_get_contents () - PullRequest
13 голосов
/ 18 апреля 2010

В настоящее время я использую file_get_contents () для отправки GET-данных в массив сайтов, но при выполнении страницы я получаю эту ошибку:

Неустранимая ошибка: превышено максимальное время выполнения 30 секунд

Все, что я действительно хочу, чтобы скрипт делал, это загружал веб-страницу, а затем уходил. Для полной загрузки каждой веб-страницы может потребоваться до 5 минут, и она мне не нужна для полной загрузки.

Вот что у меня сейчас есть:

        foreach($sites as $s) //Create one line to read from a wide array
        {
                file_get_contents($s['url']); // Send to the shells
        }

РЕДАКТИРОВАТЬ: Чтобы устранить путаницу, этот сценарий используется для запуска сценариев на других серверах, которые не возвращают данных.

РЕДАКТИРОВАТЬ: я сейчас пытаюсь использовать cURL, чтобы сделать трюк, установив тайм-аут в одну секунду, чтобы заставить его отправлять данные и затем останавливаться. Вот мой код:

        $ch = curl_init($s['url']); //load the urls
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); //Only send the data, don't wait.
        curl_exec($ch); //Execute
        curl_close($ch); //Close it off.

Возможно, я неправильно установил опцию. Я смотрю некоторые руководства, когда мы говорим. Просто даю вам обновление. Спасибо всем, кто помогает мне до сих пор.

РЕДАКТИРОВАТЬ: Ах, нашел проблему. Я использовал CURLOPT_CONNECTTIMEOUT вместо CURLOPT_TIMEOUT. Упс.

Однако сейчас сценарии не запускаются. Каждый из них использует ignore_user_abort (TRUE); поэтому я не могу понять проблему

Ха, поцарапай это. Работает сейчас. Большое спасибо всем

Ответы [ 6 ]

6 голосов
/ 18 апреля 2010

Есть много способов решить эту проблему.

Вы можете использовать cURL с его функциями curl_multi_ * для асинхронного выполнения запросов. Или используйте cURL обычным способом, но используя 1 в качестве лимита времени ожидания, поэтому он будет запрашивать и возвращать время ожидания, но запрос будет выполнен.

Если у вас не установлен cURL, вы можете продолжить использовать file_get_contents, но разветвлять процессы (не так круто, но работает), используя что-то вроде ZendX_Console_Process_Unix , чтобы избежать ожидания между каждым запросом.

2 голосов
/ 20 марта 2011

Как уже упоминал Франко, и я не уверен, что он был подхвачен, вы специально хотите использовать функции curl_multi, а не обычные функции curl. Это упаковывает несколько объектов curl в объект curl_multi и выполняет их одновременно, возвращая (или нет, в вашем случае) ответы по мере их поступления.

Пример на http://php.net/curl_multi_init

2 голосов
/ 18 апреля 2010

Re ваше обновление, что вам нужно только вызвать операция:

Вы можете попробовать использовать file_get_contents с таймаутом. Это привело бы к вызову удаленного сценария, но соединение было разорвано через n секунд (например, 1).

Если удаленный скрипт настроен таким образом, что он продолжает работать, даже если соединение прерывается (в PHP это будет ignore_user_abort), он должен работать.

Попробуйте. Если это не сработает, вы не сможете увеличить time_limit или использовать внешний исполняемый файл. Но из того, что вы говорите - вам просто нужно сделать запрос - это должно работать. Вы могли бы даже попытаться установить время ожидания на 0, но я бы не стал доверять.

С здесь :

<?php
$ctx = stream_context_create(array(
    'http' => array(
        'timeout' => 1
        )
    )
);
file_get_contents("http://example.com/", 0, $ctx);
?>

Чтобы быть справедливым, ответ Криса уже включает эту возможность: curl также имеет переключатель тайм-аута.

1 голос
/ 19 апреля 2010

Если загрузка удаленных страниц занимает до 5 минут, ваш файл file_get_contents будет сидеть и ждать эти 5 минут. Можно ли как-нибудь изменить удаленные сценарии, чтобы они превратились в фоновый процесс и выполняли там тяжелую обработку? Таким образом, ваше первоначальное попадание вернется почти сразу, и вам не придется ждать периода запуска.

Другая возможность состоит в том, чтобы выяснить, поможет ли запрос HEAD. HEAD не возвращает никаких данных, только заголовки, поэтому может быть достаточно запустить удаленные задания и не ожидать полного вывода.

1 голос
/ 18 апреля 2010

Я не совсем понимаю смысл вашего сценария. Но вот что вы можете сделать:

  1. Чтобы быстро избежать фатальной ошибки, вы можете просто добавить set_time_limit (120) в начале файла. Это позволит запустить скрипт в течение 2 минут. Конечно, вы можете использовать любое число, которое вы хотите, и 0 для бесконечного.
  2. Если вам просто нужно вызвать url, и вы не «заботитесь» о результате, вы должны использовать cUrl в асинхронном режиме. В этом случае любой вызов по URL не будет ждать до его завершения. И вы можете позвонить им всем очень быстро.

BR.

1 голос
/ 18 апреля 2010

это не file_get_contents (), который потребляет столько времени, а само сетевое соединение.
Не следует отправлять данные GET на массив сайтов, а создать rss и позволить им получать данные RSS.

...