1. 程式人生 > >PHP強化之12 - 檔案及目錄操作

PHP強化之12 - 檔案及目錄操作

一、目錄操作

1、目錄控制代碼

1)開啟目錄控制代碼
resource opendir ( string $path [, resource $context ] )
開啟一個目錄控制代碼,可用於之後的 closedir(),readdir() 和 rewinddir() 呼叫中。如果成功則返回目錄控制代碼的 resource,失敗則返回 FALSE。

2)從目錄控制代碼中讀取條目
string readdir ([ resource $dir_handle ] )
返回目錄中下一個檔案的檔名。檔名以在檔案系統中的排序返回。成功則返回檔名 或者在失敗時返回 FALSE。

3)關閉目錄控制代碼
void closedir ([ resource $dir_handle ] )
關閉由 dir_handle 指定的目錄流。流必須之前被 opendir() 所開啟。

2、列出指定路徑中的檔案和目錄

array scandir ( string $directory [, int $sorting_order [, resource $context ]] )
返回一個 array,包含有 directory 中的檔案和目錄。

注意:
1)但不包子級。
2)’.‘與’…'也會被返回。

優點:不需要建立目錄控制代碼。

3、新建與刪除目錄

1)新建目錄
bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $context ]]] )


預設的 mode 是 0777,意味著最大可能的訪問權。

2)刪除目錄
bool rmdir ( string $dirname [, resource $context ] )
嘗試刪除 dirname 所指定的目錄。 該目錄必須是空的,而且要有相應的許可權。 失敗時會產生一個 E_WARNING 級別的錯誤。

4、其它函式

1) 判斷是否是目錄
bool is_dir ( string $filename )
判斷給定檔名是否是一個目錄。
如果檔名存在並且為目錄則返回 TRUE。如果 filename 是一個相對路徑,則按照當前工作目錄檢查其相對路徑。

2)取得當前工作目錄
string getcwd ( void )


成功則返回當前工作目錄,失敗返回 FALSE。如果 directory 不是個目錄,則返回布林值 FALSE 並生成一條 E_WARNING 級的錯誤。

在某些 Unix 的變種下,如果任何父目錄沒有設定可讀或搜尋模式,即使當前目錄設定了,getcwd() 還是會返回 FALSE。

二、 檔案操作

1、檔案指標

1)開啟檔案或者URL資源
resource fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] )

mode常用引數:

mode 說明
‘r’ 只讀方式開啟,將檔案指標指向檔案頭;該檔案必須存在。
‘r+’ 讀寫方式開啟,將檔案指標指向檔案頭;該檔案必須存在。
‘w’ 寫入方式開啟,將檔案指標指向檔案頭並將檔案大小截為零。如果檔案不存在則嘗試建立之。
‘w+’ 讀寫方式開啟,其他的行為和 ‘w’ 一樣。
‘a’ 寫入方式開啟,將檔案指標指向檔案末尾。如果檔案不存在則嘗試建立之。
‘a+’ 讀寫方式開啟,其他的行為和 ‘a’ 一樣。
‘x’ 建立並以寫入方式開啟,將檔案指標指向檔案頭。如果檔案已存在,則 fopen() 呼叫失敗並返回 FALSE,並生成一條 E_WARNING 級別的錯誤資訊。如果檔案不存在則嘗試建立之。
‘x+’ 建立並以讀寫方式開啟,其他的行為和 ‘x’ 一樣。

Windows 下提供了一個文字轉換標記(‘t’)可以透明地將 \n 轉換為 \r\n。與此對應還可以使用 ‘b’ 來強制使用二進位制模式,這樣就不會轉換資料。要使用這些標記,要麼用 ‘b’ 或者用 ‘t’ 作為 mode 引數的最後一個字元。(不建議使用t)

2)讀取檔案
string fread ( resource $handle , int $length )
fread() 從檔案指標 handle 讀取最多 length 個位元組。 該函式在遇上以下情況時停止讀取檔案:
– 讀取了 length 個位元組
– 到達了檔案末尾(EOF)

注意:是從檔案指標的指標處開始讀取,並不一定是檔案開頭。

3)寫入檔案
int fwrite ( resource $handle , string $string [, int $length ] )
fwrite() 把 string 的內容寫入 檔案指標 handle 處。
fputs()fwrite()的別名。

4)關閉檔案
bool fclose ( resource $handle )
handle檔案指標必須有效,並且是通過 fopen() 或 fsockopen() 成功開啟的。

5)倒回檔案指標的位置
bool rewind ( resource $handle )
將 handle 的檔案位置指標設為檔案流的開頭。

如果將檔案以附加(“a” 或者 “a+”)模式開啟,寫入檔案的任何資料總是會被附加在後面,不管檔案指標的位置。

6)測試檔案指標是否到了檔案結束的位置
bool feof ( resource $handle )
如果檔案指標到了 EOF 或者出錯時則返回 TRUE,否則返回一個錯誤(包括 socket 超時),其它情況則返回 FALSE。

7)例子

//在檔案的頭部插入一段字串:
$file = './demo_text1.txt';
$h = fopen($file,'r');
$content = fread($h,filesize($file));
$text = "Hi , nosee! \n".$content;
fclose($h);
$h = fopen($file,'w');
fwrite($h,$text);
fclose($h);

2、不需要fopen開啟的函式

1)file_get_contents
string file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )
file_get_contents() 函式是用來將檔案的內容讀入到一個字串中的首選方法。如果作業系統支援還會使用記憶體對映技術來增強效能。

2)file_put_contents
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
將一個字串寫入檔案。

注意:當flags的值為FILE_APPEND時,表示如果檔案 filename 已經存在,則追加資料而不是覆蓋。

3)file
array file ( string $filename [, int $flags = 0 [, resource $context ]] )
把整個檔案讀入一個數組中。

可選引數 flags 可以是以下一個或多個常量:
– FILE_USE_INCLUDE_PATH 在 include_path 中查詢檔案。
– FILE_IGNORE_NEW_LINES 在陣列每個元素的末尾不要新增換行符
– FILE_SKIP_EMPTY_LINES 跳過空行

4)readfile
int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] )
讀取檔案並寫入到輸出緩衝。

3、檔案資訊

1)檔案大小
int filesize ( string $filename )
返回檔案大小的位元組數。如果出錯返回 FALSE 並生成一條 E_WARNING 級的錯誤。

2)檔案的型別
string filetype ( string $filename )
返回檔案的型別。 可能的值有 fifo,char,dir,block,link,file 和 unknown。

3)檔案路徑的資訊
mixed pathinfo ( string $path [, int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME ] )
pathinfo返回一個關聯陣列包含有 path 的資訊。返回關聯陣列還是字串取決於 options。

如果沒有傳入 options ,將會返回包括以下單元的陣列:
array:dirname,basename 和 extension(如果有),以 及filename。

4)檔案的時間
int filemtime ( string $filename )
返回檔案中的資料塊上次被寫入的時間,也就是說,檔案的內容上次被修改的時間。

int fileatime ( string $filename )
取得檔案的上次訪問時間。

int filectime ( string $filename )
取得檔案的 inode 修改時間。(Note:注意某些 Unix 說明文字中把 ctime 說成是該檔案建立的時間,這是錯的。在大多數 Unix 檔案系統中沒有 Unix 檔案的建立時間。)

5)刪除檔案
bool unlink ( string $filename [, resource $context ] )
刪除 filename。和 Unix C 的 unlink() 函式相似。

三、其它函式

1)拷貝檔案
bool copy ( string $source , string $dest [, resource $context ] )
將檔案從 source 拷貝到 dest。如果要移動檔案的話,請使用 rename() 函式。

2)重新命名檔案或目錄
bool rename ( string $oldname , string $newname [, resource $context ] )
嘗試把 oldname 重新命名為 newname。

3)檢查檔案或目錄是否存在
bool file_exists ( string $filename )

4)判斷檔名許可權
判斷給定檔名是否存在並且可讀:
bool is_readable ( string $filename )

判斷給定的檔名是否可寫:
bool is_writable ( string $filename )
如果檔案存在並且可寫則返回 TRUE。filename 引數可以是一個允許進行是否可寫檢查的目錄名。

判斷給定檔名是否可執行:
bool is_executable ( string $filename )

四、經典例項

1、列出一個目錄裡的所有檔案及目錄(包括子目錄裡面的)

$dir = '/var/www/html';
function loop_dir($dir){
  $handle = opendir($dir);
  if ($handle) {
    while (false !== ($file = readdir($handle))) {
      if($file != '.' && $file != '..'){
        echo "$file \n";
        if(filetype($dir.'/'.$file) == 'dir'){
          loop_dir($dir.'/'.$file);
        }
      }
    }
  }
}
loop_dir($dir);
closedir();

或者可以使用scandir函式:

$dir = '/var/www/html';
function loop_dir($dir){
  static $array = []; 
  $dir_arr = scandir($dir);
  if ($dir_arr) {
    foreach($dir_arr as $val){
        if($val != '.' && $val != '..'){
          if(filetype($dir.'/'.$val) == 'dir'){
            $array[] = substr($dir.'/'.$val.'/',14);
            loop_dir($dir.'/'.$val);
          }else{
            $array[] = substr($dir.'/'.$val,14);
          }
        }   
    }   
  }
  return $array;
}
$a = loop_dir($dir);
var_dump($a);

返回結果如下:

array (size=10)
  0 => string '.demo21.php.swp' (length=15)
  1 => string 'aaa/' (length=4)
  2 => string 'aaa/a1/' (length=7)
  3 => string 'aaa/a2/' (length=7)
  4 => string 'aaa/a3/' (length=7)
  5 => string 'bbb/' (length=4)
  6 => string 'demo20.php' (length=10)
  7 => string 'demo21.php' (length=10)
  8 => string 'demo_text1.txt' (length=14)
  9 => string 'index.html' (length=10)

2、大檔案讀取方法

$fp = fopen($filename,'r');
$buffer = 2048;
while(!feof($fp)){
  $str = fread($fp,$buffer);
  //$str = str_replace("\r\n","<br />",$str);//換行符轉換
  echo $str;
}
fclose($fp);

參考

官方手冊:
http://php.net/manual/zh/ref.filesystem.php
http://php.net/manual/zh/ref.dir.php