Hat file_get_contents () eine Timeout-Einstellung?

152

Ich rufe eine Reihe von Links mit der file_get_contents()Methode in einer Schleife auf. Die Verarbeitung jedes Links kann länger als 15 Minuten dauern. Jetzt mache ich mir Sorgen, ob PHPs file_get_contents()eine Zeitüberschreitung haben?

Wenn ja, tritt bei einem Anruf eine Zeitüberschreitung auf und es wird zum nächsten Link gewechselt. Ich möchte den nächsten Link nicht aufrufen, ohne dass der vorherige fertig ist.

Bitte sagen Sie mir, ob file_get_contents()es eine Zeitüberschreitung gibt. Die Datei, die das enthält, file_get_contents()wird set_time_limit()auf Null gesetzt (unbegrenzt).

Flora Clinton
quelle
Querverweis
Ich habe dasselbe Verhalten (Zeitüberschreitung beim Abfragen der URL auf demselben "Server") in einem Visual Studio-PHP-Projekt festgestellt, das die PHP-Tools für Visual Studio-Erweiterungen verwendet. Weitere Informationen hier .
Uwe Keim
Dies geschieht auch, wenn der integrierte PHP-Server zum Abfragen einer URL auf derselben Website verwendet wird , da es sich um einen Single-Threaded-Webserver handelt.
Uwe Keim

Antworten:

296

Das Standardzeitlimit wird durch die default_socket_timeoutIni-Einstellung definiert , die 60 Sekunden beträgt. Sie können es auch im laufenden Betrieb ändern:

ini_set('default_socket_timeout', 900); // 900 Seconds = 15 Minutes

Eine andere Möglichkeit, ein Zeitlimit festzulegen, besteht stream_context_createdarin, das Zeitlimit als HTTP-Kontextoptionen des verwendeten HTTP-Stream-Wrappers festzulegen:

$ctx = stream_context_create(array('http'=>
    array(
        'timeout' => 1200,  //1200 Seconds is 20 Minutes
    )
));

echo file_get_contents('http://example.com/', false, $ctx);
Stewe
quelle
8
Können Sie Informationen zum Festlegen des Zeitlimits für die https-URL geben?
Vinay
11
Dieses Ding funktioniert nicht perfekt, wenn Ihr Wert 1200 ist, ist es tatsächlich 2400. Ich teste es einfach.
TomSawyer
14
default_socket_timeout, stream_set_timeout und stream_context_create timeout sind das Timeout jeder Zeile zum Lesen / Schreiben, nicht das gesamte Verbindungszeitlimit.
DIYismus
32

Wie @diyism erwähnt hat, sind " default_socket_timeout, stream_set_timeout und stream_context_create timeout das Zeitlimit für jede Zeile zum Lesen / Schreiben, nicht das gesamte Verbindungszeitlimit. " Und die Top-Antwort von @stewe hat mich gescheitert.

Alternativ zur Verwendung file_get_contentskönnen Sie immer curleine Zeitüberschreitung verwenden.

Hier ist also ein Arbeitscode, der zum Aufrufen von Links funktioniert.

$url='http://example.com/';
$ch=curl_init();
$timeout=5;

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);

$result=curl_exec($ch);
curl_close($ch);
echo $result;
Randell
quelle
1
Diese Antwort gibt einen anderen Ansatz zur Steuerung des Verbindungszeitlimits ( fsockopenanstelle von curl): stackoverflow.com/a/3690321/1869825
stevo
2
Sie sollten sowohl CURLOPT_CONNECTTIMEOUT als auch CURLOPT_TIMEOUT in curl setzen. Siehe stackoverflow.com/a/27776164/1863432
bhelm
2
Ist keine gültige Antwort, ist die Frage für "file_get_contents". Die Resonanz ist großartig, aber unangemessen.
E-Info128
7

Ja! Durch Übergeben eines Stream-Kontexts im dritten Parameter:

Hier mit einer Zeitüberschreitung von 1s :

file_get_contents("https://abcedef.com", 0, stream_context_create(["http"=>["timeout"=>1]]));

Quelle im Kommentarbereich von https://www.php.net/manual/en/function.file-get-contents.php

HTTP-Kontextoptionen :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Andere Kontexte: https://www.php.net/manual/en/context.php

NVRM
quelle
1
Die Antwort mit 286 Wiederholungen hat nicht funktioniert, aber Ihre hat funktioniert :)
VE7JRO
Das in angegebene Zeitlimit gilt stream_context_createnur für das Verbindungszeitlimit. Wenn der Server innerhalb des angegebenen Zeitlimits antwortet (einige Daten sendet), es jedoch ewig dauert, den Rest seiner Nutzlast zu senden, unterbricht dieses Zeitlimit die langsame Übertragung nicht.
z80crew
6

Es ist erwähnenswert, dass bei Änderungen es nützlich sein kann, den Wert nach dem Aufruf von file_get_contents wiederherzustellen default_socket_timeout im laufenden Betrieb ändern :

$default_socket_timeout = ini_get('default_socket_timeout');
....
ini_set('default_socket_timeout', 10);
file_get_contents($url);
...
ini_set('default_socket_timeout', $default_socket_timeout);
Pascal Roget
quelle
1
aber du weißt, dass ini_set die Dinge nicht dauerhaft setzt, oder? Im Grunde genommen ist 4 Hälfte Ihres Skripts einfach nutzlos
Flash Thunder
2
@FlashThunder Nicht, wenn später im Code ein weiterer Aufruf von file_get_contents erfolgt, für den das vorherige Timeout erforderlich ist. Das Wiederherstellen von Einstellungen, die für ein bestimmtes Codebit im laufenden Betrieb geändert wurden, nachdem dieser Code ausgeführt wurde, ist im Allgemeinen eine gute Vorgehensweise.
Leigh Bicknell
1
@FlashThunder Es wird empfohlen, den Wert für socket_timeout nach einem Aufruf wiederherzustellen, damit nachfolgende Aufrufe derselben Funktion in derselben Skriptausführung globale Einstellungen verwenden.
Pascal Roget
1

Für mich arbeiten, wenn ich meine php.ini in meinem Host ändere:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
Max
quelle