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