কীভাবে পিএইচপি দিয়ে ফাইল ডাউনলোড জোর করবেন


122

আমি পিএইচপি এর সাথে কোনও ওয়েব পৃষ্ঠায় ভিজিটর ব্যবহারকারীর উপর একটি ফাইল ডাউনলোড করতে চাই। আমি মনে করি এটির কিছু করার আছে file_get_contentsতবে এটি কীভাবে কার্যকর করা যায় তা সম্পর্কে নিশ্চিত নই।

$url = "http://example.com/go.exe";

header(location)এটি দিয়ে কোনও ফাইল ডাউনলোড করার পরে অন্য পৃষ্ঠায় পুনর্নির্দেশ করা হচ্ছে না। এটি কেবল থামে।



উত্তর:


232

বিল্ট-ইন পিএইচপি ফাংশন রিডফিল সম্পর্কে ডকগুলি পড়ুন

$file_url = 'http://www.myremoteserver.com/file.exe';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary"); 
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\""); 
readfile($file_url); 

আপনার ফাইল অ্যাপ্লিকেশন / জিপ, অ্যাপ্লিকেশন / পিডিএফ ইত্যাদির উপর ভিত্তি করে যথাযথ সামগ্রীর প্রকার যোগ করার বিষয়টি নিশ্চিত করুন - তবে আপনি যদি সেভ-অ্যাস ডায়ালগটি ট্রিগার করতে না চান তবেই।


6
কেন এটি প্রয়োজন?
জন

আমি বলতে চাইছি এটির তুলনায় এটি যদি .exe ফাইল ব্যতীত অন্য কিছু হয় l
পিট ডিগার

7
ফ্লাশ করতে ভুলবেন না ;-) ob_clean (); ফ্লাশ (); / * এর আগে * / রিডফাইলে ($ file_url);
অ্যাশ

আপনার যদি 10 জিবি বড় ফাইল থাকে তবে পিএইচপি সেই পুরো ফাইলটি লোড করার চেষ্টা করে?
GDY

কোনও সম্ভাব্য সমস্যা এড়াতে প্রস্থান () প্রান্তে ডেকে আনা উচিত (অভিজ্ঞতা থেকে বলার জন্য :-)
ইয়েকে বলেছেন মোনিকা পুনরায় ইনস্টল করুন

42
<?php
$file = "http://example.com/go.exe"; 

header("Content-Description: File Transfer"); 
header("Content-Type: application/octet-stream"); 
header("Content-Disposition: attachment; filename=\"". basename($file) ."\""); 

readfile ($file);
exit(); 
?>

বা, যখন ফাইলটি ব্রাউজারের সাথে খোলা যায় না, আপনি কেবল শিরোনামটি ব্যবহার করতে পারেন Location:

<?php header("Location: http://example.com/go.exe"); ?>

1
আপনার শিরোনামে ফাইলের নাম হওয়া উচিত নয় $file(এতে HTTP অংশ রয়েছে) তবে একটি বৈধ ফাইলের নাম।
ফ্যাবিও 21

1
কোনও প্রয়োগ / জোর-ডাউনলোড মিডিয়া টাইপ নেই; ব্যবহার আবেদন / অক্টেট-স্ট্রীম পরিবর্তে।
গম্বো

খুব সুন্দর কাজ করে! তবে সঞ্চিত ফাইলের নামের সাথে যুক্ত করে '। দয়া করে ব্যবহার করুন: ফাইলের নাম = "। বেসনাম ($ ফাইল));
হ্যারি 4516

@ হ্যারি 4516 আপনার সন্ধান অনুসারে পরিবর্তিত হয়েছে
মারেক সেবেরা

আমার জন্য পিএনজি ইমেজের ক্ষেত্রে প্রিয় কাজ করছেন না। ধন্যবাদ।
কমলেশ

40
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"file.exe\""); 
echo readfile($url);

সঠিক

এক্স ফাইল টাইপের জন্য আরও ভাল exe

header("Location: $url");

@Fabio: আরও detials যোগ হবে
জনন

এটা খুব সহজ ছিল। এটা কাজ করেছে. তারপরে ফাইল-গেট_কন্টেন্টস কী? উৎসুক. ধন্যবাদ।
জন

এটি আপনার সার্ভারে ডাউনলোড করতে
বুদ্ধিমান

10
'রিডফিল ()' এর পূর্বে 'প্রতিধ্বনি' সরিয়ে ফেলুন যেহেতু রিটার্নের মান "ফাইল থেকে পঠিত বাইটের সংখ্যা দেখায়। যদি কোনও ত্রুটি দেখা দেয় তবে FALSE ফিরে আসে এবং যদি না ফাংশনটি @readfile () হিসাবে ডাকা হয়, একটি ত্রুটি বার্তা প্রিন্ট করা হয় "। সুতরাং আপনি সামগ্রীর শেষে ফাইল + পূর্ণসংখ্যার নম্বরটি শেষ করতে পারেন।
ম্লাদেন বি

22

আপনার ফাইলটি প্রথমে প্রদর্শন করুন এবং এর মানটি ইউআরএল সেট করুন।

index.php

<a href="download.php?download='.$row['file'].'" title="Download File">

download.php

<?php
/*db connectors*/
include('dbconfig.php');

/*function to set your files*/
function output_file($file, $name, $mime_type='')
{
    if(!is_readable($file)) die('File not found or inaccessible!');
    $size = filesize($file);
    $name = rawurldecode($name);
    $known_mime_types=array(
        "htm" => "text/html",
        "exe" => "application/octet-stream",
        "zip" => "application/zip",
        "doc" => "application/msword",
        "jpg" => "image/jpg",
        "php" => "text/plain",
        "xls" => "application/vnd.ms-excel",
        "ppt" => "application/vnd.ms-powerpoint",
        "gif" => "image/gif",
        "pdf" => "application/pdf",
        "txt" => "text/plain",
        "html"=> "text/html",
        "png" => "image/png",
        "jpeg"=> "image/jpg"
    );

    if($mime_type==''){
        $file_extension = strtolower(substr(strrchr($file,"."),1));
        if(array_key_exists($file_extension, $known_mime_types)){
            $mime_type=$known_mime_types[$file_extension];
        } else {
            $mime_type="application/force-download";
        };
    };
    @ob_end_clean();
    if(ini_get('zlib.output_compression'))
    ini_set('zlib.output_compression', 'Off');
    header('Content-Type: ' . $mime_type);
    header('Content-Disposition: attachment; filename="'.$name.'"');
    header("Content-Transfer-Encoding: binary");
    header('Accept-Ranges: bytes');

    if(isset($_SERVER['HTTP_RANGE']))
    {
        list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
        list($range) = explode(",",$range,2);
        list($range, $range_end) = explode("-", $range);
        $range=intval($range);
        if(!$range_end) {
            $range_end=$size-1;
        } else {
            $range_end=intval($range_end);
        }

        $new_length = $range_end-$range+1;
        header("HTTP/1.1 206 Partial Content");
        header("Content-Length: $new_length");
        header("Content-Range: bytes $range-$range_end/$size");
    } else {
        $new_length=$size;
        header("Content-Length: ".$size);
    }

    $chunksize = 1*(1024*1024);
    $bytes_send = 0;
    if ($file = fopen($file, 'r'))
    {
        if(isset($_SERVER['HTTP_RANGE']))
        fseek($file, $range);

        while(!feof($file) &&
            (!connection_aborted()) &&
            ($bytes_send<$new_length)
        )
        {
            $buffer = fread($file, $chunksize);
            echo($buffer);
            flush();
            $bytes_send += strlen($buffer);
        }
        fclose($file);
    } else
        die('Error - can not open file.');
    die();
}
set_time_limit(0);

/*set your folder*/
$file_path='uploads/'."your file";

/*output must be folder/yourfile*/

output_file($file_path, ''."your file".'', $row['type']);

/*back to index.php while downloading*/
header('Location:index.php');
?>

2
তুমি কোথা থেকে এলে? এটি শক্তিশালী বলে মনে হচ্ছে
অ্যাক্সেল এ। গার্সিয়া

@ jundell-agbo আকর্ষণীয় এবং একটি crt ফাইলের জন্য?
fralbo

এটি একটি খুব বড় ফাইলের জন্যও কাজ করছে। দুর্দান্ত সমাধান। তবে $ চুনসাইজ = 1 * (1024 * 1024); slow ধীর গতির। আমি একাধিক মান দিয়ে চেষ্টা করেছি এবং লক্ষ্য করেছি যে un un চুনসাইজ = 8 * (1024 * 1024); all সমস্ত উপলব্ধ ব্যান্ডউইথ ব্যবহার করছে।
লিঙ্গা

16

যদি আপনাকে অনুমোদিত মেমরি সীমা ( memory_limitআইএনআই সেটিং) এর চেয়ে বড় আকারের কোনও ফাইল ডাউনলোড করতে হয় যা PHP Fatal error: Allowed memory size of 5242880 bytes exhaustedত্রুটির কারণ হতে পারে তবে আপনি এটি করতে পারেন:

// File to download.
$file = '/path/to/file';

// Maximum size of chunks (in bytes).
$maxRead = 1 * 1024 * 1024; // 1MB

// Give a nice name to your download.
$fileName = 'download_file.txt';

// Open a file in read mode.
$fh = fopen($file, 'r');

// These headers will force download on browser,
// and set the custom file name for the download, respectively.
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');

// Run this until we have read the whole file.
// feof (eof means "end of file") returns `true` when the handler
// has reached the end of file.
while (!feof($fh)) {
    // Read and output the next chunk.
    echo fread($fh, $maxRead);

    // Flush the output buffer to free memory.
    ob_flush();
}

// Exit to make sure not to output anything else.
exit;

আমি এটি চেষ্টা করেছি এবং এটি আমার সার্ভারটিকে হত্যা করেছে। আমার লগগুলিতে প্রচুর ত্রুটি লিখেছিলেন W
ড্যানিয়েল উইলিয়ামস

লগগুলি কী ছিল তা জানার জন্য এটি দরকারী হবে।
পার্জিফল

হ্যাঁ দুঃখিত, লগ ফাইলটি এত বড় হয়ে গিয়েছিল আমাকে কেবল এটি করা উচিত ছিল, তাই আমি দেখতে পেলাম না।
ড্যানিয়েল উইলিয়ামস

আমি এমন একটি সার্ভারে এমন কিছু সেট আপ করছিলাম যাতে আমার খুব সীমাবদ্ধ অ্যাক্সেস ছিল। আমার ডাউনলোড স্ক্রিপ্টটি হোম পৃষ্ঠায় পুনঃনির্দেশিত রেখেছিল এবং কেন তা বুঝতে পারি না। এখন আমি জানি যে সমস্যাটি একটি মেমরির ত্রুটি ছিল এবং এই কোডটি এটি সমাধান করেছে।
গাভিন

যদি আপনি কেবল ব্যবহার ob_flush()করেন ত্রুটি হতে পারে: ob_flush (): বাফার ফ্লাশ করতে ব্যর্থ। ফ্লাশ করার জন্য কোনও বাফার নেই । সঙ্গে এটি চারপাশে মোড়ানো if (ob_get_level() > 0) {ob_flush();}(রেফারেন্স stackoverflow.com/a/9182133/128761 )
ভি

11

উপরে গৃহীত উত্তরের একটি পরিবর্তন, যা রানটাইমে মাইম টাইমটি সনাক্ত করে:

$finfo = finfo_open(FILEINFO_MIME_TYPE);
header('Content-Type: '.finfo_file($finfo, $path));

$finfo = finfo_open(FILEINFO_MIME_ENCODING);
header('Content-Transfer-Encoding: '.finfo_file($finfo, $path)); 

header('Content-disposition: attachment; filename="'.basename($path).'"'); 
readfile($path); // do the double-download-dance (dirty but worky)

4

নিম্নলিখিত টিউটোরিয়ালে বর্ণিত হিসাবে নিম্নলিখিত কোডটি পিএইচপি তে একটি ডাউনলোড পরিষেবা বাস্তবায়নের সঠিক উপায়

header('Content-Type: application/zip');
header("Content-Disposition: attachment; filename=\"$file_name\"");
set_time_limit(0);
$file = @fopen($filePath, "rb");
while(!feof($file)) {
    print(@fread($file, 1024*8));
    ob_flush();
    flush();
}

1
এই কোডটিতে আপনার দুটি ভেরিয়েবল রয়েছে: file_nameএবং filePath। খুব ভাল কোডিং অনুশীলন না। বিশেষ করে ব্যাখ্যা ছাড়াই বাহ্যিক টিউটোরিয়ালটির সাথে লিঙ্ক করা সহায়ক নয়।
খোম নাজিদ

2

এটা চেষ্টা কর:

header('Content-type: audio/mp3'); 
header('Content-disposition: attachment; 
filename=“'.$trackname'”');                             
readfile('folder name /'.$trackname);          
exit();

2

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

আপনার এটাই দরকার। "Monkey.gif" আপনার ফাইলের নাম পরিবর্তন করুন। আপনার যদি অন্য সার্ভার থেকে ডাউনলোড করতে হয় তবে "monkey.gif" " http://www.exsample.com/go.exe " এ পরিবর্তন করুন


1
স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম। লিঙ্কের সমস্যাগুলি এড়ানোর জন্য কোনও লিঙ্ক যুক্ত করার পরিবর্তে কোডটি সরাসরি অন্তর্ভুক্ত করার পরামর্শ দেওয়া সর্বদা।
অপরিচিত

1

আপনি ডাউনলোড স্ট্রিমও করতে পারেন যা উল্লেখযোগ্যভাবে কম সংস্থান গ্রহণ করবে। উদাহরণ:

$readableStream = fopen('test.zip', 'rb');
$writableStream = fopen('php://output', 'wb');

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="test.zip"');
stream_copy_to_stream($readableStream, $writableStream);
ob_flush();
flush();

উপরের উদাহরণে, আমি একটি টেস্ট.জিপ ডাউনলোড করছি (যা আসলে আমার স্থানীয় মেশিনে অ্যান্ড্রয়েড স্টুডিও জিপ ছিল)। পিএইচপি: // আউটপুট একটি লেখার জন্য কেবল স্ট্রিম (সাধারণত ইকো বা মুদ্রণ দ্বারা ব্যবহৃত হয়)। এর পরে, আপনাকে কেবল প্রয়োজনীয় শিরোনাম সেট করতে হবে এবং স্ট্রিম_কপি_টো_স্ট্রিম (উত্স, গন্তব্য) কল করতে হবে। stream_copy_to_stream () পদ্ধতিটি এমন পাইপ হিসাবে কাজ করে যা উত্স স্ট্রিম থেকে ইনপুট নেয় (পড়ার স্ট্রিম) এবং এটিকে গন্তব্য প্রবাহে (স্ট্রিম লেখায়) পাইপ দেয় এবং এটি অনুমোদিত মেমরির সমস্যাটি এড়িয়ে যায় যাতে আপনি আসলে বড় ফাইলগুলি ডাউনলোড করতে পারেন আপনার পিএইচপি চেয়ে memory_limit


ডাউনলোডটি আপনি কী বোঝাতে চেয়েছেন?
পারসা ইয়াজদানি

1
@ পার্সায়াজদানি এর অর্থ ডাউনলোড করা ডেটা ছিন্ন করা হবে। আরও তথ্যের জন্য দয়া করে স্ট্রিমিংয়ের ধারণাটি দেখুন। দ্রষ্টব্য: পিএইচপি-তে এই ফাইলটি কেবল স্ট্রিম (খণ্ড) ডাউনলোড করতে পারে না। তবে এটি অবশ্যই সহজতম পদ্ধতিগুলির মধ্যে একটি।
সৌদ কুরেশি

0

আমার উপরের উত্তরগুলি কাজ করে। তবে, আমি এটি জিইটি ব্যবহার করে কীভাবে সম্পাদন করতে পারি তার একটি পদ্ধতিতে অবদান রাখতে চাই

আপনার এইচটিএমএল / পিএইচপি পৃষ্ঠায়

$File = 'some/dir/file.jpg';
<a href="<?php echo '../sumdir/download.php?f='.$File; ?>" target="_blank">Download</a>

এবং download.phpরয়েছে

$file = $_GET['f']; 

header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");

$ext = pathinfo($file, PATHINFO_EXTENSION);
$basename = pathinfo($file, PATHINFO_BASENAME);

header("Content-type: application/".$ext);
header('Content-length: '.filesize($file));
header("Content-Disposition: attachment; filename=\"$basename\"");
ob_clean(); 
flush();
readfile($file);
exit;

এটি যে কোনও ফাইল ধরণের উপর কাজ করা উচিত। এটি পোষ্ট ব্যবহার করে পরীক্ষা করা হয় না তবে এটি কাজ করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.