Board logo

標題: [教學] (PHP+IIS+MsSQL教學第21篇) 資料儲存與檔案管理 下篇 [打印本頁]

作者: 小誌    時間: 2010-5-16 14:06     標題: (PHP+IIS+MsSQL教學第21篇) 資料儲存與檔案管理 下篇

檔案處理函數
fopen()函數允許PHP程式存取網頁伺服器上的檔案,實務上應用大部份以文字檔為主。
fopen() 函數格式
  1. resource fopen ( string filename, string mode [, int use_include_path [, resource zcontext]])
複製代碼
fopen()函數只負責開啟檔案,若想讀取檔案內容,則必須配合fread()函數一起使用,若fopen()函數正確執行則回傳值為1,反之回傳值為0。語法如下所示:
  1. $f=fopen(“檔案路徑與名稱”,”開啟的模式”);
複製代碼
「開啟的模式」有下列數種:

設定值

說明

a

檔案開啟成附加寫入模式檔案內內容保留,資料會從檔案最後面寫入,若檔案不存在則自動建立

a+

檔案開啟成附加讀取模式檔案內內容保留,資料會從檔案最後面寫入,若檔案不存在則自動建立

r

檔案開啟成唯讀模式

r+

檔案開啟成可讀可寫模式,資料會從檔案最前面寫入

w

開啟成唯寫的檔案,原檔案內容會被清除,若檔案不存在則自動建立

w+

檔案開啟成可讀可寫模式,原檔案內容會被清除,若檔案不存在則自動建立



例如:
  1. <?
  2. $myfile=fopen("test.txt","r"); //註1
  3. $myfile=fopen("count.txt","a"); //註2
  4. $myfile=fopen("c:\\myfile\\test.txt","r");//註1
  5. $myfile=fopen("mem.txt","w");//註2
  6. ?>
複製代碼
註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作業系統中,於指定的目錄下,建立檔案,修改檔案,與讀取檔案資料了。



提示: fopen()函數並不限定開啟本地端檔案,亦可開啟遠端檔案,例如:
  1. <?
  2. $myfile=fopen("http://www.twbts.com/test.txt","r");
  3. $hisfile=fopen("http://www.twbts.com/","w+");
  4. $yourfile=fopen("ftp://user:[email protected]/","r");
  5. ?>
複製代碼

作者: 小誌    時間: 2010-5-16 14:22

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


複製檔案
要複製檔案的操作必須使用copy()函數:
copy() 函數格式
  1. int copy ( string source, string dest)
複製代碼

copyfile.php
  1. <?
  2. $myfile="count.txt";
  3. $bakfile="myfile.bak";
  4. if (copy($myfile, $bakfile))
  5.   {
  6.    echo "已經複製$myfile 成為 $bakfile";
  7.   }
  8. else
  9.   {
  10.    echo "檔案複製失敗";
  11.   }
  12. ?>
複製代碼
刪除檔案
若想永久刪除檔案,則使用unlink()函數,語法如下:
unlink() 函數格式
  1. int unlink ( string filename)
複製代碼

範例程式碼如下:
deletefile.php
  1. <?
  2. $myfile="count.txt";
  3. if (unlink($myfile))
  4.   {
  5.    echo "已成功刪除檔案";
  6.   }
  7. else
  8.   {
  9.    echo "檔案刪除失敗";
  10.   }
  11. ?>
複製代碼
檔案更名
如果要更改檔案名稱則可透過rename()函數,語法如下:
rename() 函數格式
  1. bool rename ( string oldname, string newname)
複製代碼

範例程式碼如下:
renamefile.php
  1. <?
  2. $myfile="count.txt";
  3. if (rename($myfile,"count.bak"))
  4.   {
  5.    echo "檔案已成功更名";
  6.   }
  7. else
  8.   {
  9.    echo "檔案更名失敗";
  10.   }
  11. ?>
複製代碼
檢查檔案是否存在
file_exists()函數用於檢驗檔案是否存在,語法如下:
file_exists() 函數格式
  1. bool file_exists ( string filename)
複製代碼
檔案若存在,則傳回值為True,否則傳回False。

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

要避過這個訊息很簡單,只要再加上file_exists()函數即可,小誌就以範例renamefile.php修改給您看:
renamefile.php
  1. <?
  2. $myfile="count.txt";
  3. if (file_exists($myfile))
  4.   {
  5.     if (rename($myfile,"count.bak"))
  6.      {
  7.       echo "檔案已成功更名";
  8.      }
  9.     else
  10.      {
  11.       echo "檔案更名失敗";
  12.      }
  13.   }
  14. else
  15.   {
  16.    echo "檔案不存在";
  17.   }
  18. ?>
複製代碼

作者: 小誌    時間: 2010-5-16 14:29

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


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



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



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



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


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

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

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

  4.     $file=fopen($myfile,"w");
  5.    fwrite($file,$word,4); //檔案內只有”我是”
  6. ?>
複製代碼





歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)