1. 程式人生 > >php 上傳檔案與下載檔案

php 上傳檔案與下載檔案

上傳

/**
 * 單檔案上傳
 * @param array $fileInfo 檔案資訊 是一個數組
 * @param string $uploadPATH  檔案上傳預設路徑
 * @param bool $imageFlag       是否檢測真實圖片
 * @param array $allowExt       允許上傳的檔案型別
 * @param int $maxSize          允許上傳檔案的最大值
 * @return bool|string
 */
function upload_file(array $fileInfo,$uploadPATH='./uploads',bool $imageFlag=true,array $allowExt=array('jpeg','jpg','png','gif'),int $maxSize=2097152){

    define("UPLOAD_ERRS",
        [
            UPLOAD_ERR_INI_SIZE=>"超過了PHP配置檔案中upload_max_filesizez",
            UPLOAD_ERR_FORM_SIZE=>"超過了PHP配置檔案中upload_max_filesizez",
            UPLOAD_ERR_PARTIAL=>"檔案部分被上傳",
            UPLOAD_ERR_NO_FILE=>"沒有選擇上傳檔案",
            UPLOAD_ERR_NO_TMP_DIR=>"沒有臨沭目錄",
            UPLOAD_ERR_CANT_WRITE=>"檔案不能被寫入",
            UPLOAD_ERR_EXTENSION=>"副檔名錯誤",
            'not_true_image'=>"檔案不是真實圖片",
            'not_http_post'=>"檔案不是通過HTTP POST上傳的",
            'move_error'=>"檔案不是通過HTTP POST上傳的",
            'move_error'=>"檔案移動失敗",
        ]
    );
    //檢測上傳是否有錯誤
    if($fileInfo["error"]==UPLOAD_ERR_OK){
        //檢測檔案上傳型別
        $ext=strtolower(pathinfo($fileInfo['name'],PATHINFO_EXTENSION));
        /** @var TYPE_NAME $allowExt */
     if(!in_array($ext,$allowExt)){
         echo UPLOAD_ERRS[UPLOAD_ERR_EXTENSION];
         return false;
     }
     //檢測上傳大小是否符合規範
        if($fileInfo['size']>$maxSize){
            echo UPLOAD_ERRS[UPLOAD_ERR_INI_SIZE];
            return false;
        }
        //檢測是否是真實圖片
        if($imageFlag){
            if(@!getimagesize($fileInfo['tmp_name'])){
                echo UPLOAD_ERRS['not_true_image'];
                return false;
            }
        }
        //檢測檔案是否通過HTTP POST方式上傳來的
        if(!is_uploaded_file($fileInfo['tmp_name'])){
            echo UPLOAD_ERRS['not_http_post'];
            return false;
        }
        //檢測目標目錄是否存在,不存在則建立
        if(!is_dir($uploadPATH)){
            mkdir($uploadPATH,0777,true);
        }
        //生存唯一檔名,防止重新命名產生覆蓋
        $uniName=md5(uniqid(microtime(true),true)).".".$ext;
        $dest=$uploadPATH.DIRECTORY_SEPARATOR.$uniName;
        //移動檔案
        if(@!move_uploaded_file($fileInfo['tmp_name'],$dest)){
            echo UPLOAD_ERRS['move_error'];
            return false;
        }
        echo '檔案上傳成功';
        return $dest;
    }else{
        $megs=UPLOAD_ERRS[$fileInfo["error"]];
        echo  $megs;
    }

}

upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>檔案上傳</title>
</head>
<body>
<h1>檔案上傳</h1>
<form action="doUpload.php" method="post" enctype="multipart/form-data">

    <input type="file" name="myFile" id="">
    <input type="submit" value="立即上傳">
    
</form>
</body>
</html>

doUpload.php

<?php
/**
 * Created by PhpStorm.
 * User: liuan
 * Date: 2018-11-15 0015
 * Time: 14:36
 */
require_once 'func.php';
$fileInfo=$_FILES['myFile'];
var_dump(upload_file($fileInfo));

下載

/**
 * 下載檔案
 * @param  string $filename     檔名
 * @param  array  $allowDownExt 允許下載的檔案型別
 * @return void
 */
function down_file(string $filename,array $allowDownExt=['jpg','jpeg','png','gif','txt','html','php','rar','zip']){
if(!is_file($filename)||!is_readable($filename)){
  return false;
}
//檢測檔案型別是否允許下載
$ext=strtolower(pathinfo($filename,PATHINFO_EXTENSION));
if(!in_array($ext,$allowDownExt)){
  return false;
}

//通過header() 傳送頭資訊
//告訴瀏覽器輸出的是位元組流
header('content-type:application/octet-stream');
//告訴瀏覽器返回的檔案大小是按照位元組進行計算的
header('Accept-Ranges:bytes');
//告訴瀏覽器返回的檔案大小
header('Accept-Lenth:'.filesize($$filename));
//告訴瀏覽器 檔案作為附件處理 告訴瀏覽器最終下載完的檔名稱
header('Content-Disposition:attachment;filename=liuan_'.basename($filename));
//讀取檔案中的內容
readfile($filename);
exit;
}
/**
 * 下載檔案
 * @param  string $filename     檔名
 * @param  array  $allowDownExt 允許下載的檔案型別
 * @return void
 */
function down_file1(string $filename,array $allowDownExt=['jpg','jpeg','png','gif','txt','html','php','rar','zip']){
if(!is_file($filename)||!is_readable($filename)){
  return false;
}
//檢測檔案型別是否允許下載
$ext=strtolower(pathinfo($filename,PATHINFO_EXTENSION));
if(!in_array($ext,$allowDownExt)){
  return false;
}

//通過header() 傳送頭資訊
//告訴瀏覽器輸出的是位元組流
header('content-type:application/octet-stream');
//告訴瀏覽器返回的檔案大小是按照位元組進行計算的
header('Accept-Ranges:bytes');
//告訴瀏覽器返回的檔案大小
header('Accept-Lenth:'.filesize($filename));
//告訴瀏覽器 檔案作為附件處理 告訴瀏覽器最終下載完的檔名稱
header('Content-Disposition:attachment;filename=liuan_'.basename($filename));
//讀取檔案中的內容
//規定每次讀取檔案的位元組數為1024位元組 直接輸出shuju
$read_buffer=1024;
$sum_buffer=0;
$handle=fopen($filename,'rb');
$filesize=filesize($filename);
while(!feof($handle)&&$sum_buffer<$filesize){
  $sum_buffer+=$read_buffer;
  echo "round($sum_buffer/$filesize,2)","<br/>";
  echo fread($handle,$read_buffer);
}
fclose($handle);
exit;
}

download.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>測試下載</title>
</head>
<body>
  <a href="discuzcj_zdy_v9.5.zip">下載1.zip</a>
  <br>
  <a href="download.php?filename=2.zip">下載2.zip</a>
    <a href="download.php?filename=3.zip">下載3.zip 有進度</a>
</body>
</html>

download.php

<?php
echo dirname(__FILE__);
require_once '../fileSystem/lib/func.php';
$filename=$_GET['filename'];
down_file1($filename);