8.2常见的文件操作
8.2 常见的文件操作
文件操作是程序开发中最基本的内容之一。实际应用中,经常需要从文件取数据,或者向文件写入数据,如分析日志数据和记录日志等。因此,作为编程的基本功之一,读者需要努力掌握文件处理的有关内容,并在实际应用中加强实践。本节将为读者介绍一些基本的文件操作函数。
8.2.1 打开和关闭文件
在程序中,处理文件的一般流程如图8-5所示。

图8-5 用程序操作文件的一般流程
要通过PHP读出文件内容,或者向文件写入数据,首先要做的是打开文件。在PHP中可以使用函数fopen()打开一个文件,该函数的语法如下。
$fp = fopen(string $filename,string $mode);
该函数可以打开本地或远程文件,参数$filename是指要打开的文件的文件名,返回值是文件处理句柄$fp,程序通过$fp来操作文件。如果打开失败,函数返回FALSE。该函数的第2个参数$mode是字符串类型,指打开文件的模式。打开文件时,之所以要指定模式,是为了告诉操作系统如何处理即将打开的文件。例如,如果需要向某文件写入一些数据,可以向该函数的第2个参数传参数w,此时,这个参数表示的含义是以写入方式打开文件。表8-1列举了常用的文件打开模式。
表8-1 函数fopen()中参数$mode的主要取值

如下示例代码即通过函数fopen()打开文件。
$fp = fopen($_SERVER["DOCUMENT_ROOT"]."/../files/read.txt","w");
上述代码通过函数fopen()打开files目录下的read.txt文件,这里使用了PHP的预定义变量$_SERVER[‘DOCUMENT_ROOT’],其后跟着的..表示服务器文档根目录的上级目录。这段代码要打开的文件在服务器文档目录之外,是出于安全上的考虑。传入该函数的第2个参数w,表示以写入方式打开文件read.txt。
注意 在Linux/UNIX系统中指定文件路径时,使用斜杠(/)。如果是在Windows环境下,指定目录时,可以使用斜杠(/)或者反斜杠(\)。如果使用的是\,在使用函数fopen打开指定目录的文件时,需要对\转义,即使用\\来指定目录。
例如,在Windows平台打开C盘某目录下的文件,使用\指定目录,其代码如下。
$fp = fopen("C:\\data\\log.dat");
一般实际开发中很少使用\来指定目录,因为这样的代码只能运行于Windows环境下,不利于程序的移植。除了打开本机文件,函数fopen()还可以通过HTTP协议、FTP协议或其他网络协议打开远程文件。打开文件后,就可以向文件写入数据,或者从文件中读取数据。
当完成数据的写入或读取后,文件操作的最后一步需要关闭文件,PHP程序中使用函数fclose()关闭一个已经打开的文件。如果文件成功关闭,该函数返回TRUE,否则返回FALSE。下面的代码片段演示了使用函数fcolse()关闭打开的文件。这行代码中的变量$fp就是已经打开的文件的处理句柄。
fcolse($fp);
8.2.2 读出文件的内容
文件打开后,就可以从其中读出内容,以供程序使用。本节通过一个具体实例介绍PHP中和读文件有关的函数。
(1)建立一个文本文件,供程序打开和读其内容之用。该文本内容如下。
<b><h3>
最新动态</h3></b>
40
名企业家自费植树
中国战机南疆出击
姚明31
分火箭胜太阳
(2)将该文件以名称info.dat保存在服务器文档根目录的上级目录data下。然后编写读取这个文件内容的PHP程序,该程序如代码8-4所示。
代码8-4 读取文件内容8-4.php
01 <?php
02 $fp = fopen($_SERVER["DOCUMENT_ROOT"]."/../data/info.dat","r");//
打开指定的文件
03
04 if(!$fp)
05 {
06 echo "<b>Error:
打开文件错误,请检查目录是否正确,或稍后再试!</b>";
07 exit;
08 }
09
10 while(!feof($fp)) //
循环读取文件
11 {
12 $line = fgets($fp); //
读取文件的一行
13 echo $line;
14 echo "<br/>";
15 }
16
17 fclose($fp); //
关闭文件
18 ?>
【代码解析】代码第02行使用函数fopen()打开文件,并且向其传入了第2个参数r,表示以只读方式打开该文件,此时程序只可以读出文件的内容而不能向文件写入数据。接着,程序判断文件是否成功打开,即判断句柄$fp是否为TRUE。如果打开文件失败,程序会向页面输出一个错误信息,然后立即终止程序执行,语句“exit;”用来终止程序继续执行。

图8-6 读取文件内容
程序第10行使用了while循环来读文件,直到文件的末尾,其中,函数feof()用来判断是否到了文件的末尾。该函数使用文件句柄$fp作为其参数,当达到文件末尾时,它会返回TRUE。这个程序中,当没有达到文件末尾时,函数执行while语句的循环体。第12行语句的意思是取出文件中的一行赋给变量$line,函数fgets()会读取文件中的一行,直到遇到换行字符(\n)。该函数接受的参数是已打开的文件的句柄,返回值是文件的一行内容。函数fgets()可以接受第2个参数,表示读取一行内容的字节数(bytes),例如fgets($fp,100)表示读取一行中的100字节的内容,如果没有传入该参数,fgets()默认读取1024个字节内容。最后,第17行使用函数fclose($fp)关闭已打开的文件。代码8-4的执行结果如图8-6所示。
除了使用函数fgets()读出文件的一行内容外,还可以使用另外3个函数读入整个文件,即函数readfile()、函数file()和函数get_file_contents()。
函数readfile()读入文件的整个内容,该函数的语法如下。
int readfile(string $filename);
该函数的参数$filename是要打开的文件名称,如果打开文件成功,函数的返回值是从文件读入的字节数,否则返回FALSE。该函数还有两个可选参数,它们是比较高级的用法,这里不再赘述。
函数file()可以将整个文件读入一个数组,该函数的语法如下。
array file(string $filename, [int use_include_path]);
函数file()的参数$filename是要打开的文件,第2个参数是可选的,如果其值为1,表示PHP将在include_path中查找该文件,include_path是php.ini文件中的一个配置项。该函数读入整个文件的内容,将其存入数组后返回该数组。数组中的每个单元对应文件中的每一行,包括换行符在内。如果file()处理失败,返回值是FALSE。
函数get_file_contents()和函数file()类似,只不过它将整个文件内容读入一个字符串。该函数的语法如下。
string get_file_contents(string $filename);
该函数返回文件$filename的所有内容,如果失败,返回值是FALSE。
8.2.3 向文件写入内容
除了从文件读出内容,有时还需要向文件写入数据。本小节将介绍如何在PHP程序中向文件写入数据。通过3个函数可以完成对文件的写入操作,即函数fwrite()、函数fputs()和函数file_put_contents()。
函数fwrite()的语法如下。
int fwrite($fp, string $content [, int $length));
参数$fp是已打开的文件的句柄,$content是要向文件写入的内容。第3个参数$length是一个可选参数,表示写入数据的最大的字节数,这就是说,当向文件写入了length个字节后,写入就会停止。当然,如果$content的长度小于$length,函数写完$content后就已停止写入。如果写入成功,该函数返回写入的字符数,否则返回FALSE。代码8-5演示了函数fwrite()的用法。
代码8-5 使用函数fwrite()向文件写入数据8-5.php
01 <?php
02 $file = "data.txt";
03 $content = "
内容标题\r\n
内容第一行\r\n
内容第二行"; //
要写入文件的内容
04
05 //
打开文件$file
时,使用追加模式,此时文件指针会在文件开始处
06 if(!$fp = fopen($file,"a"))
07 {
08 echo "
打开文件$file
失败!";
09 exit;
10 }
11
12 if(fwrite($fp,$content) === FALSE) //
将内容$content
写入文件
13 {
14 echo "
写入文件失败!";
15 exit;
16 }
17
18 echo "
写入文件成功!";
19 fclose($fp); //
关闭文件
20 ?>
【代码解析】这段程序向当前目录下的文件data.txt中写入一些内容,因为使用了a模式打开文件,如果当前目录下不存在data.txt,函数fopen()会尝试创建该文件。代码第12行通过函数fwrite()将变量$content所存内容写入data.txt,同时判断是否写入成功,如果写入失败,则向页面输出一个错误提示信息。
注意 因为是在Windows平台下向文件写入内容,所以变量$content里的数据使用\r\n作为一行的结束符号,即换行。而在UNIX系统中,使用\n作为行结束字符。

图8-7 通过fwrite()向文件写入的内容
通过浏览器执行该程序,如果执行正常,会出现“文件写入成功!”的提示,同时到当前目录中打开文件data.txt,可以看到文件里已经写入内容,如图8-7所示。
函数fputs()是函数fwrite()的别名,其实它就是函数fwrite(),用法和fwrite()一样,这里不再赘述。
函数file_put_contents()也可以完成向文件写入数据,该函数的语法如下。
int file_put_contents(string $filename, string $data);
该函数主要有两个参数,参数$filename是要写入数据的文件的名称,参数$data是要写入的数据。使用函数file_put_contents(),相当于依次调用了fopen()、fwrite()和fclose(),因此,程序中不必再使用这3个函数。如果执行成功,该函数返回写入文件的字节数,否则返回FALSE。
8.2.4 获取文件的相关信息
文件的相关信息主要涉及文件的所有者、文件的大小和文件的类型等,PHP可以通过以下函数获取文件的这些主要信息。
·函数fileowner(),取得文件的所有者,返回文件所有者的用户ID,如果失败,返回FALSE。
·函数filesize(),取得文件的大小,返回值是文件大小的字节数,如果失败,返回FALSE。
·函数filetype(),返回文件类型,可能的值有file(文件)、dir(目录)、link(符号链接)、block(块)、unknown(未知)等。如果失败,返回FALSE。
代码8-6演示了这些函数的用法。
代码8-6 获取文件的主要信息8-8.php
01 <?php
02 echo "
文件的所有者(用户ID
):";
03 echo fileowner("data.txt"); //
取得文件的所有者
04 echo "<br>";
05 echo "<br>";
06
07 echo "
文件的大小:";
08 echo filesize("data.txt"); //
取得文件的大小
09 echo "<br>";
10 echo "<br>";
11
12
13 echo "
文件的类型:";
14 echo filetype("data.txt"); //
取得文件的类型
15 echo "<br>";
16 ?>
【代码解析】这段代码向页面输出当前目录下文件data.txt的一些主要信息,如文件所有者、文件大小和文件类型,执行结果如图8-8所示。
8.2.5 一些判断文件性质的函数
PHP中判断文件性质的函数主要有以下几个。
·函数is_dir($filename),判断由参数$filename指定的文件是否是目录。如果文件名存在并且是一个目录,该函数返回TRUE,否则返回FALSE。
·函数is_file($filename),判断由参数$filename指定的文件是否是普通文件。如果文件名存在并且是一个普通文件,该函数返回TRUE,否则返回FALSE。
·函数is_readable($filename),判断由参数$filename指定的文件是否可读。文件可读时,该函数返回TURE,否则返回FALSE。
·函数is_writeable($filename),判断由参数$filename指定的文件是否可写。文件可写时,该函数返回TRUE,否则返回FALSE。函数is_writeable()经常在向一个文件写入内容之前调用,如果该文件可写,才向文件里写入数据。
代码8-7演示了这些函数的用法。
代码8-7 判断文件的性质8-7.php
01 <?php
02 $file = "data.txt"; //
文件名称
03
04 if(is_dir($file)) //
判断该文件是否是目录
05 {
06 echo "
文件 $file
是个目录";
07 echo "<br/>";
08 }
09 else
10 {
11 echo "
文件 $file
不是目录";
12 echo "<br/>";
13 }
14
15 if(is_file($file)) //
判断该文件是否是普通文件
16 {
17 echo "
文件 $file
是一个普通文件";
18 echo "<br/>";
19 }
20
21 if(is_readable($file)) //
判断该文件是否可读
22 {
23 echo "
文件 $file
是可读的";
24 echo "<br/>";
25 }
26 else
27 {
28 echo "
文件 $file
是不可读的";
29 echo "<br/>";
30 }
31
32 if(is_writeable($file)) //
判断该文件是否可写
33 {
34 echo "
文件 $file
是可写的";
35 echo "<br/>";
36 }
37 else
38 {
39 echo "
文件 $file
是不可写的";
40 echo "<br/>";
41 }
42 ?>
【代码解析】这段代码判断了当前目录下文件data.txt的一些性质,包括它是否是目录、是不是文件、是可读还是可写,执行结果如图8-9所示。

图8-8 使用PHP的函数获取文件的主要信息

图8-9 使用PHP的函数判断文件的性质
注意 这段代码中输出使用了双引号字符串,其中变量$file后紧跟着中文字符,这时需要在变量$file后加入空格,程序才会有正确的输出。否则PHP会认为变量$file后的中文字符也是变量名的一部分,从而导致输出有问题。
上一篇:8.1常见的目录操作
下一篇:8.3文件和目录的通用操作
