File_get_contents () ha un'impostazione di timeout?


152

Sto chiamando una serie di collegamenti usando il file_get_contents()metodo in un ciclo. L'elaborazione di ciascun collegamento può richiedere più di 15 minuti. Ora, mi preoccupo se PHP file_get_contents()ha un periodo di timeout?

In caso affermativo, scadrà con una chiamata e passerà al collegamento successivo. Non voglio chiamare il collegamento successivo senza che quello precedente finisca.

Quindi, per favore dimmi se file_get_contents()ha un periodo di timeout. Il file che contiene il file_get_contents()è impostato set_time_limit()su zero (illimitato).



Ho riscontrato lo stesso comportamento (timeout durante la query dell'URL sullo stesso "server") all'interno di un progetto PHP di Visual Studio che utilizza le estensioni di PHP Tools per Visual Studio. Maggiori informazioni qui .
Uwe Keim,

Ciò accade anche quando si utilizza il server PHP integrato per eseguire una query di un URL sullo stesso sito Web , poiché si tratta di un server Web a thread singolo.
Uwe Keim,

Risposte:


299

Il timeout predefinito è definito da default_socket_timeoutini-setting , che è di 60 secondi. Puoi anche cambiarlo al volo:

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

Un altro modo per impostare un timeout, sarebbe utilizzare stream_context_createper impostare il timeout come opzioni di contesto HTTP del wrapper di flusso HTTP in uso:

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

echo file_get_contents('http://example.com/', false, $ctx);

8
Puoi fornire informazioni su come impostare il timeout per l'URL https?
Vinay,

11
questa cosa non funziona perfettamente, se il tuo valore è 1200, in realtà è 2400. Ho appena testato.
TomSawyer,

15
default_socket_timeout, stream_set_timeout e stream_context_create timeout sono tutti i timeout di ogni riga di lettura / scrittura, non l'intero timeout della connessione.
Diyismo,

32

Come accennato da @diyism, " default_socket_timeout, stream_set_timeout e stream_context_create timeout sono tutti i timeout di ogni riga di lettura / scrittura, non l'intero timeout della connessione. " E la risposta migliore di @stewe non mi è riuscita.

In alternativa all'utilizzo file_get_contents, è sempre possibile utilizzare curlcon un timeout.

Quindi ecco un codice funzionante che funziona per chiamare i collegamenti.

$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;

1
Questa risposta dà un altro approccio per il controllo del timeout di connessione (usando fsockopenal posto di curl): stackoverflow.com/a/3690321/1869825
Stevo

2
dovresti impostare CURLOPT_CONNECTTIMEOUT e CURLOPT_TIMEOUT in curl. Vedere stackoverflow.com/a/27776164/1863432
bhelm

2
Non è una risposta valida, la domanda è per "file_get_contents". La risposta è ottima ma inadeguata.
e-info128,

8

Sì! Passando un contesto di flusso nel terzo parametro:

Qui con un timeout di 1s :

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

Fonte nella sezione commenti di https://www.php.net/manual/en/function.file-get-contents.php

Opzioni di contesto HTTP :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Altri contesti: https://www.php.net/manual/en/context.php


1
La risposta con 286 rappresentanti non ha funzionato, ma la tua ha funzionato :)
VE7JRO,

Il timeout indicato stream_context_createfunziona solo per il timeout della connessione. Se il server risponde (invia alcuni dati) entro il timeout specificato, ma impiega un'eternità a inviare il resto del suo payload, questo timeout non interrompe il trasferimento lento.
z80crew

6

Vale la pena notare che se si modifica al volo default_socket_timeout , potrebbe essere utile ripristinarne il valore dopo la chiamata di file_get_contents :

$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);

1
ma sai che ini_set non imposta le cose in modo permanente, giusto? quindi in pratica 4 metà della tua sceneggiatura è semplicemente inutile
Flash Thunder

2
@FlashThunder Non se c'è un'altra chiamata a file_get_contents più avanti nel codice che richiede il timeout precedente. Il ripristino delle impostazioni modificate al volo per un determinato bit di codice dopo l'esecuzione del codice è generalmente una buona pratica.
Leigh Bicknell,

1
@FlashThunder è buona norma ripristinare il valore socket_timeout dopo una chiamata in modo che le chiamate successive alla stessa funzione nella stessa esecuzione dello script utilizzino le impostazioni globali.
Pascal Roget,

1

Per me lavoro quando cambio php.ini nel mio host:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.