Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/243.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用PHP强制下载文件_Php_File_Download - Fatal编程技术网

如何使用PHP强制下载文件

如何使用PHP强制下载文件,php,file,download,Php,File,Download,我想要求在用户使用PHP访问网页时下载一个文件。我认为它与文件获取内容有关,但不确定如何执行它 $url = "http://example.com/go.exe"; 下载带有标题(位置)的文件后,它不会重定向到其他页面。它只是停止。阅读关于内置PHP函数的文档 还要确保根据文件application/zip、application/pdf等添加适当的内容类型,但前提是您不想触发“另存为”对话框 <?php $file = "http://example.com/go.exe"; h

我想要求在用户使用PHP访问网页时下载一个文件。我认为它与
文件获取内容有关,但不确定如何执行它

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

下载带有
标题(位置)
的文件后,它不会重定向到其他页面。它只是停止。

阅读关于内置PHP函数的文档

还要确保根据文件application/zip、application/pdf等添加适当的内容类型,但前提是您不想触发“另存为”对话框

<?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(); 
?>
是正确的

或者对于exe类型的文件更好

header("Location: $url");
试试这个:

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


这就是你所需要的。“Monkey.gif”更改为您的文件名。如果需要从其他服务器下载,请将“monkey.gif”更改为“

对上述已接受答案的修改,该修改还会在运行时检测MIME类型:

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

首先显示文件并将其值设置为url

index.php

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

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

如果您必须下载的文件大小大于允许的内存限制(
内存限制
ini设置),这将导致
PHP致命错误:允许的内存大小5242880字节耗尽
错误,您可以执行以下操作:

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

下面的代码是在php中实现下载服务的正确方法,如下所述


您也可以流式下载,这将大大减少资源消耗。 例如:

在上面的示例中,我正在下载一个test.zip(实际上是本地机器上的android studio zip)。 php://output 是一个只写流(通常由echo或print使用)。 之后,您只需要设置所需的头并调用stream\u copy\u to\u stream(源、目标)。
stream\u copy\u to\u stream()方法充当一个管道,它从源流(读取流)获取输入并将其管道化到目标流(写入流),它还避免了允许内存耗尽的问题,因此您可以实际下载大于PHP
内存限制的文件。但是,我想提供一个关于如何使用GET执行它的方法

在html/php页面上

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

这应该适用于任何文件类型。这不是使用POST测试的,但它可以工作。

您可以使用下载属性强制下载文件:



不错,但不适用于受限区域中的文件

头文件名不应是
$file
(包含http部分),而是有效的文件名。没有应用程序/强制下载媒体类型;使用应用程序/八位字节流代替。工作非常好!但将“添加到存储的文件名中”。请使用:filename=“.basename($file));@harry4516根据您的发现进行修改,在我使用png图像的情况下不起作用。谢谢。@Fabio:将添加更多的细节,这非常简单。它起作用了。那么文件获取内容是什么?只是好奇。谢谢。要下载到您的服务器,只需在“readfile()之前删除“echo”)'因为返回值指定为“返回从文件读取的字节数。如果发生错误,将返回FALSE,除非函数被称为@readfile(),否则将打印一条错误消息。“。因此,您将以文件内容+内容末尾的整数结束。我的意思是,如果它不是.exe文件,而不是仅.exe文件。否则这应该可以正常工作。不要忘记刷新;-)ob_clean();flush();/*在*/readfile($file_url)之前;因此,如果您有一个10GB的大文件,php会尝试加载整个文件?应该在最后调用exit()以避免任何潜在的问题(根据经验:-)我正在使用图像http路径作为路径源,但文件以二进制代码显示,而不是使用您的代码下载。对我来说不起作用。谢谢。可能重复的可能重复的可能重复的你从哪里得到的?看起来powerful@jundell-agbo对crt文件来说很有趣吗?这对一个非常大的文件也是有效的。很好的解决方案。But`$chunksize=1*(1024*1024);`很慢。我尝试了多个值,发现`$chunksize=8*(1024*1024)`正在使用所有可用带宽。我刚刚尝试了这个,它杀死了我的服务器。在我的日志中写入了大量错误。了解日志内容会很有用。是的,很抱歉,日志文件太大了,我不得不用核弹把它炸开,所以我看不见。我不得不在访问权限非常有限的服务器上设置类似的东西。我的下载脚本一直重定向到主页,我不知道为什么。现在我知道问题是内存错误,这段代码解决了它。如果您只使用
ob_flush()
可能会出现错误:ob_flush():未能刷新缓冲区。没有要刷新的缓冲区。请使用
If(ob_get_level()>0){ob flush()}
(参考)欢迎使用StackOverflow。建议直接包含代码,而不是添加链接,以避免链接问题。此代码中有两个变量:
file\u name
filePath
。不是很好的编码实践。尤其是在没有解释的情况下。链接到外部教程没有帮助。您所说的downloa是什么意思d是流式的?@ParsaYazdani这意味着下载的数据将被分块。请查看流式的概念以了解更多详细信息。注意:这不是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');
?>
// 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;
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();
}
$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();
$File = 'some/dir/file.jpg';
<a href="<?php echo '../sumdir/download.php?f='.$File; ?>" target="_blank">Download</a>
$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;