URL से सर्वर पर फ़ाइल डाउनलोड करें


341

खैर, यह एक बहुत सरल लगता है, और यह है। एक फ़ाइल को अपने सर्वर पर डाउनलोड करने के लिए आपको बस इतना करना है:

file_put_contents("Tmpfile.zip", file_get_contents("http://someurl/file.zip"));

केवल एक समस्या है। अगर आपके पास एक बड़ी फाइल है, तो 100mb की तरह क्या होगा। फिर, आप स्मृति से बाहर चलेंगे, और फ़ाइल को डाउनलोड करने में सक्षम नहीं होंगे।

जैसा कि मैं चाहता हूं कि फाइल को डिस्क पर लिखने का एक तरीका है जैसा कि मैं इसे डाउनलोड कर रहा हूं। इस तरह, मैं बड़ी फ़ाइलों को डाउनलोड कर सकता हूं, बिना मेमोरी समस्याओं के।


4
यह आपके सर्वर कॉन्फ़िगरेशन में सेट है, PHP वास्तव में इसके आस-पास नहीं पहुंच सकता है, जहां तक ​​मुझे पता है (एक प्रत्यक्ष .ini संपादन को छोड़कर)
बेन

जवाबों:


494

PHP 5.1.0 के बाद से, पैरामीटर के file_put_contents()रूप में एक स्ट्रीम-हैंडल पास करके टुकड़ा-दर-टुकड़ा लिखने का समर्थन करता है $data:

file_put_contents("Tmpfile.zip", fopen("http://someurl/file.zip", 'r'));

मैनुअल से:

यदि डेटा [वह दूसरा तर्क है] एक स्ट्रीम संसाधन है, तो उस स्ट्रीम के शेष बफ़र को निर्दिष्ट फ़ाइल में कॉपी किया जाएगा। यह उपयोग के साथ समान है stream_copy_to_stream()

( साभार हक्रे ।)


4
यह मेरी पहली पसंद नहीं होगी। यदि allow_fopen_url Offphp.ini (सुरक्षा के लिए अच्छा विचार) में सेट किया गया है, तो आपकी स्क्रिप्ट टूट जाएगी।
कृपया

4
@idealmachine मुझे लगता है file_get_contents()कि अगर मामला होता तो या तो काम नहीं होता (देखें ओपी)।
एलेक्स

10
@geoff मैं विशिष्ट था, मैंने उस फ़ंक्शन का उल्लेख किया जो आप चाहते थे। आप जो चाहते थे वह कोई आपके लिए कोड लिखने के लिए था - लेकिन मुझे यकीन है कि आपने इसे स्वयं करना सीख लिया है। इसके अलावा, अगर हम एक-दूसरे के SO इंटरैक्शन पर टिप्पणी करने जा रहे हैं - तो कृपया कुछ और उत्तर स्वीकार करें :)
एलेक्स

@alex: कृपया संपादन देखें, शामिल करने के लिए स्वतंत्र महसूस करें। मुझे पता है कि जब मैं इस टिप्पणी को यहाँ हटा सकता हूँ।
हैकर

4
अधिकांश मामलों में 'बी' ध्वज का भी उपयोग किया जाना चाहिए fopen; छवियों और अन्य गैर सादे पाठ फ़ाइलों के प्रतिकूल प्रभाव को रोकता है।
वेन वेइबल

132
private function downloadFile($url, $path)
{
    $newfname = $path;
    $file = fopen ($url, 'rb');
    if ($file) {
        $newf = fopen ($newfname, 'wb');
        if ($newf) {
            while(!feof($file)) {
                fwrite($newf, fread($file, 1024 * 8), 1024 * 8);
            }
        }
    }
    if ($file) {
        fclose($file);
    }
    if ($newf) {
        fclose($newf);
    }
}

1
अपने स्निपिट के लिए धन्यवाद, लेकिन क्या आप अपने कोड @xaav की व्याख्या कर पाएंगे? मैं php पर बिल्कुल प्रतिभाशाली नहीं हूँ। 1024 * 8 क्या है? एक बार फिर धन्यवाद।
vvMinovv

@wMinow लाइन की लंबाई।
डेविड बेलांगेर

2
विशेष रूप से, इसका मतलब है कि एक बार में 8KB तक पढ़ना (1024 बाइट प्रति KB * 8) क्योंकि पैरामीटर बाइट्स में है। जब तक लाइन <= 8KB है, यह एक ही बार में पूरी लाइन को पढ़ लेगा।
Doktor J

1
यह सबसे अच्छा जवाब क्यों नहीं है?
गनजैक

1
आप इस दृष्टिकोण के साथ त्रुटियों को कैसे संभालते हैं? क्या होगा यदि 404 लौटाया जाता है या कनेक्शन बाधित होता है या बाहर निकलता है?
एडम स्विंडेन

67

CURL का उपयोग करके देखें

set_time_limit(0); // unlimited max execution time
$options = array(
  CURLOPT_FILE    => '/path/to/download/the/file/to.zip',
  CURLOPT_TIMEOUT =>  28800, // set this to 8 hours so we dont timeout on big files
  CURLOPT_URL     => 'http://remoteserver.com/path/to/big/file.zip',
);

$ch = curl_init();
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);

मुझे यकीन नहीं है लेकिन मुझे विश्वास है कि CURLOPT_FILEयह विकल्प के साथ लिखता है क्योंकि यह डेटा को खींचता है, अर्थात। शौकीन नहीं है।


2
आम तौर पर, यह ठीक होगा, लेकिन मेरे पास एक वेब ऐप में यह कोड है, इसलिए मुझे यकीन है कि उपयोगकर्ताओं को cURL स्थापित करना होगा। हालाँकि, मैंने इसे वोट दिया।
xaav

@Geoff यह एक वितरित वेब ऐप है? क्योंकि यदि आप होस्टिंग को नियंत्रित करते हैं, तो यह आपके उपयोगकर्ताओं (cURL आपके सर्वर पर एक पुस्तकालय है) के बारे में कोई फर्क नहीं पड़ता।
एलेक्स

नहीं, मैं होस्टिंग को नियंत्रित नहीं करता हूं। यह एक वितरित वेब ऐप है जो कोई भी हो सकता है।
xaav

3
कर्ल गायब हो सकता है। लेकिन लगभग सभी साझा होस्टिंग कंपनियों में डिफ़ॉल्ट रूप से CURL स्थापित है। मेरा मतलब है, मैंने ऐसा नहीं देखा है।
मंगरदास स्क्रीपका

19
मेरे परीक्षणों से, आप सीधे एक फ़ाइल पथ CURLOPT_FILE को असाइन नहीं कर सकते। यह एक फ़ाइल हैंडलर होना है। सबसे पहले, फ़ाइल को खोलें $fh = fopen('/path/to/download/the/file/to.zip', 'w');और fclose($fh);उसके बाद बंद करें curl_close($ch);। और सेटCURLOPT_FILE => $fh
गुस्तावो

22

prodigitalson का जवाब मेरे काम नहीं आया। मुझे missing fopen in CURLOPT_FILE और जानकारी मिली ।

इसने मेरे लिए काम किया, जिसमें स्थानीय url भी शामिल हैं:

function downloadUrlToFile($url, $outFileName)
{   
    if(is_file($url)) {
        copy($url, $outFileName); 
    } else {
        $options = array(
          CURLOPT_FILE    => fopen($outFileName, 'w'),
          CURLOPT_TIMEOUT =>  28800, // set this to 8 hours so we dont timeout on big files
          CURLOPT_URL     => $url
        );

        $ch = curl_init();
        curl_setopt_array($ch, $options);
        curl_exec($ch);
        curl_close($ch);
    }
}

19
  1. गंतव्य सर्वर में "डाउनलोड" नामक एक फ़ोल्डर बनाएं
  2. [इस कोड] को .phpफ़ाइल में सहेजें और गंतव्य सर्वर में चलाएँ

डाउनलोडर:

<html>
<form method="post">
<input name="url" size="50" />
<input name="submit" type="submit" />
</form>
<?php
    // maximum execution time in seconds
    set_time_limit (24 * 60 * 60);

    if (!isset($_POST['submit'])) die();

    // folder to save downloaded files to. must end with slash
    $destination_folder = 'downloads/';

    $url = $_POST['url'];
    $newfname = $destination_folder . basename($url);

    $file = fopen ($url, "rb");
    if ($file) {
      $newf = fopen ($newfname, "wb");

      if ($newf)
      while(!feof($file)) {
        fwrite($newf, fread($file, 1024 * 8 ), 1024 * 8 );
      }
    }

    if ($file) {
      fclose($file);
    }

    if ($newf) {
      fclose($newf);
    }
?>
</html> 

यह मानता है कि उपयोगकर्ता एक समाधान के बजाय एक स्टैंडअलोन स्क्रिप्ट चाहता है जो मौजूदा PHP अनुप्रयोग के भीतर काम करेगा, और मुझे विश्वास है कि उत्तरार्द्ध वही है जो ओपी और अधिकांश अन्य देख रहे हैं। एक स्पष्टीकरण उन लोगों के लिए भी उपयोगी होगा जो दृष्टिकोण को समझना चाहते हैं।
बीन

1
जब भी मैं यह हमेशा कोशिश करता हूं कि मेरी स्थानांतरित फ़ाइल का आकार 50816 है, लेकिन मेरी फ़ाइल का आकार इससे बड़ा है .. 120MB .. कोई भी विचार यह क्यों है?
रिफ़ाज़ स्टार

set_time_limit (24 * 60 * 60);एक लूप के अंदर रखा जाना है। स्क्रिप्ट की शुरुआत में इसका कोई असर नहीं हुआ।
विक्टर जोरास

16
set_time_limit(0); 
$file = file_get_contents('path of your file');
file_put_contents('file.ext', $file);

आपका उत्तर बहुत सरल और अच्छा काम कर रहा है, इससे मुझे मदद मिली जहां CURL फ़ाइल प्राप्त करने में विफल रही, यह काम किया। धन्यवाद :)
टॉमीक्स

2
आप यह समझाना चाहेंगे कि यह वास्तव में क्या करता है।
एलेक्स

6
यह PHP मेमोरी सीमा से अधिक ओपी की समस्या को संबोधित नहीं करता है।
user9645

यह बहुत सरल और सीधा है। सरल मामलों के लिए काफी उपयोगी है जहां फाइलें छोटी हैं या पर्यावरण एक स्थानीय विकास है।
वेलेंटाइन शी

.xlsx फ़ाइलों के लिए कोई विचार? यह 0 बाइट मेमोरी के साथ खाली फाइल को स्टोर कर रहा है।
ध्रुव ठक्कर


8

Php में एक सरल विधि का उपयोग करें copy()

copy($source_url, $local_path_with_file_name);

नोट: यदि गंतव्य फ़ाइल पहले से मौजूद है, तो इसे ओवरराइट कर दिया जाएगा

PHP कॉपी () फ़ंक्शन

नोट: आपको गंतव्य फ़ोल्डर के लिए अनुमति 777 सेट करने की आवश्यकता है। जब आप अपने स्थानीय मशीन पर डाउनलोड कर रहे हों तो इस विधि का उपयोग करें।

विशेष नोट: 777 पूर्ण पढ़ने / लिखने / मालिक, समूह और सभी को अनुमति देने के साथ यूनिक्स आधारित प्रणाली में एक अनुमति है। सामान्य तौर पर हम ऐसी संपत्तियों को अनुमति देते हैं, जिन्हें किसी वेब सर्वर पर सार्वजनिक रूप से छिपाए जाने की अधिक आवश्यकता नहीं होती है। उदाहरण: चित्र फ़ोल्डर।


1
मैं वेबसर्वर पर कभी भी 777 को परमिट के रूप में सेट नहीं करूंगा, और मैं किसी भी वेबडॉलर को बंद कर दूंगा जिसका बुरा विचार है। हर समय, हर जगह। सावधान रहें ! तुम ऐसा नहीं कर सकते ! सुरक्षा के बारे में सोचो। OWASP नियमों का पालन करना पर्याप्त नहीं है। साधारण चीजों के बारे में अच्छी सोच रखना मायने रखता है।
थिएरीबी

@ThierryB। नोट: मैंने स्थानीय रास्ता दिया है। & इसका उपयोग आंतरिक अनुप्रयोगों में किया जा सकता है। प्रश्न और उत्तर के मामलों को अच्छी तरह से पढ़ना और समझना। विभिन्न परिदृश्यों पर विचार करें। और यह स्वीकार / सर्वोत्तम उत्तर नहीं है। इसमें प्रत्येक प्रश्न के पेशेवरों और विपक्षों के साथ अलग-अलग उत्तर हैं .. उदाहरण के लिए आपको समझने के लिए: यहां तक ​​कि फाइबोनैचि के कई अद्वितीय समाधान हैं जहां केवल एक ही सबसे अच्छा होगा। अन्य का उपयोग विभिन्न परिदृश्यों में किया जाएगा।
प्रदीप कुमार प्रभारण जुले

ठीक है, लेकिन सर्वोत्तम प्रथाओं के बारे में सोचने और सुरक्षित स्थानों के अंदर उन्हें लागू करने के लिए समय निकालने से आपको उन अवधारणाओं की बेहतर समझ मिल जाएगी जिन्हें आपको लागू करना चाहिए। हो सकता है कि अगर एक घुसपैठिया आपके ($) घर के अंदर है, कुछ जाल या चीजें बनाने का सबसे अच्छा तरीका है जो आप कुछ सिरदर्द दे देंगे;)
ThierryB

5

मैं फ़ाइल डाउनलोड करने के लिए इसका उपयोग करता हूं

function cURLcheckBasicFunctions()
{
  if( !function_exists("curl_init") &&
      !function_exists("curl_setopt") &&
      !function_exists("curl_exec") &&
      !function_exists("curl_close") ) return false;
  else return true;
}

/*
 * Returns string status information.
 * Can be changed to int or bool return types.
 */
function cURLdownload($url, $file)
{
  if( !cURLcheckBasicFunctions() ) return "UNAVAILABLE: cURL Basic Functions";
  $ch = curl_init();
  if($ch)
  {

    $fp = fopen($file, "w");
    if($fp)
    {
      if( !curl_setopt($ch, CURLOPT_URL, $url) )
      {
        fclose($fp); // to match fopen()
        curl_close($ch); // to match curl_init()
        return "FAIL: curl_setopt(CURLOPT_URL)";
      }
      if ((!ini_get('open_basedir') && !ini_get('safe_mode')) || $redirects < 1) {
        curl_setopt($ch, CURLOPT_USERAGENT, '"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11) Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //curl_setopt($ch, CURLOPT_REFERER, 'http://domain.com/');
        if( !curl_setopt($ch, CURLOPT_HEADER, $curlopt_header)) return "FAIL: curl_setopt(CURLOPT_HEADER)";
        if( !curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $redirects > 0)) return "FAIL: curl_setopt(CURLOPT_FOLLOWLOCATION)";
        if( !curl_setopt($ch, CURLOPT_FILE, $fp) ) return "FAIL: curl_setopt(CURLOPT_FILE)";
        if( !curl_setopt($ch, CURLOPT_MAXREDIRS, $redirects) ) return "FAIL: curl_setopt(CURLOPT_MAXREDIRS)";

        return curl_exec($ch);
    } else {
        curl_setopt($ch, CURLOPT_USERAGENT, '"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11) Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //curl_setopt($ch, CURLOPT_REFERER, 'http://domain.com/');
        if( !curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false)) return "FAIL: curl_setopt(CURLOPT_FOLLOWLOCATION)";
        if( !curl_setopt($ch, CURLOPT_FILE, $fp) ) return "FAIL: curl_setopt(CURLOPT_FILE)";
        if( !curl_setopt($ch, CURLOPT_HEADER, true)) return "FAIL: curl_setopt(CURLOPT_HEADER)";
        if( !curl_setopt($ch, CURLOPT_RETURNTRANSFER, true)) return "FAIL: curl_setopt(CURLOPT_RETURNTRANSFER)";
        if( !curl_setopt($ch, CURLOPT_FORBID_REUSE, false)) return "FAIL: curl_setopt(CURLOPT_FORBID_REUSE)";
        curl_setopt($ch, CURLOPT_USERAGENT, '"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11) Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11');
    }
      // if( !curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true) ) return "FAIL: curl_setopt(CURLOPT_FOLLOWLOCATION)";
      // if( !curl_setopt($ch, CURLOPT_FILE, $fp) ) return "FAIL: curl_setopt(CURLOPT_FILE)";
      // if( !curl_setopt($ch, CURLOPT_HEADER, 0) ) return "FAIL: curl_setopt(CURLOPT_HEADER)";
      if( !curl_exec($ch) ) return "FAIL: curl_exec()";
      curl_close($ch);
      fclose($fp);
      return "SUCCESS: $file [$url]";
    }
    else return "FAIL: fopen()";
  }
  else return "FAIL: curl_init()";
}

4

एक PHP 4 और 5 समाधान:

readfile () बड़ी मेमोरी भेजने पर भी, अपने आप कोई मेमोरी इश्यू पेश नहीं करेगा। इस फ़ंक्शन के साथ एक फ़ाइल नाम के रूप में एक URL का उपयोग किया जा सकता है यदि फोपेन आवरण को सक्षम किया गया है।

http://php.net/manual/en/function.readfile.php


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