文件編程的初步認識
文件編程的必要性
文件編程指利用PHP代碼針對文件(文件夾)進行增刪改操作。
在實際開發項目中,會有很多內容(文件上傳,配置文件等)具有很多不確定性,不能在一開始就手動創建,需要根據實際需求和數據本身來進行管理,這個時候就可以使用PHP文件編程來實現代碼批量控制和其他操作。
文件操作的分類
1)目錄操作:文件夾,用來存放文件的 特殊文件
2)文件操作:用來存放內容
目錄操作
文件操作創建目錄結構
1)mkdir(路徑名字):創建成功返回true,創建失敗返回false
有些操作爲的就是得到一個想要的結果,如果結果本身存在,那麼可以忽略得到過程的錯誤:
抑制錯誤
刪除目錄
1)rmdir (string $dirname):移除文件夾
讀取目錄
讀取方式:將文件夾(路徑)按照資源方式打開
1)opendir():打開資源,返回一個路徑資源,包含指定目錄下的所有文件(文件夾)
2)readdir():從資源中讀取指針所在位置的文件名字,然後指針下移,直到指針移出資源
在任何一個文件夾下都有這兩個文件。
讀取所有內容:遍歷操作
關閉目錄
1)closedir():關閉資源
其他目錄操作
1)dirname(提供一個路徑):得到的是路徑的上一層路徑
2)realpath(一個路徑):得到真實路徑
3)is_dir():判斷指定路徑是否是一個目錄
4)scandir():封裝版的opendir\readdir\closedir,獲取一個指定路徑下的所有文件信息,以數組形式返回。
遞歸遍歷目錄
遞歸遍歷目錄:指定一個目錄的情況下,將其下的所有文件和目錄,以及目錄內部的所有內容都輸出出來。
遞歸遍歷目錄的思維邏輯:
1、設計一個能夠遍歷一層文件的函數
a.創建函數
b.安全判定:是路徑才訪問
c.讀取全部內容,遍歷輸出
2、找到遞歸點:遍歷得到的文件是目錄,應該調用當前函數
a.遍歷得到的結果只是文件的名字,需要構造路徑
b.需要排除.和..
c.判斷是路徑還是文件
d.是路徑,遞歸調用本身
3、找到遞歸出口:遍歷完這個文件夾之後,發現沒有任何子文件夾:自帶出口
4、如何顯示層級關係?函數第一次運行遍歷的結果是最外層目錄,內部調用一次說明進入一個子目錄,子目錄。。。。如果能夠在第一次調用的時候給個標記,然後在進入的時候,通過標記的變化來識別層級關係,就可以達到目的:該標記還能代表層級關係:縮進
a.在函數參數中增加一個標記:默認值爲0
b.遞歸調用的時候也需要使用該參數:但是是屬於當前層級的子層,所以加一
c.根據層級來實現縮進:str_repeat()
PHP代碼實現:
<?php
//遞歸遍歷文件夾
//定義路徑
$dir = '../uploads';
/*
*創建函數:能夠訪問指定路徑下的所有文件,且判斷出,目錄還是文件
*@param1 string $dir,指定路徑
*@param2 int $level=0,層級,默認頂層
*/
function my_scandir($dir,$level=0){
//保證文件的安全:如果不是路徑沒有必要往下
if(!is_dir($dir)) dir($dir.'<br/>');
//讀取全部路徑信息,遍歷輸出
$files = scandir($dir);
foreach($files as $file){
//$file就是一個個文件名
echo str_repeat(' ',$level),$file.'<br/>';
//排除.和..
if($file == '.' || $file == '..') continue;
//構造路徑
$file_dir = $dir.'/'.$file;
//echo $file_dir.'<br />';
//判斷路徑
if(is_dir($file_dir)){
//遞歸點
my_scandir($file_dir,$level+1);
}
}
}
//測試
my_scandir($dir,$level=0);
文件操作
常見文件操作函數
字符串形式處理:
1)file_get_contens($filename): 將整個文件讀入一個字符串,如果路徑不存在,最好做錯誤處理。
2)file_put_contens($filenmae):將一個字符串寫入文件,如果當前路徑下不存在指定的文件,函數會自動創建(如果路徑不存在,不會創建路徑)
資源類型處理:不論讀還是寫,都依賴資源指針:文件內容指針所在的位置
1)fopen(string $filename , string $mode):打開一個文件資源或者 URL,限定打開模式
2)fread(resource $handle , int $length):從打開的資源中讀取指定長度的內容(字節)
3)fwrite(resource $handle , string $string [, int $length ]):向打開的資源中寫入指定的內容
4)fclose(resource $handle):關閉
5)feof(resource $handle): 測試文件指針是否到了文件結束的位置
其他文件操作函數
1)is_file(string $filename):判斷文件是否正確,不識別路徑
2)filesize(string $filename):獲取文件大小
3)file_exists(string $filename):判斷文件是否存在,識別路徑
4)unlink(string $filename [, resource $context ]):取消文件名字與磁盤地址的連接(刪除文件)
5)filemtime(string $filename):獲取文件最後一次修改的時間
6)fseek(resource $handle , int $offset [, int $whence = SEEK_SET ]):設定fopen打開的文件的指針位置
7)fgetc(resource $handle):一次獲取一個字符,文件指針必須是有效的,必須指向由 fopen() 或 fsockopen() 成功打開的文件(並還未由 fclose() 關閉)。
8)fgets(resource $handle [, int $length ]):一次獲取一行字符串(默認),也可以指定長度,長度大於一行取一行。
9)file(string $filename):讀取整個文件,類似file_get_contents(),區別是按行讀取,返回一個數組
文件下載
文件下載:從服務器將文件通過HTTP協議傳輸到瀏覽器,瀏覽器不解析保存成響應的文件
提供下載方式可以使用HTML中的a標籤:<a href=”文件路徑”>單機下載</a>
1、缺點1:a標籤能夠讓瀏覽器自動下載的內容有限:瀏覽器是發現如果解析不了纔會啓用下載,如果是HTML等不會下載。
2、缺點2:a標籤下載的文件存儲路徑會需要通過href屬性寫出來,這樣會暴露服務器存儲數據的位置(不安全)
PHP下載:讀取文件內容,以文件流的形式傳遞給瀏覽器:在響應頭中告知瀏覽器不要解析,激活下載框實現下載
1)指定瀏覽器解析字集
2)設定響應頭:
a)設定文件返回類型:image/jpg ||application/octem-stream
b)設定返回文件計算方式:Accept-ranges:bytes
c)設定下載提示: Content-disposition:attachment;filename=’文件名字’
d)設定文件大小:Accept-length:文件大小(字節)
3)讀取文件
4)輸出文件
方式1:如果文件較小,可以使用:file_get_contents
方式2:如果文件比較大或者網絡不好,可以使用:資源指針