1. 文件上传
1.1 HTTP 文件上传
文件上传是通过HTTP POST方法实现的,PHP通过超全局变量$_FILES获取上传的文件信息。一个完整的文件上传操作需要客户端和服务器端两个流程。
以下是一个简单的文件上传示例:
<form action="upload.php" method="post" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
上面的表单中enctype属性标识了表单数据的编码类型,要上传二进制文件需要设置成multipart/form-data。上传新文件时,需要判断上传文件的类型、大小、存储路径等,代码如下:
//判断上传文件是否为图片
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "File is not an image.";
$uploadOk = 0;
}
//判断上传文件的大小是否超过2MB
if ($_FILES["fileToUpload"]["size"] > 2000000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
//文件上传目录
$target_dir = "uploads/";
//将上传文件存储到指定目录
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
1.2 Nginx 文件上传
除了使用Apache的处理方式外,常用的Nginx也可以处理文件上传。Nginx提供一个上传模块,它的处理方式是将上传的文件保存到磁盘中,然后将文件位置返回给PHP脚本。以下是一个Nginx文件上传的示例:
location /upload {
client_max_body_size 10m;
client_body_buffer_size 1024k;
proxy_pass http://php;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /upload/backend/upload_process {
client_max_body_size 10m;
client_body_buffer_size 1024k;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
上面的代码中,第一个location是将Nginx作为代理服务器,将文件上传请求转发给PHP端进行处理。第二个location则是上传文件处理的具体路径。
2. 文件下载
在实际开发中,文件下载也是非常常见的操作。PHP提供了一系列处理文件下载的函数。
2.1 读取文件并输出
PHP中可以通过fread函数来读取文件内容,并通过echo语句输出给客户端。以下是一个简单的读取文件并输出的示例:
$file = 'example.txt';
$handle = fopen($file, 'rb');
if ($handle) {
while (!feof($handle)) {
echo fread($handle, 8192);
flush();
}
fclose($handle);
}
上面的代码中,首先通过fopen打开要下载的文件,以二进制的方式读取文件内容,并通过echo语句输出给客户端。
2.2 通过header函数指定文件名和类型并输出
除了直接读取文件内容输出外,PHP还提供了另一个函数header可以将文件模拟成一个下载链接。以下是一个示例:
$file = 'example.txt';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file);
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
上面的代码中,使用了header函数模拟一个下载链接的效果。其中,Content-Type指定了文件的MIME类型,Content-Disposition指定了文件下载的名称。