File_get_contents () có cài đặt thời gian chờ không?


152

Tôi đang gọi một loạt các liên kết bằng cách sử dụng file_get_contents() phương thức trong một vòng lặp. Mỗi liên kết có thể mất hơn 15 phút để xử lý. Bây giờ, tôi lo lắng về việc PHPfile_get_contents() có thời gian chờ không?

Nếu có, nó sẽ hết thời gian với một cuộc gọi và chuyển sang liên kết tiếp theo. Tôi không muốn gọi liên kết tiếp theo mà không hoàn thành trước.

Vì vậy, xin vui lòng cho tôi biết liệu file_get_contents()có một khoảng thời gian chờ. Các tập tin có chứa file_get_contents()được đặt thành set_time_limit()không (không giới hạn).



Tôi đã trải qua hành vi tương tự (hết thời gian khi truy vấn URL trên cùng một "máy chủ") trong dự án PHP của Visual Studio sử dụng các công cụ PHP cho các tiện ích mở rộng của Visual Studio. Thêm thông tin ở đây .
Uwe Keim

Điều này cũng xảy ra khi sử dụng máy chủ PHP tích hợp để truy vấn một URL trên cùng một trang web , bởi vì đó là một máy chủ web đơn luồng.
Uwe Keim

Câu trả lời:


297

Thời gian chờ mặc định được xác định bằng default_socket_timeoutcài đặt ini , là 60 giây. Bạn cũng có thể thay đổi nó một cách nhanh chóng:

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

Một cách khác để đặt thời gian chờ, sẽ là sử dụng stream_context_createđể đặt thời gian chờ dưới dạng tùy chọn ngữ cảnh HTTP của trình bao bọc luồng HTTP đang sử dụng:

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

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

8
Bạn có thể cung cấp thông tin về cách đặt thời gian chờ cho url https không?
Vinay

11
Điều này không hoạt động hoàn hảo, nếu giá trị của bạn là 1200, thực tế là 2400. Tôi chỉ cần kiểm tra nó.
TomSawyer

15
default_socket_timeout, stream_set_timeout và stream_context_create hết thời gian chờ của mỗi dòng đọc / ghi, không phải toàn bộ thời gian chờ kết nối.
nghĩa tự làm

32

Như @diyism đã đề cập, " default_socket_timeout, stream_set_timeout và stream_context_create hết thời gian chờ của mỗi dòng đọc / ghi, không phải toàn bộ thời gian chờ kết nối. " Và câu trả lời hàng đầu của @stewe đã làm tôi thất bại.

Thay thế cho việc sử dụng file_get_contents, bạn luôn có thể sử dụng curlvới thời gian chờ.

Vì vậy, đây là một mã làm việc để gọi liên kết.

$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
Câu trả lời này đưa ra một cách tiếp cận khác để kiểm soát thời gian chờ kết nối (sử dụng fsockopenthay vì curl): stackoverflow.com/a/3690321/1869825
stevo

2
bạn nên đặt cả CURLOPT_CONNECTTIMEOUT và CURLOPT_TIMEOUT trong curl. Xem stackoverflow.com/a/27776164/1863432
bmus

2
Không phải là một phản hồi hợp lệ, câu hỏi dành cho "file_get_contents". Các phản ứng là tuyệt vời nhưng không phù hợp.
điện tử128

8

Đúng! Bằng cách chuyển một bối cảnh luồng trong tham số thứ ba:

Ở đây với thời gian chờ là 1 giây :

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

Nguồn trong phần bình luận của https://www.php.net/manual/en/feft.file-get-contents.php

Tùy chọn bối cảnh HTTP :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

Các bối cảnh khác: https://www.php.net/manual/en/context.php


1
Câu trả lời với 286 đại diện không hoạt động, nhưng bạn đã làm :)
VE7JRO

Thời gian chờ được đưa ra stream_context_createchỉ hoạt động cho thời gian chờ kết nối. Nếu máy chủ trả lời (gửi một số dữ liệu) trong khoảng thời gian chờ đã cho, nhưng sẽ mất mãi mãi để gửi phần còn lại của tải, thời gian chờ này không làm gián đoạn quá trình chuyển chậm.
z80crew

6

Điều đáng chú ý là nếu thay đổi default_socket_timeout một cách nhanh chóng, có thể hữu ích để khôi phục giá trị của nó sau khi gọi file_get_contents của bạn :

$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
nhưng bạn biết rằng ini_set không thiết lập mọi thứ vĩnh viễn, phải không? vì vậy về cơ bản 4 nửa kịch bản của bạn chỉ là vô dụng
Flash Thunder

2
@FlashThunder Không phải nếu có một cuộc gọi khác đến file_get_contents sau đó trong mã yêu cầu thời gian chờ trước đó. Khôi phục cài đặt đã thay đổi nhanh chóng cho một bit mã cụ thể sau khi mã đó được thực thi nói chung là cách thực hành tốt.
Leigh Bicknell

1
@FlashThunder nên khôi phục giá trị socket_timeout sau một cuộc gọi để các cuộc gọi tiếp theo đến cùng chức năng trong cùng thực thi tập lệnh sử dụng cài đặt chung.
Pascal Roget

1

Đối với tôi làm việc khi tôi thay đổi php.ini trong máy chủ của mình:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.