File_get_contents () a-t-il un paramètre de délai d'expiration?

152

J'appelle une série de liens en utilisant la file_get_contents()méthode en boucle. Le traitement de chaque lien peut prendre plus de 15 minutes. Maintenant, je me demande si PHP file_get_contents()a un délai d'expiration?

Si oui, il expirera avec un appel et passera au lien suivant. Je ne veux pas appeler le lien suivant sans que le précédent ne soit terminé.

Alors, dites-moi s'il y file_get_contents()a un délai d'expiration. Le fichier qui contient le file_get_contents()est mis set_time_limit()à zéro (illimité).

Flora Clinton
la source
J'ai connu le même comportement (délai d'expiration lors de la requête d'URL sur le même "serveur") dans un projet PHP Visual Studio qui utilise les outils PHP pour les extensions Visual Studio. Plus d'informations ici .
Uwe Keim
Cela se produit également lorsque vous utilisez le serveur PHP intégré pour interroger une URL sur le même site Web , car il s'agit d'un serveur Web à un seul thread.
Uwe Keim

Réponses:

299

Le délai d'expiration par défaut est défini par default_socket_timeoutini-setting , qui est de 60 secondes. Vous pouvez également le changer à la volée:

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

Une autre façon de définir un délai d'expiration serait de l'utiliser stream_context_createpour définir le délai d'expiration en tant qu'options de contexte HTTP du wrapper de flux HTTP utilisé:

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

echo file_get_contents('http://example.com/', false, $ctx);
ragoût
la source
8
Pouvez-vous donner des informations sur la façon de définir le délai d'expiration pour l'URL https?
Vinay
11
cette chose ne fonctionne pas parfaitement, si votre valeur est de 1200, c'est en fait 2400. Je viens de le tester.
TomSawyer
15
default_socket_timeout, stream_set_timeout et stream_context_create timeout correspondent au délai d'expiration de chaque ligne en lecture / écriture, et non au délai d'expiration de la connexion.
diyism
32

Comme @diyism l'a mentionné, " default_socket_timeout, stream_set_timeout et stream_context_create timeout sont tous les délais d'expiration de chaque ligne en lecture / écriture, pas tout le délai d'expiration de la connexion. " Et la réponse principale de @stewe m'a échoué.

Comme alternative à l'utilisation file_get_contents, vous pouvez toujours utiliser curlavec un délai d'expiration.

Voici donc un code fonctionnel qui fonctionne pour appeler des liens.

$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
la source
1
Cette réponse donne une autre approche pour contrôler le délai de connexion (en utilisant fsockopenau lieu de curl): stackoverflow.com/a/3690321/1869825
stevo
2
vous devez définir à la fois CURLOPT_CONNECTTIMEOUT et CURLOPT_TIMEOUT dans curl. Voir stackoverflow.com/a/27776164/1863432
bhelm
2
N'est pas une réponse valide, la question est pour "file_get_contents". La réponse est excellente mais inappropriée.
e-info128
8

Oui! En passant un contexte de flux dans le troisième paramètre:

Ici avec un timeout de 1s :

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

Source dans la section commentaires de https://www.php.net/manual/en/function.file-get-contents.php

Options de contexte HTTP :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Autres contextes: https://www.php.net/manual/en/context.php

NVRM
la source
1
La réponse avec 286 représentants n'a pas fonctionné, mais la vôtre l'a fait :)
VE7JRO
Le délai indiqué dans stream_context_createne fonctionne que pour le délai de connexion. Si le serveur répond (envoie des données) dans le délai imparti, mais prend une éternité pour envoyer le reste de sa charge utile, ce délai n'interrompt pas le transfert lent.
z80crew le
6

Il est à noter que si vous modifiez default_socket_timeout à la volée, il peut être utile de restaurer sa valeur après votre appel 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);
Pascal Roget
la source
1
mais vous savez que ini_set ne règle pas les choses de façon permanente, non? donc fondamentalement 4 la moitié de votre script est tout simplement inutile
Flash Thunder
2
@FlashThunder Pas s'il y a un autre appel à file_get_contents plus tard dans le code qui nécessite le délai d'expiration précédent. La restauration des paramètres modifiés à la volée pour un morceau de code spécifique après l'exécution de ce code est généralement une bonne pratique.
Leigh Bicknell
1
@FlashThunder, il est conseillé de restaurer la valeur socket_timeout après un appel afin que les appels suivants à la même fonction dans la même exécution de script utilisent les paramètres globaux.
Pascal Roget
1

Pour moi, je travaille lorsque je change mon php.ini dans mon hôte:

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