麻辣家族討論版版's Archiver

小誌 發表於 2010-5-16 14:06

(PHP+IIS+MsSQL教學第21篇) 資料儲存與檔案管理 下篇

[color=darkorange][size=5][b]檔案處理函數[/b][/size][/color]
fopen()函數允許PHP程式存取網頁伺服器上的檔案,實務上應用大部份以文字檔為主。
fopen() 函數格式[code]resource fopen ( string filename, string mode [, int use_include_path [, resource zcontext]])[/code]fopen()函數只負責開啟檔案,若想讀取檔案內容,則必須配合fread()函數一起使用,若fopen()函數正確執行則回傳值為1,反之回傳值為0。語法如下所示:[code]$f=fopen(“檔案路徑與名稱”,”開啟的模式”);[/code]「開啟的模式」有下列數種:
[table]
[tr][td=1,1,73][p=30, 2, center][size=2]設定值[/size][/p][/td][td=1,1,442][p=30, 2, center][size=2]說明[/size][/p][/td][/tr]
[tr][td=1,1,73][p=30, 2, center][color=#000000][size=2]a[/size][/color][/p][/td][td=1,1,442][p=30, 2, left][color=#000000][size=2]檔案開啟成附加寫入模式檔案內內容保留,資料會從檔案最後面寫入,若檔案不存在則自動建立[/size][/color][/p][/td][/tr]
[tr][td=1,1,73][p=30, 2, center][color=#000000][size=2]a+[/size][/color][/p][/td][td=1,1,442][p=30, 2, left][color=#000000][size=2]檔案開啟成附加讀取模式檔案內內容保留,資料會從檔案最後面寫入,若檔案不存在則自動建立[/size][/color][/p][/td][/tr]
[tr][td=1,1,73][p=30, 2, center][color=#000000][size=2]r[/size][/color][/p][/td][td=1,1,442][p=30, 2, left][color=#000000][size=2]檔案開啟成唯讀模式[/size][/color][/p][/td][/tr]
[tr][td=1,1,73][p=30, 2, center][color=#000000][size=2]r+[/size][/color][/p][/td][td=1,1,442][p=30, 2, left][color=#000000][size=2]檔案開啟成可讀可寫模式,資料會從檔案最前面寫入[/size][/color][/p][/td][/tr]
[tr][td=1,1,73][p=30, 2, center][color=#000000][size=2]w[/size][/color][/p][/td][td=1,1,442][p=30, 2, left][color=#000000][size=2]開啟成唯寫的檔案,原檔案內容會被清除,若檔案不存在則自動建立[/size][/color][/p][/td][/tr]
[tr][td=1,1,73][p=30, 2, center][color=#000000][size=2]w+[/size][/color][/p][/td][td=1,1,442][p=30, 2, left][color=#000000][size=2]檔案開啟成可讀可寫模式,原檔案內容會被清除,若檔案不存在則自動建立[/size][/color][/p][/td][/tr]
[/table]

例如:[code]<?
$myfile=fopen("test.txt","r"); //註1
$myfile=fopen("count.txt","a"); //註2
$myfile=fopen("c:\\myfile\\test.txt","r");//註1
$myfile=fopen("mem.txt","w");//註2
?>[/code]註1:
當以「r」模式開啟檔案時,該檔案必須是已建立完成,不可是不存在的檔案,否則會發生「failed to create stream: No such file or directory」的錯誤,如下圖:
[attach]466[/attach]

註2:
若您希望開啟的檔案不存在時,能夠自動建立該檔案,請特別注意目錄的使用權限!預設是不允許「寫入」動作(不能建立檔案,改變檔案內容),因此會有「failed to create stream: Permission denied」的錯誤。
[attach]467[/attach]

在Window 2000中,您應該在自動建立檔案所在的目錄圖示上按下滑鼠右鍵,選取「內容」=>點選「安全」頁籤=>「名稱」欄位中選取『Users』項目=>『權限』欄位裡,把「修改」、「讀取」與「寫入」這三個項目的『允許』核取起來:[attach]468[/attach]

經過以上設定後,您就可以在指定的目錄下,建立檔案,修改檔案,與讀取檔案資料了!若「名稱」欄位中沒有『Users』項目則可按下「新增」按鈕來增加使用者項目:
[attach]469[/attach]



在Window XP中,「內容」項目中預設是沒有「安全性」這個頁籤的,在設定目錄權限時則需先將「安全性」頁籤變出來。
點選「我的電腦」=>工具=>資料夾選項:
[attach]470[/attach]


在「資料夾選項」視窗中選取『檢視』頁籤=>找到「使用簡易檔案共用(建議使用)」這個項目,並取消這個項目的核取,這樣一來,資料夾的「內容」視窗中就有「安全性」這個頁籤了:
[attach]471[/attach]


在「安全性」頁籤的『群組或使用者名稱』欄位中選取『Users』項目=>『Users的權限』欄位裡,把「修改」、「讀取」與「寫入」這三個項目的『允許』核取起來:
[attach]472[/attach]


經過以上設定後,您就可以在window XP作業系統中,於指定的目錄下,建立檔案,修改檔案,與讀取檔案資料了。



[color=Red]提示:[/color] fopen()函數並不限定開啟本地端檔案,亦可開啟遠端檔案,例如:[code]<?
$myfile=fopen("http://www.twbts.com/test.txt","r");
$hisfile=fopen("http://www.twbts.com/","w+");
$yourfile=fopen("ftp://user:psw@test.net/","r");
?>[/code]

小誌 發表於 2010-5-16 14:22

[color=DarkOrange][size=5][b]檔案操作的方法[/b][/size][/color]
如果您已經設定好目錄的操作權限,那您就可以對目錄下的檔案進行複製、更名、刪除等動作,這一切操作可是跟fopen()函數無關喔。


[color=Green][size=4][b]複製檔案[/b][/size][/color]
要複製檔案的操作必須使用copy()函數:
copy() 函數格式[code]int copy ( string source, string dest)[/code][list]
[*]source(來源檔案):必須是已存在的檔案,否則會產生『找不到來源檔案』的錯誤。
[*]dest(目的檔案):檔案若已存在,則會被覆蓋,若為唯讀屬性或被鎖定的檔案,則會產生『沒有使用權限』的錯誤。
[*]如果檔案複製成功則copy()函數回傳True,反之回傳False。
[/list]
copyfile.php[code]<?
$myfile="count.txt";
$bakfile="myfile.bak";
if (copy($myfile, $bakfile))
  {
   echo "已經複製$myfile 成為 $bakfile";
  }
else
  {
   echo "檔案複製失敗";
  }
?>[/code][color=Green][size=4][b]刪除檔案[/b][/size][/color]
若想永久刪除檔案,則使用unlink()函數,語法如下:
unlink() 函數格式[code]int unlink ( string filename)[/code][list]
[*]filename(被刪除的檔案):必須為已存在的檔案,否則會產生『找不到來源檔』的錯誤。  
[*]如果檔案刪除成功則unlink()函數回傳True,反之回傳False。
[/list]
範例程式碼如下:
deletefile.php[code]<?
$myfile="count.txt";
if (unlink($myfile))
  {
   echo "已成功刪除檔案";
  }
else
  {
   echo "檔案刪除失敗";
  }
?>[/code][color=Green][size=4][b]檔案更名[/b][/size][/color]
如果要更改檔案名稱則可透過rename()函數,語法如下:
rename() 函數格式[code]bool rename ( string oldname, string newname)[/code][list]
[*]oldname(來源檔案):必須是已存在的檔案,否則會產生『找不到來源檔』的錯誤。
[*]newname(目的檔案):必須是不存在的檔案,否則會產生『檔案已存在』的錯誤。
[*]如果檔案更名成功則rename()函數回傳True,反之回傳False。
[/list]
範例程式碼如下:
renamefile.php[code]<?
$myfile="count.txt";
if (rename($myfile,"count.bak"))
  {
   echo "檔案已成功更名";
  }
else
  {
   echo "檔案更名失敗";
  }
?>[/code][color=Green][size=4][b]檢查檔案是否存在[/b][/size][/color]
file_exists()函數用於檢驗檔案是否存在,語法如下:
file_exists() 函數格式[code]bool file_exists ( string filename)[/code]檔案若存在,則傳回值為True,否則傳回False。

範例程式碼如下:
exfile.php[code]<?
$myfile="count.txt";
if (file_exists($myfile))
  {
   echo "檔案存在";
  }
else
  {
   echo "檔案不存在";
  }
?>[/code]當您在執行範例delfile.php或renamefile.php時,若來源檔案不存在時,在我們自訂的回應訊息之前都會秀出一段「檔案不存在」的錯誤訊息對吧!
[attach]473[/attach]

要避過這個訊息很簡單,只要再加上file_exists()函數即可,小誌就以範例renamefile.php修改給您看:
renamefile.php[code]<?
$myfile="count.txt";
if (file_exists($myfile))
  {
    if (rename($myfile,"count.bak"))
     {
      echo "檔案已成功更名";
     }
    else
     {
      echo "檔案更名失敗";
     }
  }
else
  {
   echo "檔案不存在";
  }
?>[/code]

小誌 發表於 2010-5-16 14:29

[color=DarkOrange][size=5][b]讀取檔案資料[/b][/size][/color]
不管是要從檔案中讀取資料,還是要將資料寫入檔案,您都要注意一件事:確認已使用fopen()函數成功的開啟某個檔案!


[size=4][color=Green][b]顯示檔案內容[/b][/color][/size]
當我們已經完成檔案的開啟動作後,可利用fpassthru()函數一次讀取全部的檔案資料並將這些資料輸出到網頁畫面中:
fpassthru() 函數格式[code]int fpassthru ( resource handle)[/code]例如:[code]<?
$myfile="contest.txt";
if (file_exists($myfile))
  {
    $file=fopen($myfile,"r");
    fpassthru($file);
  }
else
  {
   echo "檔案不存在";
  }
?>[/code][attach]474[/attach]



[color=Red]思考一下![/color]
在上例中,文字檔案內的資料輸出時,所有的字都連在一起了,可是原始的文字檔內容卻是分成兩行的耶!請問您:該如何讓輸出的資料能照原始檔案內容一般的分成兩行?



[color=Green][size=4][b]讀取檔案內容[/b][/size][/color]
利用fpassthru()函數會一次讀取全部的檔案並輸出,可是我不想全部輸出ㄚ,我可能只是要取出資料來利用,或是只要輸出部分檔案內容而已耶!這個時候我們可以改用「多字元讀取」與「單字元讀取」。
第一種多字元讀取方式是使用fread()函數:
fread() 函數格式[code]string fread ( resource handle, int length)[/code]例如:[code]<?
$myfile="contest.txt";
if (file_exists($myfile))
  {
    $file=fopen($myfile,"r");
    echo fread($file,20);
    fclose($file); //關閉已開啟的檔案
  }
else
  {
   echo "檔案不存在";
  }
?>[/code]上例:自檔案最前面開始抓回20個字元長度的資料,一個中文字算兩個字元,資料輸出後,若不再需要已開啟的檔案,則以「fclose()」函數關閉檔案。



第二種多字元讀取方式是使用fgets()函數:
fgets() 函數格式[code]string fgets ( resource handle [, int length])[/code]fgets()函數也可以讀取指定長度的資料,可是它的長度參數必須比我們要取的資料長度再多一個字元,例如:[code]<?
$myfile="contest.txt";
if (file_exists($myfile))
  {
    $file=fopen($myfile,"r");
    echo fgets($file,21); //其實只取得20個字元
    fclose($file);
  }
else
  {
   echo "檔案不存在";
  }
?>[/code]fgets()函數含有一個特點,如果讀取資料時遇到換行符號或檔案結尾,就會結束讀取動作。因此,fgets()函數也可稱它為「行讀取」函數。
我們可不可以利用fread()函數或fgets()函數把檔案內容全部讀出來?當然可以!我們可以利用「feof()」函數來判斷我們讀取的資料是否已到檔案結尾,如果是就停止讀取,反之就繼續讀取。
之前不是給您一個「思考一下」的問題嗎?您現在知道該如何解決了吧!沒錯!就是要利用fgets()函數的「行讀取」特性,fgets()函數每讀到換行符號就會結束讀取,這個時候,我們就加個「<br>」標籤:[code]<?
$myfile="contest.txt";
if (file_exists($myfile))
  {
    $file=fopen($myfile,"r");
     while(!feof($file))
      {
       echo fgets($file) . "<br>";
      }
    fclose($file);
  }
else
  {
   echo "檔案不存在";
  }
?>[/code][attach]475[/attach]


難道我真的不能使用fpassthru()函數一次讀取全部的檔案資料,並將這些資料依原來的段落格式輸出到網頁畫面中嗎?那倒也未必,文字檔案內的換行符號跟表單元件「多行文字輸入元件」一樣,都是「\r\n」,這個換行字元在我們輸出到瀏覽器時並不會有換行的效果,因此,輸出時應先使用「str_replace()」函數將這個換行字元「\r\n」替換成「<Br>」或「<P>」的HTML標籤符號。[code]<?
$myfile="contest.txt";
if (file_exists($myfile))
  {
    $file=fopen($myfile,"r");
    while(!feof($file))
     {
      echo str_replace("\r\n" ,"<br>" ,fread($file,20));
      }
    fclose($file);
  }
else
  {
   echo "檔案不存在";
  }
?>[/code]如果您喜歡一個字元一個字元慢慢的讀取也行,那就使用fgetc()函數吧!如果函數發生錯誤時回傳False。
fgetc() 函數格式[code]string fgetc ( resource handle)[/code]例如:[code]<?
$myfile="contest.txt";
if (file_exists($myfile))
  {
    $file=fopen($myfile,"r");
     while(!feof($file))
      {
       echo fgetc($file);
      }
    fclose($file);
  }
else
  {
   echo "檔案不存在";
  }
?>[/code][color=Green][size=4][b]移動讀取的位置[/b][/size][/color]
如果:我想取得檔案中特定位置特定長度的資料時該如何處理?例如:我要讀取檔案內第11個字元起,長度為20個字元的資料,該如何做?
當然就是先將讀取位置一到第11個字元上囉,要移動讀取位置可使用fseek()函數:
fseek() 函數格式[code]int fseek ( resource handle, int offset [, int whence])[/code]Offset參數是檔案開頭算起的偏移量,也就是我們要從哪裡開始讀取,設定了偏移量之後,我們再利用其他資料讀取函數來讀取特定長度的資料,例如:[code]<?
$myfile="contest.txt";
if (file_exists($myfile))
  {
    $file=fopen($myfile,"r");
     fseek($file,10); //設定讀取起始位置
     echo fgets($file,20);  //讀取指定長度的資料
    fclose($file);
  }
else
  {
   echo "檔案不存在";
  }
?>[/code]那我想知道:現在檔案資料讀取到哪個位置了,則可以使用ftell()函數來得知:
ftell() 函數格式[code]int ftell ( resource handle)[/code]ftell()函數回傳值是一個整數,也就是現在檔案資料讀取位置。

小誌 發表於 2010-5-16 14:33

[color=Green][b][size=4]將資料寫入檔案[/size][/b][/color]
要將資料寫入檔案最簡單了,直接使用fwrite()或fputs()函數就行了:
fwrite() 與fputs()函數格式[code]int fwrite ( resource handle, string string [, int length])
int fputs ( resource handle, string string [, int length])[/code]fwrite()與fputs()函數格式都一樣,使用的方式當然也都一樣,小制是比較喜歡fwrite()函式啦!例如:[code]<?
$myfile="writetest1.txt";
$word="我是被寫入的資料";

    $file=fopen($myfile,"w");
   fwrite($file,$word);
?>[/code]如果沒設定寫入長度參數,代表要將全部的資料都寫入到檔案中,若指定長度參數,則寫入的資料就只有我們所指定的長度資料:[code]<?
$myfile="writetest1.txt";
$word="我是被寫入的資料";

    $file=fopen($myfile,"w");
   fwrite($file,$word,4); //檔案內只有”我是”
?>[/code]

頁: [1]

麻辣家族討論版版為 麻辣學園 網站成員  由 昱得資訊工作室 © Since 1993 所提供