[PHP從小白到大牛]-020 PHP文件函數封裝

函數封裝

文件操做相關

建立文件

/** * create_file, 根據文件路徑, 建立文件 * * @param string $filename 文件路徑 * * @return boolean true表示建立成功, false表示建立失敗 */
function create_file(string $filename) {
    // 判斷文件名是否存在
    if (file_exists($filename)) {
        // 若是存在, 則返回false
        return false;
    }
    // 判斷路徑是否存在, 若是不存在, 則建立
    if (!file_exists(dirname($filename))) {
        // 若是不存在文件夾, 則建立, 權限給777, 遞歸建立, 就是若是有多級, 就建立多個文件夾, 好比"hello/world"
        mkdir(dirname($filename), 0777, true);
    }
    // 往文件裏寫數據, 判斷是否可寫, 若是不可寫, 會返回false
    if (file_put_contents($filename, '') !== false) {
        return true;
    }
    // 最後給一個返回值, 不然沒有返回值的函數, 會返回null, 儘可能作到, 每一個函數都有返回值
    return false;
}
複製代碼

刪除文件

/** * del_file 根據文件路徑, 刪除文件 * * @param string $filename 文件路徑 * * @return boolean true表示建立成功, false表示建立失敗 */
function del_file(string $filename) {
    // 先判斷如下, 若是文件不存在, 或者文件不可寫, 都返回false, 之因此先判斷是否可寫, 由於若是有寫保護, 文件會刪不掉
    if (!file_exists($filename) || !is_writable($filename)) {
        // 返回false
        return false;
    }
    // 若是刪除成功, 返回true
    if (unlink($filename)) {
        // 返回成功
        return true;
    }
    // 若是走到這一步了, 說明以前沒有刪除成功, 返回false
    return false;
}
複製代碼

複製文件

/** * copy_file 複製文件到新的路徑 * * @param string $filename 文件路徑 * @param string $dest 新的目錄路徑 * * @return boolean true表示建立成功, false表示建立失敗 */
function copy_file(string $filename, string $dest) {
    // 若是第二個參數不是目錄, 遞歸建立
    if (!is_dir($dest)) {
        // 權限777, 最高權限, 遞歸建立
        mkdir($dest, 0777, true);
    }
    // DIRECTORY_SEPARATOR, 系統常量, 表示系統分隔符, 
    // 由於每一個操做系統的分隔符都不同, 因此寫成常量, 能夠作到跨平臺/操做系統
    // $destName爲新的文件路徑
    $destName = $dest . DIRECTORY_SEPARATOR . basename($filename);
    // 若是文件已經存在, 則返回false, 不讓複製
    if (file_exists($destName)) {
        // 返回false
        return false;
    }
    // 若是複製成功, 返回true
    if (copy($filename, $destName)) {
        // 返回true, 表示成功
        return true;
    }
    // 若是走到這一步, 說明以前的系統函數copy()沒有成功, 返回false
    return false;
}
複製代碼

重命名文件

/** * rename_file 重命名文件 * * @param string $oldName 文件路徑 * @param string $newName 新的文件的名字, 只要名字便可, 由於是同一個路徑 * * @return boolean true表示建立成功, false表示建立失敗 */
function rename_file(string $oldName, string $newName) {
    // 重命名以前, 先判斷參數一是否是文件, 不是文件則不能重命名, 由於只有文件能夠重命名
    if (!is_file($oldName)) {
        // 返回false
        return false;
    }
    // 獲取參數一的路徑
    $path = dirname($oldName);
    // 拼接出新文件的路徑
    $destName = $path . DIRECTORY_SEPARATOR . $newName;
    // 重命名以前, 先判斷有沒有重名函數
    if (is_file($destName)) {
        // 若是已經存在同名文件, 返回false
        return false;
    }
    // 使用系統函數rename, 來重命名文件
    if (rename($oldName, $newName)) {
        // 若是成功, 返回true
        return true;
    }
    // 若是走到這一步, 說明系統函數rename()沒有執行成功, 返回false
    return false;
}
複製代碼

剪切文件

/** * cut_file 剪切文件 * * @param string $filename 文件路徑 * @param string $dest 剪切到的目錄路徑 * * @return boolean true表示建立成功, false表示建立失敗 */
function cut_file(string $filename, string $dest) {
    // 剪切文件以前, 須要判斷是否是文件, 若是不是文件, 返回false
    if (!is_file($filename)) {
        // 若是不是文件, 返回false
        return false;
    }
    // 判斷路徑是否存在, 若是不存在, 則建立
    if (!is_dir($dest)) {
        // 遞歸建立路徑, 給與最高權限, 777
        mkdir($dest, 0777, true);
    }
    // 拼接文件路徑
    $destName = $dest . DIRECTORY_SEPARATOR . basename($filename);
    // 若是存在重名文件, 則不能剪切
    if (is_file($destName)) {
        // 返回false
        return false;
    }
    // 使用系統函數rename, 來實現剪切功能
    if (rename($filename, $destName)) {
        // 成功返回true
        return true;
    }
    // 若是走到這一步, 說明系統函數rename(), 沒有執行成功, 返回false
    return false;
}
複製代碼

文件信息相關

返回文件信息

/** * get_file_info 獲取文件信息, 返回的是一個關聯數組 * * @param string $filename 文件路徑 * * @return array 返回包括文件信息的關聯數組 * @return array['atime'] 訪問時間 * @return array['mtime'] 修改時間 * @return array['ctime'] 建立時間 * @return array['size'] 文件大小, 調用trans_byte函數進行轉換 * @return array['type'] 返回文件類型, 調用系統函數filetype */
function get_file_info(string $filename) {
    // 獲取文件信息的前提: 能夠找到這個文件, 而且該文件可讀
    if (!is_file($filename) || !is_readable($filename)) {
        // 若是找不到文件或者不可讀, 返回false
        return false;
    }
    // 返回一個數組, 時間格式爲 年-月-日 時:分:秒
    return [
        // 訪問時間
        'atime' => date("Y-m-d H:i:s", fileatime($filename)),
        // 修改時間
        'mtime' => date("Y-m-d H:i:s", filemtime($filename)),
        // 建立時間
        'ctime' => date("Y-m-d H:i:s", filectime($filename)),
        // 文件大小, 調用trans_byte函數進行轉換
        'size' => trans_byte(filesize($filename)),
        // 返回文件類型, 調用系統函數filetype
        'type' => filetype($filename),
    ];
}
複製代碼

字節單位轉換的函數

/** * trans_byte 文件大小的單位轉換 * * @param int $byte 總的字節數 * @param int $precision 四捨五入時, 保留的小數點位數, 默認兩位 * * @return string 帶上單位的文件大小 */
function trans_byte(int $byte, int $precision = 2) {
    // 定義一些變量, 用來描述單位之間的換算關係
    $kb = 1024;
    // 1mb = 1024kb
    $mb = 1024 * $kb;
    // 1gb = 1024mb
    $gb = 1024 * $mb;
    // 1tb = 1024gb
    $tb = 1024 * $gb;

    // 進行單位轉換
    if ($byte < $kb) { // 若是不足1kb, 單位爲b
        // 返回字節數
        return $byte . 'B';
    } elseif ($byte < $mb) { // 若是不夠1mb, 返回kb數
        // 四捨五入, 保留兩位
        return round($byte / $kb, $precision) . 'KB';
    } elseif ($byte < $gb) { // 若是不夠1gb, 返回mb數
        // 四捨五入, 保留兩位
        return round($byte / $mb, $precision) . 'MB';
    } elseif ($byte < $tb) { // 若是不夠1tb, 返回gb數
        // 四捨五入, 保留兩位
        return round($byte / $gb, $precision) . 'GB';
    } else { // 最後無論多大, 返回都是TB數
        // 四捨五入, 保留兩位
        return round($byte / $tb, $precision) . 'TB';
    }
}

複製代碼

讀取文件內容,返回字符串

/** * read_file 根據文件路徑, 獲取/讀取文件的內容 * * @param string $filename 文件路徑 * * @return string 文件的內容 */
function read_file(string $filename) {
    // 讀取文件信息的前提, 是文件能找到, 而且可讀
    if (is_file($filename) && is_readable($filename)) {
        // 若是能找到文件, 而且擁有讀的權限, 則使用系統函數 file_get_contents()來獲取文件信息, 而且返回
        return file_get_contents($filename);
    }
    // 若是走到這一步, 說明沒能返回文件的內容, 那麼返回false
    return false;
}

複製代碼

讀取文件中的內容到數組中

/** * read_file_array 獲取文件內容, 返回數組, 一行是一個元素 * * @param string $filename 文件路徑 * @param boolean $skip_empty_lines 是否跳過空行, 默認false, 不跳過 * * @return array 文件內容, 一行是一個元素 */
function read_file_array(string $filename, bool $skip_empty_lines = false) {
    // 可以讀取文件的前提: 存在文件, 而且該文件可讀
    if (is_file($filename) && is_readable($filename)) {
        // 是否要跳過空行
        if ($skip_empty_lines) {
            // 若是跳過空行, 須要設置第二個參數, 須要同時設置兩個
            // FILE_IGNORE_NEW_LINES 在數組每一個元素的末尾不要添加換行符
            // FILE_SKIP_EMPTY_LINES 跳過空行
            // 必須同時設置, 不設置FILE_IGNORE_NEW_LINES的話, 只有一個換行符也會當成一行, 由於不是空行
            return file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        } else {
            // 若是不跳過空行, 直接調用系統函數file(), 來返回文件內容的數組
            return file($filename);
        }
    }
    // 若是走到這一步, 說明沒能返回文件的內容, 那麼返回false
    return false;
}

複製代碼

向文件中寫入內容

/** * write_file 把變量寫入文件中 * * @param string $filename 文件路徑 * @param mixed $data 須要寫入文件的變量, 數據類型不限 * * @return boolean 操做結果, 若是成功返回true, 失敗返回false */
function write_file(string $filename, $data) {
    // 獲取文件的路徑部分
    $dirname = dirname($filename);
    // 若是路徑不存在, 則建立
    if (!file_exists($dirname)) {
        // 根據路徑, 建立文件夾, 權限777, 遞歸建立
        mkdir($dirname, 0777, true);
    }
    // 判斷是否爲數組或者對象, 若是是, 須要序列化成字符串, 由於不能直接寫
    if (is_array($data) || is_object($data)) {
        // 序列化數組或者對象
        $data = serialize($data);
    }
    // 若是能成功寫入, 返回true
    if (file_put_contents($filename, $data) !== false) {
        // 表明可以寫入
        return true;
    } else { 
        // 不然返回false
        return false;
    }
}
複製代碼

向文件中寫入內容,以前內容不清空

/** * write_file1 寫入文件, 能夠選擇是否保留原來的內容 * * @param string $filename 文件路徑 * @param mixed $data 要寫入的變量, 數據類型不限 * @param bool $clearFlag 是否清除內容, true爲清除, false爲不清除(保留內容) * * @return boolean 操做結果, 若是成功返回true, 失敗返回false */
function write_file1(string $filename, $data, bool $clearFlag = false) {
    // 獲取文件路徑的目錄部分
    $dirname = dirname($filename);
    // 若是目錄不存在, 則建立
    if (!file_exists($dirname)) {
        // 權限777, 遞歸建立目錄
        mkdir($dirname, 0777, true);
    }
    // 若是文件存在, 而且可讀, 就讀取數據
    if (is_file($filename) && is_readable($filename)) {
        // 獲取文件中的內容
        $srcData = file_get_contents($filename);
    }else{
        // 不然內容爲空字符串
        $srcData = "";
    }
    // 若是變量是數組或者是對象, 則須要序列化, 否則寫不到文件裏去
    if (is_array($data) || is_object($data)) {
        // 序列換數組或者對象
        $data = serialize($data);
    }
    // 若是不清除文件, 則採用拼接的方式
    if(!$clearFlag){
        // 把內容拼接到文件的最後, 相似於append
        $data = $srcData . $data;
    }
    // 若是寫入成功, 返回true, 不然返回false
    if (file_put_contents($filename, $data) !== false) {
        return true; // 成功
    } else {
        return false; // 失敗
    }
}
複製代碼

截斷文件到指定大小

/** * truncate_file 將文件截斷到給定的長度 * * @param string $filename 文件路徑 * @param int $length 截取長度, 能夠是負數, 爲變成0 * * @return bool 操做結果, 若是成功返回true, 失敗返回false */
function truncate_file(string $filename, int $length) {
    // 若是是文件而且可寫, 則進行操做, 不然返回false
    if (is_file($filename) && is_writable($filename)) {
        // 使用fopen獲取文件句柄
        $handle = fopen($filename, 'r+');
        // 判斷截斷的長度, 若是爲負數, 則改爲0
        $length = $length < 0 ? 0 : $length;
        // 使用系統函數ftruncate進行截斷
        ftruncate($handle, $length);
        // 關閉文件
        fclose($handle);
        // 返回成功
        return true;
    }
    // 若是走到這一步, 說明操做失敗, 返回false
    return false;
}
複製代碼

下載文件

function down_file(string $filename, array $allowDownExt = array('jpeg', 'jpg', '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('Content-Type:application/octet-stream');
    header('Accept-Ranges: bytes');
    header('Accept-Length: ' . filesize($filename));
    header('Content-Disposition: attachment;filename=king_' . basename($filename));
    readfile($filename);
    exit;
}
複製代碼

下載文件

/** * down_file 根據文件路徑, 下載文件 * * @param string $filename 文件路徑 * @param array $allowDownExt 容許的後綴名 * * @return void */
function down_file(string $filename, array $allowDownExt = array('jpeg', 'jpg', 'png', 'gif', 'txt', 'html', 'php', 'rar', 'zip')) {
    // 判斷文件是否存在, 而且可讀, 由於咱們須要往裏寫數據
    if (!is_file($filename) || !is_readable($filename)) {
        // 不可讀, 或者不存在, 則報錯
        return false;
    }
    // 獲取後綴名
    $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    // 若是後綴名不符合要求, 則返回false, 不讓下載
    if (!in_array($ext, $allowDownExt)) {
        return false;
    }
    //經過header()發送頭信息
    //告訴瀏覽器輸出的是字節流
    header('Content-Type:application/octet-stream');
    //告訴瀏覽器返回的文件大小是按照字節進行計算的
    header('Accept-Ranges: bytes');
    // 獲取文件大小
    $filesize = filesize($filename);
    //告訴瀏覽器返回的文件大小
    header('Accept-Length: ' . $filesize);
    //告訴瀏覽器文件做爲附件處理,告訴瀏覽器最終下載完的文件名稱
    header('Content-Disposition: attachment;filename=king_' . basename($filename));
    //讀取文件中的內容
    //規定每次讀取文件的字節數爲1024字節,直接輸出數據
    $read_buffer = 1024;
    // 獲取文件句柄
    $handle = fopen($filename, 'rb');
    // 循環讀取, 直到文件結束
    while (!feof($handle)) {
        echo "hello";
        // fread 系統函數, 文件句柄, 每次讀取的大小
        echo fread($handle, $read_buffer);
    }
    // 關閉句柄
    fclose($handle);
    // 退出
    exit;
}

複製代碼

單文件上傳

/** * upload_file 上傳文件 * @param array $fileInfo 文件信息 * @param string $uploadPath 上傳後, 文件保存的路徑 * @param bool|boolean $imageFlag 是否檢測爲真實的圖片 * @param array $allowExt 容許的後綴 * @param int|integer $maxSize 上傳文件的最大值 * @return string|bool 若是成功, 返回保存的文件路徑, 若是失敗返回false */
function upload_file(array $fileInfo, string $uploadPath = './uploads', bool $imageFlag = true, array $allowExt = array('jpeg', 'jpg', 'png', 'gif'), int $maxSize = 2097152) {


    // 定義常量, UPLOAD_ERRS, 上傳錯誤信息, 是一個關聯數組
    define('UPLOAD_ERRS', [
        'upload_max_filesize' => '超過了PHP配置文件中upload_max_filesize選項的值',
        'form_max_size' => '超過了表單MAX_FILE_SIZE選項的值',
        'upload_file_partial' => '文件部分被上傳',
        'no_upload_file_select' => '沒有選擇上傳文件',
        'upload_system_error' => '系統錯誤',
        'no_allow_ext' => '非法文件類型',
        'exceed_max_size' => '超出容許上傳的最大值',
        'not_true_image' => '文件不是真實圖片',
        'not_http_post' => '文件不是經過HTTP POST方式上傳上來的',
        'move_error' => '文件移動失敗',
    ]);
    // 上傳成功沒有錯誤的處理邏輯
    if ($fileInfo['error'] === 0) {
        // 獲取文件後綴
        $ext = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
        // 判斷後綴是否符合要求, 不符合, 輸出信息"非法文件類型", 返回false
        if (!in_array($ext, $allowExt)) {
            echo UPLOAD_ERRS['no_allow_ext'];
            return false;
        }
        // 若是文件大小過大, 輸出信息"超出容許上傳的最大值", 返回false
        if ($fileInfo['size'] > $maxSize) {
            echo UPLOAD_ERRS['exceed_max_size'];
            return false;
        }
        // 若是須要檢測圖片是否爲真是圖片
        if ($imageFlag) {
            // 判斷一下, 若是不是圖片, 輸出信息"文件不是真實圖片", 返回false
            // getimagesize() 函數用於獲取圖像大小及相關信息,成功返回一個數組
            if (@!getimagesize($fileInfo['tmp_name'])) {
                echo UPLOAD_ERRS['not_true_image'];
                return false;
            }
        }
        // 若是文件不是走的http post, 輸出信息"文件不是經過HTTP POST方式上傳上來的", 返回false
        // is_uploaded_file() 函數檢查指定的文件是不是經過 HTTP POST 上傳的
        if (!is_uploaded_file($fileInfo['tmp_name'])) {
            return UPLOAD_ERRS['not_http_post'];
        }


        // 開始保存
        // 上傳文件的保存路徑是否存在, 若是不存在, 則遞歸建立
        if (!is_dir($uploadPath)) {
            mkdir($uploadPath, 0777, true);
        }
        // 給文件起一個名字, 目的是爲了排重
        // microtime(true) 秒級時間戳.毫米級時間戳
        // uniqid生成惟一id, 使用microtime做爲前綴
        // md5加密, 生成32位字符串
        $uniName = md5(uniqid(microtime(true), true)) . '.' . $ext;
        // 生成須要保存的完整文件名
        $dest = $uploadPath . DIRECTORY_SEPARATOR . $uniName;
        // move_uploaded_file 函數將上傳的文件移動到新位置
        if (@!move_uploaded_file($fileInfo['tmp_name'], $dest)) {
            // 若是失敗, 輸出"文件移動失敗""
            echo UPLOAD_ERRS['move_error'];
            return false;
        }
        // 若是沒有問題, 輸出 文件上傳成功
        echo '文件上傳成功';
        // 返回上傳完之後的文件路徑
        return $dest;
    } else {
        // 判斷具體上傳失敗時的錯誤, 返回中文信息
        switch ($fileInfo['error']) {
        case 1:
            $mes = UPLOAD_ERRS['upload_max_filesize']; // 超過了PHP配置文件中upload_max_filesize選項的值
            break;
        case 2:
            $mes = UPLOAD_ERRS['form_max_size']; // 超過了表單MAX_FILE_SIZE選項的值
            break;
        case 3:
            $mes = UPLAOD_ERRS['upload_file_partial']; // 文件部分被上傳
            break;
        case 4:
            $mes = UPLOAD_ERRS['no_upload_file_select']; // 沒有選擇上傳文件
            break;
        case 6:
        case 7:
        case 8:
            $mes = UPLAOD_ERRS['upload_system_error']; // 系統錯誤
            break;
        } 
        // 錯誤信息
        echo $mes;
        // 返回false
        return false;
    }
}
複製代碼

壓縮單個文件

/** * zip_file 壓縮單個文件 * * @param string $filename 文件路徑 * * @return bool true表示壓縮成功, false表示壓縮失敗 */
function zip_file(string $filename) {
	// 判斷文件是否存在, 沒有則返回false
    if (!is_file($filename)) {
        return false;
    }
    // 實例化一個ZipArchive對象
    $zip = new ZipArchive();
    // 設置壓縮文件的文件名, 原文件後面加zip, 相似於: hello.txt ==> hello.txt.zip
    $zipName = basename($filename) . '.zip';
    // 打開一個壓縮文件, 開始往裏寫內容, 若是沒有就建立, 若是有就覆蓋
    if ($zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
    	// 往壓縮包裏添加文件, 把結果賦值給一個變量
    	$result = $zip->addFile($filename);
        // 關閉壓縮包
        $zip->close();
        // 若是變量爲true, 說明添加成功, 刪除原文件
        if ($result) {
        	// 刪除原文件
            unlink($filename);
        }
        // 返回成功
        return true;
    } else {
    	// 返回失敗
        return false;
    }
}
複製代碼

多文件壓縮

/** * zip_files 多文件壓縮 * * @param string $zipName 自定義壓縮文件名 * @param mixed $files 須要壓縮的文件路徑, 個數不限 * * @return bool 成功返回true, 失敗返回false */
function zip_files(string $zipName, ...$files) {
	// 獲取後綴名
    $zipExt = strtolower(pathinfo($zipName, PATHINFO_EXTENSION));
    // 若是後綴名不是zip, 返回false
    if ('zip' !== $zipExt) {
        return false;
    }
    // 實例化ZipArchive()對象
    $zip = new ZipArchive();
    // 打開一個壓縮文件, 開始往裏寫內容, 若是沒有就建立, 若是有就覆蓋
    if ($zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
    	// 遍歷文件, 要壓縮的文件的路徑
        foreach ($files as $file) {
        	// 判斷是否能夠找到文件
            if (is_file($file)) {
            	// 若是沒有問題, 添加到壓縮文件裏
                $zip->addFile($file);
            }
        }
        // 關閉壓縮文件
        $zip->close();
        // 返回 true
        return true;
    } else {
    	// 返回 false
        return false;
    }
}
複製代碼

解壓縮

/** * unzip_file 解壓縮文件到指定路徑 * * @param string $zipName 壓縮包的文件路徑 * @param string $dest 解壓縮到指定路徑 * * @return bool 成功返回true, 失敗返回false */
function unzip_file(string $zipName, string $dest) {
	// 判斷可否找到壓縮文件, 若是找不到, 返回false
    if (!is_file($zipName)) {
        return false;
    }
    // 判斷解壓路徑是否存在, 沒有則建立
    if (!is_dir($dest)) {
        mkdir($dest, 0777, true);
    }
    // 實例化ZipArchive對象
    $zip = new ZipArchive();
    // 打開壓縮文件, 解壓到指定路徑
    if ($zip->open($zipName)) {
    	// 解壓到路徑
        $zip->extractTo($dest);
        // 關閉壓縮文件
        $zip->close();
        // 返回true
        return true;
    } else {
    	// 返回false
        return false;
    }
}
複製代碼

$_FILES詳解

$_FILES參數詳解:

  • $_FILES["file"]["name"]–被上傳文件的名稱
  • $_FILES["file"]["type"]–被上傳文件的類型
  • $_FILES["file"]["size"]–被上傳文件的大小, 以字節計
  • $_FILES["file"]["tmp_name"]–存儲在服務器的文件的臨時副本的名稱
  • $_FILES["file"]["error"]–由文件上傳致使的錯誤代碼

$_FILES["file"]["error"]中的["error"]值狀況

UPLOAD_ERR_OK

  • 0: 沒有錯誤發生, 文件上傳成功

UPLOAD_ERR_INI_SIZE

  • 1: 上傳的文件超過了php.ini中upload_max_filesize(默認狀況爲2M)選項限制的值

UPLOAD_ERR_FORM_SIZE

  • 2: 上傳文件的大小超過了HTML表單中MAX_FILE_SIZE選項指定的值

UPLOAD_ERR_PARTIAL

  • 3: 文件只有部分被上傳

UPLOAD_ERR_NO_FILE

  • 4: 沒有文件被上傳
  • 5: 傳文件大小爲 0
相關文章
相關標籤/搜索