本期格言:
在當年還沒有資料庫存在的時候,讀寫檔案是我們程式員在空虛的夜晚唯一能乾的事情之一(也許不一定哦~~~)。所以即使現在這項技術變的有多麼的簡單、快捷和普通,我們依然要保持細緻的態度和嚴格的操守,千萬不要忽視它的重要性和嚴謹性。
本文開始:
關於讀檔案我有個小故事。早年工作室開辦初期,正是業務慌的時候,QQ上某好友介紹說他有個朋友單位要做網站,介紹給我做。我一聽很激動,立馬整理髮型掐滅煙頭,因為我朋友說那個客戶等下要和我視頻(這麼潮?)。又據說他是大企業的IT主管,很正規,要我重視一下,不要太頹廢。我特意拿出電動剃鬚刀颳了鬍子。
我當時很喜歡這種幾千大洋的網站生意,基本上是排排介面做做css,不超過100句php代碼。派個新手一個星期搞定即可,雖然可複用性和後續業務拓展根本談不上,但是一個月的煙酒茶錢肯定到手了。當然談肯定得我去談,讓新手去談,我晚上基本上只能在大排檔吃麻辣燙了。
視頻開,對面出現一個清秀男子,長相委婉,聲帶很細。互相很假的客套後,他驕傲的介紹了一下他所在的廠,很大,由於發展規模太快太快太快太快,現在想做一 個網站(我不知規模太快和想做網站有何太大聯絡)來貼合規模,末了發給我一個Excel,已經畫好了網站首頁結構圖,以前公司的小軟體都是他做的,由於他最近太忙太忙太忙太忙,所以這次想找個網路公司開發了,話末清秀男委婉的告訴我,他技術方面“很懂的哦~"。
一陣冷風吹過~~~。
我點開Excel,我佩服清秀男的“素描”功底,能在Excel把頁面結構圖畫出來並且還能畫的這麼形象的實屬少見。我表示認可,並說能按時交貨,同時我已經把該Excel發給了我的美工兼程式員,讓他照做,時間是3天。不過接下來清秀男的要求讓我差點想把台式機顯示屏給蓋上,他的要求是把圖片和文字直接貼在Excel裡面,然後在該Excel裡面建立多個活頁簿(當時我已經蒙了,不知道該用$sheet還是shit來表達”活頁簿“),首頁只需一個 PHP頁面,根據他的設定分別讀取Excel裡面的活頁簿。這樣就可以做到每隔一段時間使用者開啟的首頁都是不同的。從而多角度展現了他們廠業務的”多元化
“和創新。
清秀男在視頻中得意的笑容讓我很大限度上對我自己關於”可配置化、產品化“的設計思路有很大懷疑。我想拒絕這種外星人式的思維,可是清秀男堅持他的”理念“,他說他的設計已經得到他廠長充分的”高度評價“。
由於清秀男”轉賬支票“的魔力,讓我臣服了與他的這種”可配置化“思路。我只想說,他太牛了,我做不了大型企業的IT主管,是因為我真想不出用這種辦法來實現CMS概念中的模板切換。
當然我也不是傻子(讀Office檔案可不是很簡單的事情),我用了一個很簡單的辦法解決此問題。並順利的得到了轉賬支票。方法很簡單,用html基本頁面設計五個不同的清秀男要求的頁面,然後另存新檔5個不同的Excel(注意:雖然儲存的檔案尾碼是xls,但其實還是html檔案),用php分別讀取檔案展示之。當時的代碼如下:
<?php
$fileIndex=rand(1,5); //取一個隨機數,範圍是1到5
$fileName='index'.$fileIndex.'xls'; //拼湊一個檔案名稱,注意:從index1.xls.....index5.xls都放在網站根目錄下,和index.php同級
$getIndex=file_get_contents($fileName); //讀取檔案,
exit($getIndex); //輸出讀取檔案的內容,並展示出來
?>
這裡有幾個知識點:
1、rand 函數
取隨機數,參數是範圍rand(最小值,最大值)。例子中 就是從1到5 隨機產生一個數字。然後拼湊一個檔案名稱。如index1.xls,index2.xls,index3.xls,index4.xls,index5.xls,代表了我為清秀男設計了5個頁面分別另存了5個xls檔案。
既然講到了rand函數,就不得不擴充一下知識點: array_rand函數,(數組--array 我們在上一天已經唾沫橫飛的講過了,這裡就不贅述了)
上面隨機拼湊檔案的方式還可以用下面的方式
$file=array("index1.xls","index2.xls","index3.xls","index4.xls","index5.xls");
$fileName='index'.$file[array_rand($file,1)].'xls';
這說明 array_rand返回的是傳入的數組的索引值,而第二個參數代表返回幾個。如果是1則返回的是一個字元或數字變數,如果超過1,則會返回一個數組,該數組裡面會包含2個隨機索引值。
2、file_get_contents函數
這個函數很重要,我們絕對要記住,也是我們非常常用的一個檔案內容讀取函數。它代表一次性把檔案裡面的內容讀取出來,並讀取成數組。
記住:一次性。讀的過程中你沒法幹涉它。你想讓它讀到一半停下來幹點其他事情,兩個字“不行”。
記住:返回一定是一個字串。
如 $getFileContent=file_get_contents("index1.xls"); 這說明 清秀男的要求我滿足了。
這個函數的原型是:file_get_contents(path,include_path,context,start,max_length)
path:檔案的路徑,記住是從當前你“代碼”最終執行的頁面開始計算路徑,這裡"./"代表目前的目錄,"../"代表上一級目錄,"http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/" 這個代表上N級目錄(麻煩自己數一下吧)
include_path:很多教材和網上的文章都帶了一句如果要用include_path就填1。其他沒了。我想在這山寨橫行的年代,大家抄的太厲害了。其實include_path 是一個可設定環境變數,你可以用set_include_path設定,也可以用get_include_path獲得。作用是什麼呢其實很簡單,include_path就是你設定的一堆檔案夾路徑,為了引用或者索引方便。以上面這個例子,譬如你的網站部署在 D:/web/,裡面有個index.php, 理論上你的index1..index5.xls
也會放在D:/web/,這樣讀取只需要用file_get_contents("index1.xls").就可以,但是假設清秀男一定要你放在其他目錄也就是不放在網站目錄下,
譬如是 c:/清秀男的BT檔案/ ,我們千萬不能寫 file_get_contents("c:/清秀男的BT檔案/index1.xls"); 原因很簡單:在純潔的程式中出現"清秀男“三個字是多麼的猥瑣,再一個將來網站移植到Linux中就運行不起來了。
正確的方式是修改 php.ini
include_path = .:c:/清秀男的BT檔案:./其他檔案夾。移植到Linux中改設定檔即可。
這樣的話 上面的程式 依然可以寫成 file_get_contents("index1.xls",1); 儘管同級檔案夾沒有index1.xls,但是系統會在c:/清秀男的BT檔案/下去尋找index1.xls。
context:這是一個神一樣的參數。很多教材都是這麼說的:"一套可以修改流的行為的選項"。這句話比教科書上"資本主義”的概念以及另外一個同類某“主義”的概念解釋還要難懂。
實際上這個參數是這樣的。file_get_contents不光可以讀取本地檔案,還能讀取web檔案。如我們要讀取www.shenyisyn.org(註:作者簡陋的工作室網站)首頁源碼,這時我們會需要設定一些參數,如http參數:
$options = array(
'http'=>array(
'method'=>'GET',//代表使用GET模式訪問
'header'=>'Content-Type:text/html;charset=gb2312'.PHP_EOL.//代表編碼是中文gb2312
'Cookie:xxxxx'.PHP_EOL //帶cookie,假如你要攻擊我的網站 很可能會用到哦
)
);
$context = stream_context_create($options);
然後就可以使用file_get_contents("www.shenyisyn.org",0,$context"); 來直接擷取了。
由於真正要擷取網頁內容不推薦使用這個函數,並且也沒有真正的爬蟲或者索引軟體會使用php來幹,因此這裡就不多擴充解釋這個函數在擷取遠程地址時的用法。php應該讓它幹它最適合的事情,尤其我看到有些大牛用php案頭運行庫來做案頭軟體,Jesus Christ,鑽研精神值得讚揚,但是絕不推薦大家花過多精力去研究。有多餘的時間帶帶孩子騙騙老婆吧,或者大家一起討論討論如何“更進一步深化和發揚”精神文明建設來的更實際和高尚。
start,max_length:開始索引和擷取最大位元組數。很好理解但也沒啥太大用。
3、PHP_EOL
這個知識點還是有點小重要的。
\n 軟斷行符號:在Windows 中表示換行且回到下一行的最開始位置。在Linux、unix 中只表示換行,但不會回到下一行的開始位置。
\r 軟空格:
在Linux、unix 中表示返回到當行的最開始位置。在Mac OS 中表示換行且返回到下一行的最開始位置,相當於Windows 裡的 \n 的效果。
\t 跳格(移至下一列)
它們在雙引號或定界符表示的字串中有效,在單引號表示的字串中無效。
\r\n 一般一起用,用來表示鍵盤上的斷行符號鍵(Linux,Unix中),也可只用 \n(Windwos中),在Mac OS中用\r表示斷行符號!\t表示鍵盤上的“TAB”鍵。
檔案中的分行符號號:windows : \n linux,unix: \r\n
廢話了很久了,總結一下就是為了保證將來移植到不同平台方便。大家應該用 PHP_EOL來代替 \r或者\n或者\r\n. PHP會在不同平台中幫你自動解析。程式員一定要學會把繁瑣的事情交給系統來做。不要去記這些很有可能會搞混的東西。
4、PHP中檔案處理的其他函數,這裡簡單列舉一下,因為一般真實項目中很少會對檔案做過多的操作,所以有的函數用的真心不是很多。因此下面只是列舉一下:
- file(path,include_path,context) ---把檔案讀取,並讀取成數組,根據分行符號分割。上一天交過,這個函數真心不錯,對於txt檔案,直接可以讀取成數組,省的我們還要根據分行符號進行分隔。
- fopen(filename,mode,include_path,context).開啟檔案並返回控制代碼。有人會問 什麼叫控制代碼,
$file=fopen("檔案名稱"); 這個$file就是控制代碼。譬如,我的名字叫沈逸,我就是這個檔案,而我的名字就是控制代碼。沒有特殊含義,不要過於糾結,否則太糾結晚上容易起夜次數太多。
- fwrite(file,string,length) .寫檔案函數。大家可以通過度娘 看一下 file_put_contents和這個函數的區別。
- readfile(filename,include_path,context) 該函數讀入一個檔案並寫入到輸出緩衝.這個函數的特點是還會輸出 讀取檔案的位元組數。我很少用,因為以前很菜的時候把它當成了file_get_contents這個函數,結果在頁面中始終出現了一個詭異的數字,經過我日夜反思才發現了端倪,懊惱無比。
- filesize 返迴文件大小(位元組數). 這個函數有用,但是它會有緩衝。為啥呢?譬如按照清秀男的要求,測算了index1.xls的檔案大小是12306KB,不小心我吃頓飯的時間,清秀男手工把index1.xls加了點資料或者刪了,我如果吃完飯再來執行filesize('index1.xls')會發現還是12306KB。這就是緩衝,清楚緩衝需要使用clearstatcache();函數如
$size=filesize('index1.xls');
echo $size;
.....這裡清秀男悄悄的來修改了,修改完後,很不負責任的回家洗洗睡了。。。。
clearstatcache();//我必須清一下緩衝。
echo filesize('index1.xls'); //這樣就對了,
- feof(file) 函數檢測是否已到達檔案末尾。不常用,官方教材上說對於未知長度檔案的遍曆很有用,有誤導。用php絕對不應該去操作一些“未知長度”的檔案,這不是php該乾的事情。
- unlink(filename,context) 刪除檔案 。不說了,我不懂你都會懂的。
- copy(source,destination) 拷貝檔案。記住一點就好:檔案沒有就沒有,有就有,反正一句話“果斷的會覆蓋”。
- mkdir(path,mode,recursive,context) 建立目錄。這個很好理解 ,主要要注意mode:預設全部許可權。還有是recursive:是否遞迴。譬如你要建立 1/2/3/4/5 這樣層級的檔案夾,其實最關鍵的是你要建立“5”這個檔案夾,如果這個參數是false,那麼如果前面的1/2/3/4沒有那麼會建立失敗,如果設定了true,系統會自動幫你把1/2/3/4/一起給建立了。
- rmdir(path). 刪除檔案夾 。話說這個函數還是安全。檔案夾假如不是空的,它鳥都不會鳥你。
先寫這麼多,這裡包含了大部分php檔案的操作,當然還有很多,由於篇幅不全部列舉,歡迎大家補充有故事、有特點、需謹慎使用的檔案操作函數。若上文中有不到、不當、不足、胡扯的部分請諒解和指正。