Apakah file_get_contents () memiliki pengaturan waktu habis?

152

Saya memanggil serangkaian tautan menggunakan file_get_contents()metode ini dalam satu lingkaran. Setiap tautan mungkin membutuhkan waktu lebih dari 15 menit untuk diproses. Sekarang, saya khawatir tentang apakah PHP file_get_contents()memiliki periode waktu habis?

Jika ya, itu akan habis dengan panggilan dan pindah ke tautan berikutnya. Saya tidak ingin memanggil tautan berikutnya tanpa yang sebelumnya selesai.

Jadi, tolong beri tahu saya apakah file_get_contents()ada periode waktu habis. File yang berisi file_get_contents()diatur set_time_limit()ke nol (tidak terbatas).

Flora Clinton
sumber
Saya telah mengalami perilaku yang sama (batas waktu ketika menanyakan URL pada "server" yang sama) di dalam proyek Visual Studio PHP yang menggunakan Alat PHP untuk ekstensi Visual Studio. Informasi lebih lanjut di sini .
Uwe Keim
Ini terjadi juga ketika menggunakan server PHP bawaan untuk menanyakan URL di situs web yang sama , karena ini adalah server web single-threaded.
Uwe Keim

Jawaban:

297

Batas waktu default ditentukan oleh default_socket_timeoutpengaturan-awal , yaitu 60 detik. Anda juga dapat mengubahnya dengan cepat:

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

Cara lain untuk mengatur batas waktu, adalah dengan menggunakan stream_context_createuntuk mengatur batas waktu sebagai opsi konteks HTTP dari pembungkus aliran HTTP yang digunakan:

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

echo file_get_contents('http://example.com/', false, $ctx);
pelayan
sumber
8
Bisakah Anda memberikan info tentang cara mengatur batas waktu untuk https url?
Vinay
11
hal ini tidak berfungsi dengan baik, jika nilai Anda adalah 1200, sebenarnya adalah 2400. saya hanya mengujinya.
TomSawyer
15
default_socket_timeout, stream_set_timeout, dan stream_context_create timeout adalah semua timeout dari setiap baris baca / tulis, bukan seluruh koneksi timeout.
diyism
32

Seperti @diyism menyebutkan, " default_socket_timeout, stream_set_timeout, dan stream_context_create timeout adalah semua timeout dari setiap baris baca / tulis, bukan seluruh koneksi timeout. " Dan jawaban teratas oleh @stewe telah mengecewakan saya.

Sebagai alternatif untuk menggunakan file_get_contents, Anda selalu dapat menggunakan curldengan batas waktu.

Jadi, inilah kode yang berfungsi untuk memanggil tautan.

$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
sumber
1
Jawaban ini memberikan pendekatan lain untuk mengendalikan batas waktu koneksi (menggunakan fsockopenbukan curl): stackoverflow.com/a/3690321/1869825
stevo
2
Anda harus menetapkan CURLOPT_CONNECTTIMEOUT dan CURLOPT_TIMEOUT dalam ikal. Lihat stackoverflow.com/a/27776164/1863432
bhelm
2
Bukan tanggapan yang valid, pertanyaannya adalah untuk "file_get_contents". Responsnya bagus tetapi tidak tepat.
e-info128
8

Iya! Dengan melewatkan konteks aliran di parameter ketiga:

Di sini dengan batas waktu 1s :

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

Sumber di bagian komentar https://www.php.net/manual/en/function.file-get-contents.php

Opsi konteks HTTP :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Konteks lain: https://www.php.net/manual/en/context.php

NVRM
sumber
1
Jawaban dengan 286 perwakilan tidak bekerja, tetapi Anda punya :)
VE7JRO
Batas waktu yang diberikan stream_context_createhanya berfungsi untuk batas waktu koneksi. Jika server membalas (mengirim beberapa data) dalam batas waktu yang diberikan, tetapi membutuhkan waktu selamanya untuk mengirim sisa muatannya, batas waktu ini tidak mengganggu transfer yang lambat.
z80crew
6

Perlu dicatat bahwa jika mengubah default_socket_timeout dengan cepat, mungkin berguna untuk mengembalikan nilainya setelah panggilan file_get_contents Anda :

$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
sumber
1
tetapi Anda tahu bahwa ini_set tidak mengatur hal-hal secara permanen, bukan? jadi pada dasarnya 4 setengah dari skrip Anda tidak berguna
Flash Thunder
2
@FlashThunder Tidak jika ada panggilan lain ke file_get_contents nanti dalam kode yang memerlukan batas waktu sebelumnya. Mengembalikan pengaturan yang diubah dengan cepat untuk sedikit kode tertentu setelah kode itu dijalankan umumnya merupakan praktik yang baik.
Leigh Bicknell
1
@FlashThunder adalah praktik yang baik untuk mengembalikan nilai socket_timeout setelah panggilan sehingga panggilan berikutnya ke fungsi yang sama dalam eksekusi skrip yang sama menggunakan pengaturan global.
Pascal Roget
1

Bagi saya bekerja ketika saya mengubah php.ini di host saya:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
Maks
sumber