Php 简明教程
PHP - Download File
大多数现代浏览器允许自动下载特定类型的文件,无需任何服务器端代码(例如 PHP 脚本)。例如,zip 文件或 EXE 文件。
Most modern browsers allow files of certain types to be downloaded automatically, without any server-side code such as a PHP script. For example, a zip file, or an EXE file.
如果 HTML 超链接指向 ZIP 或 EXE 文件,浏览器将下载它并弹出一个保存对话框。但是,不会下载文本文件、图像文件等,而是在浏览器中打开,您可将其保存到本地文件系统。
If an HTML hyperlink points to a ZIP or EXE file, the browser downloads it and pops up a save dialog. However, text files, image files, etc., are not downloaded but opened in the browser, which you can save to your local filesystem.
The readfile() Function
要下载此类文件(而不是让浏览器自动打开它们),我们可以使用 PHP 内置函数库中的 readfile() 函数。
To download such files (instead of the browser automatically opening them), we can use the readfile() function in PHP’s built-in function library.
readfile(string $filename,
bool $use_include_path = false,
?resource $context = null)
: int|false
此函数读取文件并将其写入输出缓冲区。
This function reads a file and writes it to the output buffer.
第二个参数 $use_include_path 默认情况下为 false,因此将下载当前目录中的文件。如果设置为 true ,将搜索添加到 php.ini 配置的 include_path 设置中的目录以找到要下载的文件。
The second parameter $use_include_path is false by default, hence the file in the current directory will be downloaded. If set to true, the directories added to the include_path setting of php.ini configuration will be searched to locate the file to be downloaded.
readfile() 函数返回已读取的字节数,即使已成功完成。
The readfile() function returns the number of bytes read or false even it is successfully completed or not.
Example
以下 PHP 脚本展示了 readfile() 函数的用法。
The following PHP script shows the usage of readfile() function.
要下载文件, Content-Type 响应头应该设置为 application/octect-stream 。此 MIME 类型是二进制文件的默认值。浏览器通常不会执行该文件,甚至不会询问是否应该执行。
To download a file, the Content-Type response header should be set to application/octect-stream. This MIME type is the default for binary files. Browsers usually don’t execute it, or even ask if it should be executed.
此外,将 Content-Disposition 头设置为 attachment 将提示“另存为”对话框弹出。
Additionally, setting the Content-Disposition header to attachment prompts the "Save As" dialog to pop up.
<?php
$filePath = 'welcome.png';
// Set the Content-Type header to application/octet-stream
header('Content-Type: application/octet-stream');
// Set the Content-Disposition header to the filename of the downloaded file
header('Content-Disposition: attachment; filename="'. basename($filePath).'"');
// Read the contents of the file and output it to the browser.
readfile($filePath);
?>
将在文档根文件夹中将上述脚本保存为“download.php”。确保要下载的文件存在于同一文件夹中。
Save the above script as "download.php" in the document root folder. Make sure that the file to be downloaded is present in the same folder.
启动服务器,并在浏览器中访问 http://localhost/download.php 。你将获得如下所示的“另存为”对话框 -
Start the server and visit http://localhost/download.php in the browser. You will get a "Save As" dialog as below −
你可以选择一个名称并下载该文件。
You can select a name and download the file.
对于大型文件,你可以从文件流中以一定预定义大小的块中读取它。如果 Content-Disposition 头设置为“attachment”(如前一个示例中),浏览器将提供将其保存在本地文件系统中。
For a large file, you can read it from the file stream in the chunk of a certain predefined size. The browser offers to save it in the local filesystem, if the Content-Disposition head is set to "attachment", as in the previous example.
<?php
$filename = 'welcome.png';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
$handle = fopen($filename, 'rb');
$buffer = '';
$chunkSize = 1024 * 1024;
ob_start();
while (!feof($handle)) {
$buffer = fread($handle, $chunkSize);
echo $buffer;
ob_flush();
flush();
}
fclose($handle);
?>