fopen 方法可能是以前的 C 和 C++ 程式設計師最熟悉的,因為如果您使用過這些語言,那麼它們或多或少都是您已掌握多年的工具。對於這些方法中的任何一種,透過使用 fopen(用於讀取資料的函數)的標準方法開啟文件,然後使用 fclose 關閉文件,如清單 1 所示。
清單 1. 用 fgets 開啟並讀取檔案
$file_handle = fopen("myfile", "r"); while (!feof($file_handle)) { $line = fgets($file_handle); echo $line; } fclose($file_handle);
開啟檔案。 $file_handle 儲存了一個對文件本身的引用。
檢查您是否已到達文件的末端。
繼續讀取文件,直到到達文件末尾,邊讀取邊列印每行。
關閉檔案。
記住這些步驟。
feof
feof 指令將偵測您是否已經讀到檔案的結尾並傳回 True 或 False。清單 1 中的循環將繼續執行,直到您達到檔案「myfile」的末端。注意:如果讀取的是 URL 且套接字由於不再有任何資料可以讀取而逾時,則 feof 也會傳回 False。
fclose
向前跳至清單 1 的末尾,fclose 將實現與 fopen 相反的功能:它將關閉指向檔案或 URL 的連線。執行此函數後,您將不再能夠從檔案或套接字中讀取任何資訊。
fgets
在清單 1 中回跳幾行,您就到達了檔案處理的核心:實際讀取檔案。 fgets 函數是處理第一個範例的首選武器。它將從文件中提取一行資料並將其作為字串返回。在那之後,您可以列印或以別的方式處理資料。清單 1 中的範例將精細地列印整個文件。
如果決定限制處理資料塊的大小,您可以將一個參數加到 fgets 中限制最大行長度。例如,使用下列程式碼將行長度限制為80 個字元:$string = fgets($file_handle, 81);
回想C 中的「\0」字串結尾終止符,將長度設為比實際所需值大一的數字。因而,如果需要 80 個字符,則以上範例使用 81。應養成以下習慣:只要對此函數使用行限制,就加入該額外字元。
fread
fgets 函數是多個檔案讀取函數中惟一一個可用的。它是一個更常用的函數,因為逐行解析通常會有意義。事實上,幾個其他函數也可以提供類似功能。但是,您並非總是需要逐行解析。
這時就需要使用 fread。 fread 函數與 fgets 的處理目標略有不同:它趨於從二進位檔案(即,並非主要包含人類可閱讀的文字的檔案)中讀取資訊。由於「行」的概念與二進位檔案無關(邏輯資料結構通常都不是由新行終止),因此您必須指定需要讀入的位元組數。 $fh = fopen("myfile", "rb");
$data = fread($file_handle, 4096);
<?php $file_path = "test.txt"; if(file_exists($file_path)){ $fp = fopen($file_path,"r"); $str = fread($fp,filesize($file_path));//指定读取大小,这里把整个文件内容读取出来 echo $str = str_replace("\r\n","<br />",$str); } ?>
使用二進位資料
注意:此函數的範例已經使用了略微不同於 fopen 的參數。當處理二進位資料時,始終要記得將 b 選項包含在 fopen 中。如果跳過這一點,Microsoft® Windows® 系統可能無法正確處理檔案,因為它們將以不同的方式處理新行。如果處理的是 Linux® 系統(或其他某個 UNIX® 變種),這可能看似沒關係。但即使不是針對 Windows 開發的,這樣做也將獲得良好的跨平台可維護性,並且也是應遵循的一個好習慣。
以上程式碼將讀取 4,096 位元組 (4 KB) 的資料。注意:不管指定多少位元組,fread 都不會讀取超過 8,192 個位元組 (8 KB)。
假定檔案大小不超過 8 KB,則下列程式碼應能將整個檔案讀入一個字串。 $fh = fopen("myfile", "rb");
$data = fread($fh, filesize("myfile"));
fclose($fh);
如果檔案長度大於此值,則只能使用循環將其餘內容讀入。
fscanf
回到字串處理,fscanf 同樣遵循傳統的 C 檔案庫函數。如果您不熟悉它,則 fscanf 將把欄位資料從檔案讀入變數中。 list ($field1, $field2, $field3) = fscanf($fh, "%s %s %s");
此函數使用的格式字串在許多地方都有描述(如PHP.net 中) ,故在此不再贅述。可以這樣說,字串格式化極為靈活。值得注意的是所有欄位都放在函數的回傳值中。 (在 C 中,它們都被作為參數傳遞。)
fgetss
fgetss 函數不同於傳統文件函數並使您能更好地了解 PHP 的力量。該函數的功能類似於 fgets 函數,但將去除發現的任何 HTML 或 PHP 標記,只留下純文字。查看如下所示的 HTML 文件。
範例 HTML 檔案
<html> <head><title>My title</title></head> <body> <p>If you understand what "Cause there ain't no one for to give you no pain" means then you listen to too much of the band America</p> </body> </html>
然後透過 fgetss 函數過濾它。
使用 fgetss
$file_handle = fopen("myfile", "r"); while (!feof($file_handle)) { echo = fgetss($file_handle); } fclose($file_handle);
以下是输出: My title
If you understand what "Cause there ain't no one for to give you no pain"
means then you listen to too much of the band America
fpassthru 函数
无论怎样读取文件,您都可以使用 fpassthru 将其余数据转储到标准输出通道。fpassthru($fh);
此外,此函数将打印数据,因此无需使用变量获取数据。
非线性文件处理:跳跃访问
当然,以上函数只允许顺序读取文件。更复杂的文件可能要求您来回跳转到文件的不同部分。这时就用得着 fseek 了。fseek($fh, 0);
以上示例将跳转回文件的开头。如果不需要完全返回 —— 我们可设定返回千字节 —— 然后就可以这样写:fseek($fh, 1024);
从 PHP V4.0 开始,您有一些其他选项。例如,如果需要从当前位置向前跳转 100 个字节,则可以尝试使用:fseek($fh, 100, SEEK_CUR);
类似地,可以使用以下代码向后跳转 100 个字节:fseek($fh, -100, SEEK_CUR);
如果需要向后跳转至文件末尾前 100 个字节处,则应使用 SEEK_END。fseek($fh, -100, SEEK_END);
在到达新位置后,可以使用 fgets、fscanf 或任何其他方法读取数据。
注:不能将 fseek 用于引用 URL 的文件处理。
回页首
提取整个文件
现在,我们将接触到一些 PHP 的更独特的文件处理功能:用一两行处理大块数据。例如,如何提取文件并在 Web 页面上显示其全部内容?好的,您看到了 fgets 使用循环的示例。但是如何能够使此过程变得更简单?用 fgetcontents 会使过程超级简单,该方法将把整个文件放入一个字符串中。$my_file = file_get_contents("myfilename");
echo $my_file;
虽然它不是最好的做法,但是可以将此命令更简明地写为:echo file_get_contents("myfilename");
本文主要介绍的是如何处理本地文件,但是值得注意的是您还可以用这些函数提取、回显和解析其他 Web 页面。echo file_get_contents("http://127.0.0.1/");
此命令等效于:$fh = fopen("http://127.0.0.1/", "r");
fpassthru($fh);
您一定会查看此命令并认为:“那还是太费力”。PHP 开发人员同意您的看法。因此可以将以上命令缩短为:readfile("http://127.0.0.1/");
readfile 函数将把文件或 Web 页面的全部内容转储到默认的输出缓冲区。默认情况下,如果失败,此命令将打印错误消息。要避免此行为(如果需要),请尝试:@readfile("http://127.0.0.1/");
当然,如果确实需要解析文件,则 file_get_contents 返回的单个字符串可能有些让人吃不消。您的第一反应可能是用 split() 函数将它分解一下。$array = split("\n", file_get_contents("myfile"));
但是既然已经有一个很好的函数为您执行此操作为什么还要这样大费周章?PHP 的 file() 函数一步即可完成此操作:它将返回分为若干行的字符串数组。$array = file("myfile");
应当注意的是,以上两个示例有一点细微差别。虽然 split 命令将删除新行,但是当使用 file 命令(与 fgets 命令一样)时,新行仍将被附加到数组中的字符串上。
但是,PHP 的力量还远不止于此。您可以在一条命令中使用 parse_ini_file 解析整个 PHP 样式的 .ini 文件。
当然,您可能注意到此命令合并了各个部分。这是默认行为,但是您可以通过将第二个参数传递给 parse_ini_file 轻松地修正它:process_sections,这是一个布尔型变量。将 process_sections 设为 True。
$file_array = parse_ini_file("holy_grail.ini", true); print_r $file_array;
并且您将获得以下输出:
Array ( [personal information] => Array ( [name] => King Arthur [quest] => To seek the Holy Grail [favorite color] => Blue ) [more stuff] => Array ( [Samuel Clemens] => Mark Twain [Caryn Johnson] => Whoopi Goldberg ) )
<?php $file_path = "test.txt"; if(file_exists($file_path)){ $fp = fopen($file_path,"r"); $str = ""; $buffer = 1024;//每次读取 1024 字节 while(!feof($fp)){//循环读取,直至读取完整个文件 $str .= fread($fp,$buffer); } $str = str_replace("\r\n","<br />",$str); echo $str; } ?>
以上是正確使用php讀取文件的方法匯總,別忘了關閉文件的詳細內容。更多資訊請關注PHP中文網其他相關文章!