2017年3月31日 星期五

php fopen() 開啟、建立檔案

開啟(建立)檔案

fopen():打開文件檔案或是 url 網址,如果打開失敗,函數返回 false
語法:
fopen filename , mode , include_path , context )
  • 參數說明:
  • filename:必要參數。要打開的文件(本機中須使用絕對或相對路徑)或url網址。
  • mode:必要參數。打開文件時所使用的開啟方式(註1)。
  • include_path:此參數可省略。如果也需要在 include_path 中檢索文件的話,可以將該參數設為 1 或 TRUE。
  • context:此參數可省略。在 PHP 5.0.0 中增加了對上下文(context)的支持。
註1
mode說明
"r"以唯讀方式打開檔案,將檔案指針指向檔案頭部。
"r+"以讀寫方式打開檔案,將檔案指針指向檔案頭部。
"w"以寫入方式打開檔案,將檔案指針指向檔案頭部並將檔案大小截為零(先清空內容再寫入)。如果檔案不存在則嘗試建立檔案
"w+"以讀寫方式打開檔案,將檔案指針指向檔案頭部並將檔案大小截為零(先清空檔案內容再寫入)。如果檔案不存在則嘗試建立檔案
"a"以寫入方式打開檔案,將檔案指針指向檔案末尾。如果檔案不存在則嘗試建立檔案
"a+"以讀寫方式打開檔案,將檔案指針指向檔案末尾。如果檔案不存在則嘗試建立檔案
"x"創建並以寫入方式打開檔案,將檔案指針指向檔案頭。如果檔案已存在,則 fopen() 調用失敗並返回 FALSE,並生成一條 E_WARNING 級別的錯誤信息。如果檔案不存在則嘗試建立檔案。這和給 底層的 open(2) 系統調用指定 O_EXCL|O_CREAT 標記是等價的。此選項被 PHP 4.3.2 以及以後的版本所支持,僅能用於本地文件。
"x+"建立並以讀寫方式打開檔案,其他的行為和 'x' 一樣。
注意事項:不同的操作系統具有不同的「行」結束習慣。當寫入一個文本文件並想插入一個新行時,需要使用符合操作系統的行結束符號。
  • Unix 的系統使用\n 作為行結束字符(簡單說就是「斷行」)
  • Windows 的系統使用\r\n 作為行結束字符
  • Macintosh 的系統使用 \r 作為行結束字符。
如果寫入文件時使用了錯誤的行結束符號,則其它應用程序打開這些文件時可能會表現得很怪異。
備註:一般所謂斷行 \n ,請試的使用 echo "\n"; 指令印出斷行後,檢視原始檔你便可看到斷行效果

關閉檔案

fclose():關閉一個打開的文件。
 fclose( file )
參數說明:
file:要關閉的文件檔案。
使用是fopen()打開的 文件如果沒有用fclose()關閉會如何?
即使你沒有用fclose()關閉也不要緊~因為php的資源會在腳本結束的時候全部釋放,因此普遍的情況都可以省略fclose
但是這不表示fcolse()就沒有用了~用fclose()關閉是因為可以減少發生文件不同步現象的幾率!

建立檔案範例:

寫入檔案

fwrite):將資料寫入檔案內
fwritefilename , string )
  • 參數說明:
  • filename:開啟的檔案文件
  • string:寫入文件內的資料
範例:

 以 fopen() 函數所建立的檔案,預設編碼與建立檔案時的程式本身編碼是一樣的,編碼問題常會讓人陷入一種迷思,這點要特別注意。關於亂碼問題請查看html 及 php 程式 utf-8 編碼亂碼說明

讀取檔案(一)

file( ):把整個文件讀入到一個陣列中
語法:
filepath , include_path , context )
  • path:不可省略,要讀取的文件。
  • include_path:可省略。如果也想在 include_path 中搜尋文件的話,可以將該參數設為 "1"。
  • context:可省略。返回的陣列中每一行都包括了行結束符,因此如果不需要行結束符時還需要使用 rtrim() 函數。

讀取檔案(二)

fgets():從文件指針中讀取一行
語法:
fgetsfile , length )
  • 參數說明:
  • file:必填參數,要讀取的文件。
  • length:可省略參數。要讀取的字節數(byte)。默認是 1024 字節。
    從 file 指向的文件中讀取一行並返回長度最多為 length - 1 字節的字符串。碰到換行符(包括在返回值中)、EOF 或者已經讀取了 length - 1 字節後停止(看先碰到那一種情況)。如果沒有指定 length,則默認為 1K,或者說 1024 字節。
fgets()範例:

讀取檔案(三)

fread():讀取文件(可安全用於二進制文件)。
語法:
freadfile,length )
  • 參數說明:
  • file:必備參數。讀取打開的文件內容。
  • length:要讀取的最大字節數。
    從文件指針 file 讀取最多 length 個字節。該函數在讀取完最多 length 個字節數,或到達 EOF 的時候,或(對於網絡流)當一個包可用時,或(在打開用戶空間流之後)已讀取了 8192 個字節時就會停止讀取文件,視乎先碰到哪種情況。
    返回所讀取的字符串,如果出錯返回 false。
  • 提示:如果只是想將一個文件的內容讀入到一個字符串中,請使用 file_get_contents(),它的性能比 fread() 好得多。
fread() 範例:

取得檔案大小

filesize():取得檔案文件大小(byte)
語法:
filesize ( filename )
語法說明:
filename:必備參數,檔案所在路徑。
範例:

計算檔案陣列數

sizeof()
語法:
sizeof( array mode )
  • 參數說明:
  • array:必備參數。陣列。
  • mode:可省略參數。
    規定模式。可能的值:
    0 - 默認。不計數多維陣列中的所有元素。
    1 - 遞歸地計數陣列中元素的數目(計算多維陣列中的所有元素)。
範例一:
範例二

檔案鎖

flock() 函數鎖定或釋放檔案文件。
若成功,則返回 true。若失敗,則返回 false。
語法:
flockfile lock block )
參數描述
file必需。要鎖定或釋放之檔案文件
lock必需。鎖定的類型。為下列值之一:
LOCK_SH 取得共享鎖定(讀取的程序)。
LOCK_EX 取得獨佔鎖定(寫入的程序)。
LOCK_UN 釋放鎖定(無論共享或獨佔)。
如果不希望 flock() 在鎖定時堵塞,則是 LOCK_NB(Windows 上還不支持)。
block可選。若設置為 1 或 true,則當進行鎖定時阻擋其他進程。
此指令可用來鎖定打開之檔案文件,通常若是在多線程時(很多連線以 fopen 開啟同一檔案),舉例原程式為 fopen("xxx.txt","w"); 假設此 xxx.txt 檔案原本內容有文字 123,若甲先開啟此程式,在剛開啟的那段時間(一直到未寫入關檔前都算),php會先將此檔案清空,那麼此檔案內容會變成空白,此時,若乙剛好又使用此程式,那麼乙一開始讀到的 xxx.txt 檔案就會是空白內容,而不會是 123,而後,當甲關寫入資料檔後,乙也寫入資料關檔後,將造成後面寫入的資料為不完整或不確實!
因為伺服器處理程式的時間非常快速,通常若單線程不會有此問題發生,但若站上人數很多同時在使用同一檔案進行讀取寫入動作時,此問題便可見到,下面我們列一段程式碼來模擬剛好檔案被開啟的狀況
先新增兩頁命名為 a.php 及 b.php 以及一文字檔案 abc.txt 檔於相同的資料夾內,程式碼及文字檔內容分別如下:
你可先開啟 a.php 後,再另外新增頁面開啟 b.php,然後重讀 b.php 多次,便可以發現,當 a.php 開啟檔案後,以 b.php 讀取 abc.txt 檔案內容是空的,如果檔案沒加鎖的狀況,在此時另位使用者又開啟了此檔案,則檔案就會發生內容不正確的現象。

再來看另一個範例:
請自行建立 1.php 、2.php 兩程式頁面及 tmp.txt 空白檔案在同一個資料夾內,然後程式碼分別為:
好的,我們現在先以瀏覽器打開 1.php,第一次執行時,tmp.txt 檔案因為本來就是空白檔,所以同時另開一頁面查看 2.php 為空白是很正常,等到 1.php 執行完畢(10秒鐘,可自改...若你反應太慢可改 60秒),再打開 2.php 就可以看到 tmp.txt 內記錄的資料,重複上面動作,再執行 1.php 後,馬上再以另一頁面開啟 2.php ,就會發生錯誤現象了,因為 2.php 會讀取 tmp.txt 檔案內容,按道理來講,tmp.txt 在第一次寫入檔案動作時,裡面早就有資料了,第二次 2.php 應該是可以讀到 tmp.txt 的資料的,但這裡卻沒讀到,表示程式有發生錯誤囉!
好吧!知錯能改,善莫大焉,浪子回頭金不換,遷善遠罪,棄邪歸正,放下屠刀。。。疑?!抱歉,小學生搞錯方向了,我們不是在探討國語文。。好吧!我們改一下 2.php 改成下面代碼:
我們再重複先開啟 1.php 頁面後,同時另一頁打開 2.php ,這時候你將發現,2.php 會等到 1.php 執行動作完畢後,讀取 tmp.txt 檔案內容,這樣似乎是正確了,不過這還得等到 1.php 釋放檔案後(10秒),才能看到 2.php 內容,等太久了怎麼辦?因為 LOCK_EX 此指令會獨佔,因此我們再改一次 2.php 內容如下:
2.php 最終改成這樣,就是若 tmp.txt 檔案被堵塞或鎖定後,就會顯示出此檔案被使用的訊息了,用此種方式則可以保護你的檔案資料不會發生錯誤情況囉!
當然,這裡都僅是示範,有道是「戲法人人會變,各有巧妙不同」,程式碼也是一樣,如何撰寫,完全是看你個人囉!不過安全很重要,網路資安是非常重要的一環唷,切記呀!
引入資料來源:https://scriptmarks.com/php-fopen-開啟、建立檔案/


沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。

cas server 一直圈圈或取得狀態異常

重點: cas server 不能開 VPN,會造成取的來源 dns 異常,會一直轉圈圈或等很久。