PHP 檔案的上傳與下載
阿新 • • 發佈:2020-11-23
檔案上傳與下載
檔案上傳
- 檔案上傳表單
- 表單的提交方式必須為POST
enctype="multipart/form-data"
- 說明瀏覽器可以提供檔案上傳功能
- 該屬性提示表單中有二進位制檔案資料
<input type="hidden" name="max_file_size" value="30000">
- 可以指定允許上傳檔案的最大尺寸
- MAX_FILE_SIZE必須在檔案域的上面。
<!-- form.html --> <form action="upload.php" enctype="multipart/form-data" method="post"> <input type="hidden" name="max_file_size" value="30000"> 選擇檔案:<input type="file" name="userfile"> <input type="submit" value="上傳檔案"> </form>
-
檔案域 表單的enctype屬性
- 預設情況下,表單傳遞是字元流,不能傳遞二進位制流
- 通過設定表單的enctype屬性傳遞複合資料
- enctype屬性的值有
application/x-www-form-urlencoded
(預設)表示傳遞的是帶格式的文字資料multipart/form-data
複合的表單資料(字串\檔案),檔案上傳必須設定此值text/plain
用於向伺服器傳遞無格式的文字資料,主要使用者電子郵件
-
PHP處理上傳檔案
- PHP會自動生成一個$_FILES二維陣列,該陣列儲存了上傳檔案的資訊
# upload.php <?php $name= $_FILES['userfile']['name']; $type= $_FILES['userfile']['type']; $size= $_FILES['userfile']['size']; $tmpName= $_FILES['userfile']['tmp_name']; $error= $_FILES['userfile']['error']; echo "{$name}<br>{$type}<br>{$size}<br>{$tmpName}<br>{$error}"; ?>
-
$_FILES['userfile']
鍵值說明$_FILES['userfile']['name']
上傳檔案的名稱$_FILES['userfile']['type']
上傳檔案的MIME型別(image/jpeg、image/gif、image/png)$_FILES['userfile']['size']
上傳檔案的大小,以位元組為單位$_FILES['userfile']['tmp_name']
檔案上傳時的臨時檔案$_FILES[][‘error’]
錯誤編碼(值有0、1、2、3、4、6、7)- 0 - 正確
- 4 - 沒有檔案上傳
- 1 - 檔案大小超過了php.ini中允許的最大值 upload_max_filesize = 2M
- 2 - 檔案大小超過了表單允許的最大值
- 3 - 只有部分檔案上傳
- 6 - 找不到臨時檔案
- 7 - 檔案寫入失敗
-
與檔案上傳有關的配置
post_max_size = 8M
表單允許的最大值upload_max_filesize = 2M
允許上傳的檔案大小upload_tmp_dir =F:\wamp\tmp
指定臨時檔案地址,如果不知道作業系統指定file_uploads = On
是否允許檔案上傳max_file_uploads = 20
允許同時上傳20個檔案
<?php
echo ini_get('post_max_size');
echo ini_get('upload_max_filesize');
echo ini_get('upload_tmp_dir');
echo ini_get('file_uploads');
echo ini_get('max_file_uploads');
?>
- 將上傳檔案移動到指定位置
move_uploaded_file()
臨時地址,目標地址- 上傳的同名的檔案要給覆蓋
# upload.php
<?php
mkdir('D:\Program Files\xampp\htdocs\uploads');
$newDir= "uploads/".$_FILES['userfile']['name'];
if(!empty($_POST)) {
if($_FILES['userfile']['error']== 0){
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
echo "上傳成功";
};
}else{
echo '上傳有誤';
echo '錯誤碼:'.$_FILES['userfile']['error'];
exit;
}
}
?>
優化檔案上傳
- 更改檔名
- 通過時間戳做檔名
- 通過uniqid()實現
uniqid()
生成唯一的IDuniqid('goods_')
帶有字首uniqid('goods_',true)
唯一ID+隨機數
# upload.php
<?php
# 判斷是否存在目錄
$dir= 'D:\Program Files\xampp\htdocs\uploads';
if(!is_dir($dir)){
mkdir($dir);
}
# 通過時間戳做檔名
$newName= time().rand(100,999).strrchr($_FILES['userfile']['name'],'.');
$newDir= "uploads/".$newName;
# 上傳服務處理
if(!empty($_POST)) {
if($_FILES['userfile']['error']== 0){
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
echo "上傳成功";
};
}else{
echo '上傳有誤';
echo '錯誤碼:'.$_FILES['userfile']['error'];
exit;
}
}
?>
# upload.php
<?php
# 判斷是否存在目錄
$dir= 'D:\Program Files\xampp\htdocs\uploads';
if(!is_dir($dir)){
mkdir($dir);
}
# 通過uniqid()實現
$newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.');
$newDir= "uploads/".$newName;
# 上傳服務處理
if(!empty($_POST)) {
if($_FILES['userfile']['error']== 0){
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
echo "上傳成功";
};
}else{
echo '上傳有誤';
echo '錯誤碼:'.$_FILES['userfile']['error'];
exit;
}
}
?>
- 驗證檔案格式
- 將檔案的字尾和允許的字尾對比 (不能識別檔案偽裝)
- 通過
$_FIELS[]['type']
型別判斷 (不能識別檔案偽裝) - 在php.ini中開啟fileinfo擴充套件 (可以防止檔案偽裝)
# # upload.php
<?php
if(!empty($_POST)) {
# 判斷是否存在目錄
$dir= 'D:\Program Files\xampp\htdocs\uploads';
if(!is_dir($dir)){
mkdir($dir);
}
# 通過uniqid()實現重新命名
$newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.');
$newDir= "uploads/".$newName;
# 檔名拓展名驗證
$allow= array('.jpg','.png','.gif');
$ext= strrchr($_FILES['userfile']['name'],'.');
if(!in_array($ext,$allow)){
echo '檔案上傳不合法';
exit;
}
# 上傳服務處理
if($_FILES['userfile']['error']== 0){
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
echo "上傳成功";
};
}else{
echo '上傳有誤';
echo '錯誤碼:'.$_FILES['userfile']['error'];
exit;
}
}
?>
# upload.php
<?php
if(!empty($_POST)) {
# 判斷是否存在目錄
$dir= 'D:\Program Files\xampp\htdocs\uploads';
if(!is_dir($dir)){
mkdir($dir);
}
# 通過uniqid()實現重新命名
$newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.');
$newDir= "uploads/".$newName;
# 檔名拓展名驗證
$allow= array('image/jpeg','image/png','image/gif');
$ext= $_FILES['userfile']['type'];
if(!in_array($ext,$allow)){
echo '檔案上傳不合法';
exit;
}
# 上傳服務處理
if($_FILES['userfile']['error']== 0){
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
echo "上傳成功";
};
}else{
echo '上傳有誤';
echo '錯誤碼:'.$_FILES['userfile']['error'];
exit;
}
}
?>
# upload.php
<?php
if(!empty($_POST)) {
# 判斷是否存在目錄
$dir= 'D:\Program Files\xampp\htdocs\uploads';
if(!is_dir($dir)){
mkdir($dir);
}
# 通過uniqid()實現重新命名
$newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.');
$newDir= "uploads/".$newName;
# 檔名拓展名驗證
$info=finfo_open(FILEINFO_MIME_TYPE);
$ext= finfo_file($info, $_FILES['userfile']['tmp_name']);
$allow= array('image/jpeg','image/png','image/gif');
if(!in_array($ext,$allow)){
echo '檔案上傳不合法';
exit;
}
# 上傳服務處理
if($_FILES['userfile']['error']== 0){
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
echo "上傳成功";
};
}else{
echo '上傳有誤';
echo '錯誤碼:'.$_FILES['userfile']['error'];
exit;
}
}
?>
- 優化檔案上傳
<?php
if(!empty($_POST)) {
# 判斷是否存在目錄
$dir= 'D:\Program Files\xampp\htdocs\uploads';
if(!is_dir($dir)){
mkdir($dir);
}
# 通過uniqid()實現重新命名
$newName= uniqid('goods_',true).strrchr($_FILES['userfile']['name'],'.');
$newDir= "uploads/".$newName;
# 檔名拓展名驗證
$info=finfo_open(FILEINFO_MIME_TYPE);
$ext= finfo_file($info, $_FILES['userfile']['tmp_name']);
$allow= array('image/jpeg','image/png','image/gif');
if(!in_array($ext,$allow)){
echo '只能上傳 '.implode(' , ',$allow).' 等檔案格式';
exit;
}
# 驗證檔案大小
$fileSize= ini_get('upload_max_filesize');
if(substr($fileSize, -1, 1)== 'k'){
$fileSize= (integer)$fileSize* 1024;
}elseif(substr($fileSize, -1, 1)== 'M'){
$fileSize= (integer)$fileSize* 1024* 1024;
}elseif(substr($fileSize, -1, 1)== 'G'){
$fileSize= (integer)$fileSize* 1024* 1024* 1024;
}elseif(substr($fileSize, -1, 1)== 'T'){
$fileSize= (integer)$fileSize* 1024* 1024* 1024* 1024;
}
if($_FILES['userfile']['size']> $fileSize){
echo '檔案大小不能超過'.number_format($fileSize/1024, 1).'K';
exit;
}
# 驗證是否是http上傳
if(!is_uploaded_file($_FILES['userfile']['tmp_name'])){
echo '檔案不是HTTP POST上傳的<br>';
exit;
}
# 上傳服務處理
if($_FILES['userfile']['error']== 0){
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $newDir)){
echo "上傳成功";
};
}else{
switch($_FILES['userfile']['error']) {
case 1:
echo '檔案大小超過了php.ini中允許的最大值,最大值是:'.ini_get('upload_max_filesize');
break;
case 2:
echo '檔案大小超過了表單允許的最大值';
break;
case 3:
echo '只有部分檔案上傳';
break;
case 4:
echo '沒有檔案上傳';
break;
case 6:
echo '找不到臨時檔案';
break;
case 7:
echo '檔案寫入失敗';
break;
default:
echo '未知錯誤';
break;
}
}
}
?>
檔案下載
<?php
header('Content-Type:text/html; charset=utf-8');
define('ROOT_PATH', dirname(__FILE__));
function downfile($file_path){
$file_path= iconv('utf-8', 'gb2312', $file_path);
if(!file_exists($file_path)){
exit('檔案不存在!');
}
$file_name= basename($file_path);
$file_size= filesize($file_path);
$file= fopen($file_path, 'r');
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename={$file_name}");
$buffer= 1024;
$file_count= 0;
while(!feof($file) && ($file_size- $file_count> 0)){
$file_data= fread($file, $buffer);
$file_count+= $buffer;
echo $file_data;
}
fclose($file);
}
downfile(ROOT_PATH.".\img\pigger.jpg");
?>