PHP में कर्ल का टाइमआउट सेट करना


230

मैं PHP के माध्यम से एक eXist डेटाबेस पर एक कर्ल अनुरोध चला रहा हूँ। डेटासेट बहुत बड़ा है, और परिणामस्वरूप, XML प्रतिसाद को वापस करने के लिए डेटाबेस लगातार एक लंबी राशि लेता है। इसे ठीक करने के लिए, हमने एक कर्ल रिक्वेस्ट सेट की है, जिसे लंबे समय के लिए माना जाता है।

$ch = curl_init();
$headers["Content-Length"] = strlen($postString);
$headers["User-Agent"] = "Curl/1.0";

curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'admin:');
curl_setopt($ch,CURLOPT_TIMEOUT,1000);
$response = curl_exec($ch);
curl_close($ch);

हालाँकि, अनुरोध पूरा होने से पहले कर्ल अनुरोध लगातार समाप्त होता है (<1000 जब ब्राउज़र के माध्यम से अनुरोध किया जाता है)। क्या किसी को पता है कि यह कर्ल में टाइमआउट सेट करने का उचित तरीका है?

जवाबों:


346

प्रलेखन देखें: http://www.php.net/manual/en/function.curl-setopt.php

CURLOPT_CONNECTTIMEOUT- कनेक्ट करने की कोशिश करते हुए प्रतीक्षा करने के लिए सेकंड की संख्या। अनिश्चित काल तक प्रतीक्षा करने के लिए 0 का उपयोग करें।
CURLOPT_TIMEOUT- CURL फ़ंक्शन को निष्पादित करने की अनुमति देने के लिए सेकंड की अधिकतम संख्या।

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 
curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds

यह भी php स्क्रिप्ट स्वयं के समय निष्पादन को बढ़ाने के लिए मत भूलना:

set_time_limit(0);// to infinity for example

13
set_time_limit(0);यदि स्क्रिप्ट कंसोल पर चल रही है, तो आपको इसकी आवश्यकता नहीं है।
CONvid19

6
@PedroLobito आप जो उल्लेख करते हैं, वह cli पर php का डिफ़ॉल्ट विन्यास है, लेकिन यह संभव है कि इसे संशोधित किया गया हो।
चेरोविम

4
@cherouvim स्पष्ट रूप से यहाँ सही है (बस चलाने के लिए php -d max_execution_time=1 -r 'while(true){$r=1*1;}'या कार्रवाई में निरीक्षण करने के लिए कुछ है कि cli में एक जादू 'असीमित' झंडा नहीं है।
Wrikken

@Pedro लोबिटो की जरूरत नहीं है set_time_limit(0)अगर आप इसे लूप के अंदर इस्तेमाल नहीं कर रहे हैं।
विक्टर जोरास

58

हम्म, यह मुझे ऐसा लगता है जैसे CURLOPT_TIMEOUTकिसी भी cURL फ़ंक्शन को निष्पादित करने के लिए समय की मात्रा को परिभाषित करता है। मुझे लगता है कि आपको वास्तव में CURLOPT_CONNECTTIMEOUTइसके बजाय देखना चाहिए , क्योंकि यह कनेक्शन को पूरा करने के लिए प्रतीक्षा करने के लिए अधिकतम समय बताता है।


जबकि PHP में डॉक्स का कहना CURLOPT_TIMEOUTहै कि फ़ंक्शन को कितना समय लगता है, अंतर्निहित कर्ल लाइब्रेरी डॉक्स के बारे में यह कहना प्रतीत होता है कि अनुरोध कितना समय लेता है, जो कि एक दिलचस्प अंतर है - निश्चित नहीं है कि किस तरह से पढ़ना है!
फिडेलोपर

मुझे लगता है कि यहाँ सबसे अच्छी व्याख्या है: stackoverflow.com/questions/27776129/…
फिडेल्पर

33

इसके साथ एक विचित्र बात है जो कुछ लोगों के लिए प्रासंगिक हो सकती है ... PHP डॉक्स टिप्पणियों से।

यदि आप चाहते हैं कि CURL एक सेकंड से भी कम समय में समाप्त हो जाए, तो आप उपयोग कर सकते हैं CURLOPT_TIMEOUT_MS, हालांकि "यूनिक्स जैसी प्रणालियों" पर एक बग / "सुविधा" है, जो मान के तुरंत बाद libcurl का कारण बनता है यदि मान <1000 ms त्रुटि के साथ है / cURL त्रुटि (28): समय समाप्त हो गया था "। इस व्यवहार के लिए स्पष्टीकरण है:

"यदि मानक सिस्टम नाम रिज़ॉल्वर का उपयोग करने के लिए libcurl बनाया गया है, तो हस्तांतरण का वह भाग अभी भी एक सेकंड के न्यूनतम अनुमत टाइमआउट के साथ पूर्ण-सेकंड रिज़ॉल्यूशन का उपयोग करेगा।"

PHP डेवलपर्स के लिए इसका मतलब यह है "आप इस फ़ंक्शन का उपयोग पहले परीक्षण के बिना नहीं कर सकते, क्योंकि आप यह नहीं बता सकते हैं कि libcurl मानक सिस्टम नाम रिज़ॉल्वर का उपयोग कर रहा है (लेकिन आप इसे सुनिश्चित कर सकते हैं)"

समस्या यह है कि (Li ​​| U) nix पर, जब libcurl मानक नाम रिज़ॉल्वर का उपयोग करता है, तो SIGALRM नाम रिज़ॉल्यूशन के दौरान उठाया जाता है जो libcurl सोचता है कि टाइमआउट अलार्म है।

समाधान CURLOPT_NOSIGNAL का उपयोग करके संकेतों को अक्षम करना है। यहाँ एक उदाहरण स्क्रिप्ट है जो अनुरोध करता है कि आप 10 सेकंड की देरी का कारण बन सकते हैं ताकि आप टाइमआउट का परीक्षण कर सकें:

if (!isset($_GET['foo'])) {
    // Client
    $ch = curl_init('http://localhost/test/test_timeout.php?foo=bar');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
    $data = curl_exec($ch);
    $curl_errno = curl_errno($ch);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if ($curl_errno > 0) {
        echo "cURL Error ($curl_errno): $curl_error\n";
    } else {
        echo "Data received: $data\n";
    }
} else {
    // Server
    sleep(10);
    echo "Done.";
}

से http://www.php.net/manual/en/function.curl-setopt.php#104597


नमस्कार, यह कोड काम करता है लेकिन स्रोत फ़ाइल 7MB है और यह मुझे केवल 52KB डाउनलोड करता है, क्या गलत हो सकता है? URL कुछ ऐसा है जैसे webserver.tld / folder / download /…
Muflix

@Simon पूर्व आप कृपया मेरी मदद कर सकते हैं stackoverflow.com/questions/30861112/…
नाथन श्रीवी

यह ध्यान दिया जाना चाहिए कि आप इस स्क्रिप्ट के साथ टाइमआउट त्रुटि की उम्मीद कर रहे हैं
kmoney12

30

आपका कोड 1000 सेकंड का समय निर्धारित करता है । मिलीसेकंड के लिए, का उपयोग करें CURLOPT_TIMEOUT_MS


13

आपको अपने और फ़ाइल के बीच के समय के बारे में सुनिश्चित करने की आवश्यकता होगी। इस मामले में PHP और कर्ल।

कर्ल को यह बताने के लिए कि जब कोई हस्तांतरण अभी भी सक्रिय नहीं है, तो आपको इसके बजाय सेट CURLOPT_TIMEOUTकरना होगा ।01000

curl_setopt($ch, CURLOPT_TIMEOUT, 0);

PHP में, फिर से, आपको समय सीमा को हटा देना चाहिए या PHP को स्वयं (डिफ़ॉल्ट रूप से 30 सेकंड के बाद) कर्ल के अनुरोध पर स्क्रिप्ट को मार देगा। यह अकेले आपके मुद्दे को ठीक करना चाहिए
इसके अतिरिक्त, यदि आपको डेटा अखंडता की आवश्यकता है, तो आप उपयोग करके सुरक्षा की एक परत जोड़ सकते हैं ignore_user_abort:

# The maximum execution time, in seconds. If set to zero, no time limit is imposed.
set_time_limit(0);

# Make sure to keep alive the script when a client disconnect.
ignore_user_abort(true);

एक ग्राहक वियोग स्क्रिप्ट के निष्पादन को बाधित करेगा और संभवतः डेटा को नुकसान पहुंचाएगा,
जैसे। गैर-संक्रमणकालीन डेटाबेस क्वेरी, एक कॉन्फिग फ़ाइल का निर्माण, ecc।, जबकि आपके मामले में यह एक आंशिक फ़ाइल डाउनलोड करेगा ... और आप इस बारे में परवाह कर सकते हैं या नहीं।

इस पुराने प्रश्न का उत्तर दे रहा है क्योंकि यह धागा इंजन खोजों में सबसे ऊपर है CURL_TIMEOUT


8

आप ब्राउज़र से अनुरोध नहीं चला सकते हैं, यह प्रतिक्रिया देने के लिए CURL अनुरोध को चलाने वाले सर्वर की प्रतीक्षा करेगा। ब्राउज़र संभवत: 1-2 मिनट में समाप्त हो रहा है, डिफ़ॉल्ट नेटवर्क टाइमआउट।

आपको इसे कमांड लाइन / टर्मिनल से चलाने की आवश्यकता है।


2
+1 - टाइमआउट शायद बाहरी रूप से कर्ल है। आप वास्तव में समय-समय पर कुछ सुनिश्चित करने के लिए ब्राउज़र टाइमआउट के आसपास काम कर सकते हैं; ब्राउज़र आमतौर पर हर बार जब वे अधिक डेटा प्राप्त करते हैं तो अपना टाइमआउट रीसेट कर लेते हैं। लेकिन वह हैक है; CLI के माध्यम से चलना (लगभग?) हमेशा बेहतर होता है।
फ्रैंक किसान

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.