Het downloaden van bestanden forceren met PHP

Ik wil dat een bestand wordt gedownload wanneer de gebruiker een webpagina met PHP bezoekt. Ik denk dat het iets te maken heeft met file_get_contents, maar ik weet niet zeker hoe ik het moet uitvoeren.

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

Na het downloaden van een bestand met header(location)wordt het niet omgeleid naar een andere pagina. Het stopt gewoon.


Antwoord 1, autoriteit 100%

Lees de documenten over de ingebouwde PHP-functie readfile

$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); 

Zorg er ook voor dat u het juiste inhoudstype toevoegt op basis van uw bestandstoepassing/zip, toepassing/pdf enz. – maar alleen als u het dialoogvenster Opslaan als niet wilt activeren.


Antwoord 2, autoriteit 18%

<?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(); 
?>

Of, als het bestand niet met de browser kan worden geopend, kunt u gewoon de kop Locationgebruiken:

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

Antwoord 3, autoriteit 16%

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

is juist

of beter een voor exetype bestanden

header("Location: $url");

Antwoord 4, autoriteit 10%

Geef eerst uw bestand weer en stel de waarde in op url.

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');
?>

Antwoord 5, autoriteit 7%

In het geval dat u een bestand moet downloaden dat groter is dan de toegestane geheugenlimiet (memory_limitini-instelling), wat de PHP Fatal error: Allowed memory size of 5242880 bytes exhausted-fout, kunt u dit doen:

// 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;

Antwoord 6, autoriteit 4%

Een wijziging van het geaccepteerde antwoord hierboven, die ook het MIME-type detecteert in runtime:

$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)

Antwoord 7, autoriteit 2%

De volgende code is een correcte manier om een ​​downloadservice in php te implementeren, zoals uitgelegd in de volgende zelfstudie

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();
}

Antwoord 8

probeer dit:

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

Antwoord 9

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

Dat is alles wat je nodig hebt. “Monkey.gif” wijzigen in uw bestandsnaam. Als u van een andere server moet downloaden, wijzigt u “monkey.gif” in “http://www.exsample. com/go.exe


Antwoord 10

De antwoorden boven mij werken. Maar ik wil graag een methode bijdragen om dit uit te voeren met GET

op uw html/php-pagina

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

en download.phpbevat

$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;

dit zou op alle bestandstypes moeten werken. dit is niet getest met POST, maar het zou kunnen werken.


Antwoord 11

Je kunt ook download streamen, wat aanzienlijk minder bronnen verbruikt.
voorbeeld:

$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();

In het bovenstaande voorbeeld download ik een test.zip (dit was eigenlijk de Android Studio-zip op mijn lokale computer).
php://output is een alleen-schrijven stream (meestal gebruikt door echo of print).
daarna hoef je alleen maar de vereiste headers in te stellen en stream_copy_to_stream (bron, bestemming) aan te roepen.
stream_copy_to_stream() methode fungeert als een pijp die de invoer van de bronstroom (lees stroom) neemt en deze doorstuurt naar de bestemmingsstroom (schrijfstroom) en het vermijdt ook het probleem van toegestaan ​​geheugen uitgeputzodat u kan daadwerkelijk bestanden downloaden die groter zijn dan uw PHP memory_limit.


Antwoord 12

u kunt het kenmerk downloadgebruiken om het downloaden van een bestand te forceren:

<a href="https://test.com/aaa.exe" download>click here to download</a>

Antwoord 13

leuk, maar werkt niet met bestanden in beperkte gebieden

Other episodes