2012-06-12 6 views
6

मैं एक दूरस्थ फ़ाइल प्राप्त करने की कोशिश कर रहा हूं और इसे एक ही समय में उपयोगकर्ता को डाउनलोड करने के लिए मजबूर कर रहा हूं। मैं कोड पेस्ट नहीं कर सकता, कोड बहुत लंबा है। लेकिन कर्ल फ़ंक्शन काम करता है, लेकिन समस्या यह है कि यह तब तक कुछ भी नहीं डालता जब तक कि यह पहले रिमोट फ़ाइल नहीं प्राप्त करता है, तो यह उपयोगकर्ता को डाउनलोड करने के लिए मजबूर करता है।कर्ल दूरस्थ फ़ाइल और बल एक ही समय में डाउनलोड करें

मैं इस का उपयोग कर्ल बताने के लिए एक कॉलबैक

curl_setopt($ch, CURLOPT_READFUNCTION, 'readCallback'); 

अब वापस जाने के लिए मेरी readCallback समारोह में मैं इस है:

function readCallback($curl, $stream, $maxRead){ 
    $read = fgets($stream, $maxRead); 
    echo $read; 
    return $read; 
} 

लेकिन यह कुछ भी यह सिर्फ रिमोट को लाते समय तक इंतजार कर रहा है वापस नहीं करता है फ़ाइल समाप्त हो गई है

+0

आप * और * वापसी क्यों करते हैं? – ThiefMaster

+0

प्रतिध्वनि डाउनलोड किए गए हिस्सों को उपयोगकर्ता को आउटपुट करना है, और वापसी कर्ल के लिए है क्योंकि यह कॉलबैक – Danny

+0

से वापसी मूल्य पूछता है [संभवतः एक curl fetch से बाहर निकलें] [http://stackoverflow.com/questions/9491621/ बाहर निकलने के लिए बाहर निकलना) --- आप लिखने के लिए कॉलबैक की तलाश में हैं, एक कामकाजी उदाहरण के लिए यहां देखें (और आप इसे कैसे डिबग कर सकते हैं): [curl 'CURLOPT_WRITEFUNCTION' PHP उदाहरण] (http: //stackoverflow.com/a/9491855/367456) – hakre

उत्तर

6

इस प्रयास करें, तो वहाँ के रूप में है यह कर्ल का उपयोग फ़ाइल का कुल आकार पाने के लिए होगा तो उपयोगकर्ता के लिए यह प्रॉक्सी फ़ाइल का आंशिक हिस्सा डाउनलोड नहीं इंतजार कर्ल के लिए यह पहली बार डाउनलोड करने के लिए, मैं के साथ इस परीक्षण किया एक एवी, एमपी 4, एमपी 3 और एक exe, उम्मीद है कि यह मदद करता है:

<?php 
$file = 'http://example.com/somefile.mp3'; 
download($file,2000); 

/* 
Set Headers 
Get total size of file 
Then loop through the total size incrementing a chunck size 
*/ 
function download($file,$chunks){ 
    set_time_limit(0); 
    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-disposition: attachment; filename='.basename($file)); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Expires: 0'); 
    header('Pragma: public'); 
    $size = get_size($file); 
    header('Content-Length: '.$size); 

    $i = 0; 
    while($i<=$size){ 
     //Output the chunk 
     get_chunk($file,(($i==0)?$i:$i+1),((($i+$chunks)>$size)?$size:$i+$chunks)); 
     $i = ($i+$chunks); 
    } 

} 

//Callback function for CURLOPT_WRITEFUNCTION, This is what prints the chunk 
function chunk($ch, $str) { 
    print($str); 
    return strlen($str); 
} 

//Function to get a range of bytes from the remote file 
function get_chunk($file,$start,$end){ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $file); 
    curl_setopt($ch, CURLOPT_RANGE, $start.'-'.$end); 
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'chunk'); 
    $result = curl_exec($ch); 
    curl_close($ch); 
} 

//Get total size of file 
function get_size($url){ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_HEADER, true); 
    curl_setopt($ch, CURLOPT_NOBODY, true); 
    curl_exec($ch); 
    $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); 
    return intval($size); 
} 
?> 
+0

बेहतर प्रदर्शन के लिए भविष्य में 'readfile' और PHP स्ट्रीम संदर्भों का उपयोग करने पर विचार करें। आप इसे प्यार करेंगे। – hakre

+0

रिमोट फाइल से बात कर रहे थे, आईडी का मतलब यह है कि आप इस सवाल के बारे में एक घंटे के लिए अपना सिर लेने की कोशिश कर रहे हैं। :) –

+0

'readfile' PHP स्ट्रीम के साथ काम करता है, उदा। आप इसे रिमोट फाइलें ला सकते हैं। स्ट्रीम कॉपी स्ट्रीम को देखने के लिए कुछ भी लायक हो सकता है यदि PHP आउटपुट को सीधे स्ट्रीम करना संभव हो (जो मुझे लगता है कि यह भी संभव है)। हालांकि मुझे लगता है कि रीडफाइल अभी भी थोड़ा हल्का है। http://php.net/manual/en/book.stream.php; http://www.php.net/manual/en/stream.contexts.php और अंत में: http://ua2.php.net/manual/en/function.readfile.php – hakre

2

इस तरह कर्ल उपयोग करके देखें:

$ch = curl_init($url); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_HTTPGET, 1); 
curl_setopt($ch, CURLOPT_TIMEOUT, 60); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
$result = curl_exec($ch); 

$msg = new HttpMessage($result); 
return $msg->getBody(); 

वापसी मान तो अनुरोध की गई फ़ाइल की सामग्री है, जो आप तो उत्पादन कर सकते हैं है। तो कॉलबैक की कोई ज़रूरत नहीं है। HTTPMessage docs

+2

लेकिन यह तब तक इंतजार नहीं करता जब तक कि फ़ाइल कर्ल द्वारा डाउनलोड को समाप्त नहीं कर लेती है, फिर इसे आउटपुट करता है? – Danny

+0

हां यह करता है, लेकिन क्या वह नकारात्मक है? स्थानांतरण अविश्वसनीय रूप से तेज़ होना चाहिए क्योंकि यह एक सर्वर से दूसरे में है और शायद आपके क्लाइंट कनेक्शन से बहुत तेज है। और आप स्थानीय रूप से उन फ़ाइलों को कैश कर सकते हैं ताकि अगले फ़ाइल को अनुरोध करने वाले अगले उपयोगकर्ता को तेज प्रतिक्रिया मिले। क्या आपने दो तरीकों के डाउनलोड समय के अंतर को माप लिया है? – Michael

+0

अच्छी तरह से मैं उन्हें कैश करना चाहता हूं क्योंकि मैं इसे उपयोगकर्ता को प्रस्तुत करता हूं, क्योंकि मैं इसे स्वयं सर्वर पर डाउनलोड करता हूं, मैं इसे उपयोगकर्ता को दूसरी तरफ डाउनलोड करने देता हूं और जैसे ही मैं इसे डाउनलोड करता हूं, मैं इसे स्वयं कैश कर सकता हूं, और उपयोगकर्ता की गति और अधिक नहीं हो सकती है सर्वर से भी अगर यह है कि मैं इसे सीमित कर सकता हूं। – Danny

संबंधित मुद्दे