|
|
|
|
|
本人一直使用的是asp和.net環(huán)境,php比較少使用。如果用asp或asp.net來進行文件操作,我還是比較有經(jīng)驗的。今天由于需要,我得在php環(huán)境下做一次文件的讀寫操作,這對于我來說還是第一次。
雖然在寫程序時信心十足,但是當運行起來時卻發(fā)現(xiàn)沒那么簡單。
路徑問題導(dǎo)致fopen() 創(chuàng)建和寫入文件失敗
首先是在本地測試程序,程序如下:
<?php
$fileDir = '/phpDemo/fopen.txt';
$str ='testing';
$h = fopen($fileDir,'w+');
if(fwrite($h,$str))
{
echo '文件寫入成功';
}
fclose($h);
?>
但卻沒有執(zhí)行成功,提示“failed to open stream: No such file or directory ”,即是文件路徑不對,問題應(yīng)該是這句
$fileDir = '/phpDemo/fopen.txt';
我改為
$fileDir = '../phpDemo/fopen.txt';
終于成功了。
不過,上述的相對路徑的寫法,不是我的習(xí)慣,我比較喜歡用絕對路徑。查了下,我發(fā)現(xiàn)可以用如下方式來寫文件的路徑:
$RootDir = $_SERVER['DOCUMENT_ROOT'];
$fileDir = $RootDir.'\phpDemo\fopen.txt';
這個方法是首先定義了根目錄,再寫出文件的絕對路徑,更通用,也方便管理。
不可忽視的權(quán)限問題
本地測試通過,原以為上傳到空間后會很順利,誰知竟然不成功!是什么新的問題又出現(xiàn)了?
根據(jù)提示,是沒有權(quán)限。
原來,空間里的目錄寫權(quán)限沒有打開。這個已經(jīng)不是php的問題了。
知識擴充
fopen
fopen — 打開文件或者URL。
格式:
fopen(string $filename , string $mode)
fopen() 將 filename 指定的名字資源綁定到一個流上。
filename可以是一個本地文件,也可以是一個URL。
如果filename 指定的是一個本地文件,該文件必須是 PHP 可以訪問的,并且文件訪問權(quán)限允許該訪問。
如果filename 指定的是一個URL,PHP 將檢查并確認 allow_url_fopen 已被激活。如果關(guān)閉了,PHP 將發(fā)出一個警告,而 fopen 的調(diào)用則失敗。(fopen()和file_get_contents()打開URL獲得網(wǎng)頁內(nèi)容的用法區(qū)別)
fopen() 中 mode 的可能值列表
mode | 說明 |
'r' | 只讀方式打開,將文件指針指向文件頭。 |
'r+' | 讀寫方式打開,將文件指針指向文件頭。 |
'a' | 寫入方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創(chuàng)建之。 |
'a+' | 讀寫方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創(chuàng)建之。 |
'w' | 寫入方式打開,將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建之。 |
'w+' | 讀寫方式打開,將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建之。 |
返回值
成功時返回文件指針資源(如何調(diào)用fopen()打開的資源),如果打開失敗,本函數(shù)返回 FALSE。
錯誤/異常
如果打開失敗,會產(chǎn)生一個 E_WARNING 錯誤??梢?a target="_blank" href="http://m.howtostagehomes.com/tutorial/php/2013/060736/">通過 @ 來屏蔽錯誤。
有時我們會看到,fopen中mode值包含一個“b”字符,例如“wb”,這是怎么回事呢?
這是因為:
不同的操作系統(tǒng)家族具有不同的行結(jié)束習(xí)慣。當寫入一個文本文件并想插入一個新行時,需要使用符合操作系統(tǒng)的行結(jié)束符號。基于 Unix 的系統(tǒng)使用 \n 作為行結(jié)束字符,基于 Windows 的系統(tǒng)使用 \r\n 作為行結(jié)束字符,基于 Macintosh 的系統(tǒng)使用 \r 作為行結(jié)束字符。
如果寫入文件時使用了錯誤的行結(jié)束符號,則其它應(yīng)用程序打開這些文件時可能會表現(xiàn)得很怪異。
Windows 下提供了一個文本轉(zhuǎn)換標記('t')可以透明地將 \n 轉(zhuǎn)換為 \r\n。與此對應(yīng)還可以使用 'b' 來強制使用二進制模式,這樣就不會轉(zhuǎn)換數(shù)據(jù)。要使用這些標記,要么用 'b' 或者用 't' 作為 mode 參數(shù)的最后一個字符。
默認的轉(zhuǎn)換模式依賴于 SAPI 和所使用的 PHP 版本,因此為了便于移植鼓勵總是指定恰當?shù)臉擞?。如果是操作純文本文件并在腳本中使用了 \n 作為行結(jié)束符,但還要期望這些文件可以被其它應(yīng)用程序例如 Notepad 讀取,則在 mode 中使用 't'。在所有其它情況下使用 'b'。
在操作二進制文件時如果沒有指定 'b' 標記,可能會碰到一些奇怪的問題,包括壞掉的圖片文件以及關(guān)于 \r\n 字符的奇怪問題。
為移植性考慮,強烈建議在用 fopen() 打開文件時總是使用 'b' 標記。