file_get_contents () มีการตั้งค่าการหมดเวลาหรือไม่


152

ฉันกำลังเรียกใช้ชุดลิงก์โดยใช้file_get_contents()วิธีในลูป แต่ละลิงก์อาจใช้เวลาในการประมวลผลมากกว่า 15 นาที ตอนนี้ฉันกังวลว่า PHP file_get_contents()มีช่วงหมดเวลาหรือไม่

ถ้าใช่จะหมดเวลาด้วยการโทรและย้ายไปที่ลิงก์ถัดไป ฉันไม่ต้องการโทรไปที่ลิงค์ถัดไปหากไม่มีการตกแต่งก่อนหน้า

ดังนั้นโปรดบอกฉันว่าfile_get_contents()มีระยะหมดเวลาหรือไม่ ไฟล์ที่มีการfile_get_contents()ตั้งค่าset_time_limit()เป็นศูนย์ (ไม่ จำกัด จำนวน)


การอ้างอิง
โยง

ฉันเคยมีพฤติกรรมแบบเดียวกัน (หมดเวลาเมื่อสอบถาม URL บน "เซิร์ฟเวอร์" เดียวกัน) ภายในโครงการ Visual Studio PHP ที่ใช้เครื่องมือ PHP สำหรับส่วนขยาย Visual Studio ข้อมูลเพิ่มเติมที่นี่
Uwe Keim

สิ่งนี้เกิดขึ้นเมื่อใช้เซิร์ฟเวอร์ PHP ในตัวเพื่อค้นหา URL ในเว็บไซต์เดียวกันเพราะเป็นเว็บเซิร์ฟเวอร์เธรดเดี่ยว
Uwe Keim

คำตอบ:


298

การหมดเวลาเริ่มต้นถูกกำหนดโดยdefault_socket_timeoutการตั้งค่า iniซึ่งคือ 60 วินาที คุณสามารถเปลี่ยนได้ทันที:

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

อีกวิธีในการตั้งค่าการหมดเวลาจะเป็นการใช้stream_context_createการตั้งค่าการหมดเวลาเป็นตัวเลือกบริบท HTTPของwrapper กระแส HTTP ที่ใช้งานอยู่:

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

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

8
คุณสามารถให้ข้อมูลเกี่ยวกับวิธีตั้งค่าการหมดเวลาสำหรับ URL url ได้หรือไม่
Vinay

11
สิ่งนี้ไม่ทำงานอย่างสมบูรณ์ถ้าค่าของคุณคือ 1200 จริง ๆ แล้วมันคือ 2,400 ฉันแค่ทดสอบมัน
TomSawyer

15
default_socket_timeout, stream_set_timeout และ stream_context_create timeout เป็นค่าหมดเวลาทั้งหมดของทุกบรรทัดที่อ่าน / เขียนไม่ใช่การหมดเวลาเชื่อมต่อทั้งหมด
diyism

32

ตามที่ @diyism พูดถึง " default_socket_timeout, stream_set_timeout และ stream_context_create timeout นั้นเป็นการหมดเวลาของการอ่าน / เขียนทุกบรรทัดไม่ใช่การหมดเวลาเชื่อมต่อทั้งหมด " และคำตอบยอดนิยมโดย @stewe ทำให้ฉันล้มเหลว

ในฐานะที่เป็นทางเลือกในการใช้file_get_contentsคุณก็สามารถใช้curlกับหมดเวลา

ดังนั้นนี่คือรหัสการทำงานที่ใช้งานได้สำหรับการโทรลิงก์

$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
คำตอบนี้ให้วิธีการอื่นในการควบคุมการหมดเวลาเชื่อมต่อ (ใช้fsockopenแทนcurl): stackoverflow.com/a/3690321/1869825
stevo

2
คุณควรตั้งค่าทั้ง CURLOPT_CONNECTTIMEOUT และ CURLOPT_TIMEOUT ใน curl ดูstackoverflow.com/a/27776164/1863432
bhelm

2
ไม่ใช่คำตอบที่ถูกต้องคำถามนี้มีไว้สำหรับ "file_get_contents" คำตอบนั้นยอดเยี่ยม แต่ไร้ความสามารถ
e-info128

8

ใช่ โดยผ่านบริบทสตรีมในพารามิเตอร์ที่สาม:

ที่นี่ด้วยการหมดเวลา1 วินาที :

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

แหล่งที่มาในส่วนความคิดเห็นของhttps://www.php.net/manual/en/function.file-get-contents.php

ตัวเลือกบริบท HTTP :

method
header
user_agent
content
request_fulluri
follow_location
max_redirects
protocol_version
timeout

บริบทอื่น ๆ : https://www.php.net/manual/en/context.php


1
คำตอบที่มี 286 ตัวแทนไม่ทำงาน แต่คุณทำได้ :)
VE7JRO

การหมดเวลาที่กำหนดให้stream_context_createใช้ได้กับการหมดเวลาเชื่อมต่อเท่านั้น หากเซิร์ฟเวอร์ตอบกลับ (ส่งข้อมูลบางส่วน) ภายในระยะหมดเวลาที่กำหนด แต่ใช้เวลาตลอดไปในการส่งข้อมูลที่เหลืออยู่การหมดเวลานี้จะไม่ขัดขวางการถ่ายโอนช้า
z80crew

6

เป็นที่น่าสังเกตว่าถ้าเปลี่ยนdefault_socket_timeoutในทันทีมันอาจมีประโยชน์ในการกู้คืนค่าหลังจากเรียกใช้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
แต่คุณรู้ไหมว่า ini_set ไม่ได้ตั้งค่าอย่างถาวรใช่มั้ย โดยพื้นฐานแล้วสคริปต์ครึ่งหนึ่งของคุณไม่มีประโยชน์เลย
Flash Thunder

2
@FlashThunder ไม่ใช่ถ้ามีการเรียกไปยัง file_get_contents ในภายหลังในรหัสที่ต้องใช้การหมดเวลาก่อนหน้านี้ การตั้งค่าการคืนค่าเปลี่ยนไปอย่างรวดเร็วสำหรับรหัสบิตเฉพาะหลังจากที่ประมวลผลรหัสนั้นเป็นวิธีปฏิบัติที่ดีโดยทั่วไป
Leigh Bicknell

1
@FlashThunder มันเป็นวิธีปฏิบัติที่ดีในการคืนค่า socket_timeout หลังจากการโทรเพื่อให้การโทรที่ตามมาไปยังฟังก์ชั่นเดียวกันในการเรียกใช้สคริปต์เดียวกันใช้การตั้งค่าร่วม
ปาสกาล Roget

1

สำหรับฉันทำงานเมื่อฉันเปลี่ยน php.ini ในโฮสต์ของฉัน:

; Default timeout for socket based streams (seconds)
default_socket_timeout = 300
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.