第1篇 PHP基础应用
第1章 文件系统与文本数据操作
在程序设计中,文件是一个很重要的对象,Web编程也不例外。文件的操作在很多Web系统中一直都是被反复用到的。在实际应用中经常会遇到对文件和目录的创建、修改、删除等操作。本章将主要介绍如何使用PHP对文件系统以及文本数据进行操作。
1.1 PHP中目录操作详解
所谓目录,也称文件夹,是操作系统用于管理文件的群组。在PHP中,常见的目录操作包括打开目录、关闭目录、读取目录中的文件、创建目录以及删除目录等。
1.1.1 打开目录
PHP中使用opendir函数打开一个目录。opendir函数将返回一个资源对象,用于存储当前目录资源,语法格式如下所示。
opendir(string path)
其中,path是目录所在的路径。通常,为了确保程序的正确性,在打开目录之前要使用is_dir函数判断路径的有效性。is_dir函数的语法格式如下所示。
bool is_dir(string path)
以下代码是一个打开目录的例子。
<?php $dir = "test/"; //设置目录为test if(is_dir($dir)) //如果目录存在,则打开 $dir_res = opendir($dir); else //否则输出错误信息 echo "目录不存在或者不是一个有效目录"; ?>
1.1.2 关闭目录
PHP中使用closedir函数关闭目录,其语法格式如下。
void closedir(dir_resource)
其中dir_resource是使用opendir函数打开目录时返回的资源对象。以下代码用于关闭上面打开的目录。
<?php closedir($dir_res); //关闭目录 ?>
1.1.3 读取目录中的文件
PHP中使用readdir函数读取目录中的文件并返回文件名,其语法格式如下所示。
string readdir(dir_resource)
其中dir_resource是使用opendir函数打开目录时返回的资源对象。该函数按照文件系统中的文件排序返回文件名。每次执行读取下一个文件并返回一条记录。以下代码是一个读取目录中文件的例子。
<?php $dir = "files/"; //定义路径 $dir_res = opendir($dir); //打开目录 while($filen=readdir($dir_res)) //循环读取目录中的文件 { echo $filen."<br>" ; } closedir($dir_res) //关闭目录 ?>
运行结果如下所示。
. .. class.php test.php test1.php
从运行结果可以看出,除了文件夹中的文件以外还包含有“.”和“..”两个文件夹。其中,“.”用于表示当前目录,“..”用于表示上一级目录。
1.1.4 创建目录
PHP中使用mkdir函数创建目录,其语法格式如下所示。
bool mkdir(string pathname)
其中pathname是要创建的目录地址。以下代码是一个创建目录的例子。
<?php $dir = "Test/"; if(!is_dir($dir)) //如果目录不存在则创建 mkdir($dir); ?>
执行后可以看到,程序在当前页面所在的目录下创建了一个新的名为“Test”的目录。
1.1.5 删除目录
PHP中使用rmdir函数创建目录,其语法格式如下所示。
bool rmdir(string pathname)
其中pathname是要删除的目录地址。需要注意的是删除目录的时候,该目录必须是空的。以下代码是一个删除目录的例子。
<?php $dir = "Test/"; if(is_dir($dir)) //如果目录存在则删除 rmdir($dir); ?>
执行后可以看到,在前面用mkdir函数创建的名为“Test”的目录被删除了。
1.2 PHP中文件操作详解
在文件系统中,一个目录可能会包含很多文件。在实际应用中,文件的操作比目录的操作更普遍。本节将主要介绍PHP中的文件操作。需要注意的是,在PHP中文件的概念不仅包括本地文件,还包括远程文件。本节中所讲述的文件路径既可以是一个本地的路径,也可以是一个远程的网址。
1.2.1 打开文件
PHP中使用fopen函数打开一个文件。fopen函数将返回一个资源对象,用于存储当前文件资源,其语法格式如下所示。
fopen(string filename, string mode)
其中,filename是文件的文件名及其所在路径,mode是文件的打开模式。mode的可能值如表1-1所示。
表1-1 fopen函数的mode参数
1.2.2 关闭文件
PHP中使用fclose函数关闭文件,其语法格式如下所示。
void fclose(file_resource)
其中 file_resource 是使用 fopen 函数打开文件时返回的资源对象。以下代码实现了一个打开关闭文件的操作。
<?php $file = fopen("Test\\file.txt", "w"); //打开文件 fclose($file); //关闭文件 ?>
1.2.3 读取文件
PHP提供了多种读取文件的方法。这里仅介绍最常见的3种。
1.读取文件中的一个字符
函数fgetc用来读取文件中的一个字符,语法格式如下所示。
string fgetc(file_resource)
其中 file_resource 是使用 fopen 函数打开文件时返回的资源对象。该函数返回文件中的一个字符并将指针移动到下一个字符。以下代码是一个使用fgetc函数读取文件的例子。
<?php $file = fopen("Test\\file.txt", "r"); //打开文件 echo fgetc($file); //读取文件中的一个字符 fclose($file); //关闭文件 ?>
从该程序的运行结果可以看出,文件中的第一个字符被输出了。2.读取文件中的一行
函数fgets用来读取文件中的一行,语法格式如下所示。
string fgets(file_resource)
其中 file_resource 是使用 fopen 函数打开文件时返回的资源对象。该函数返回文件中的一行并将指针移动到下一行。以下代码是一个使用fgets函数读取文件的例子。
<?php $file = fopen("Test\\file.txt", "r"); //打开文件 echo fgets($file); //读取文件中的一行 fclose($file); //关闭文件 ?>
从该程序的运行结果可以看出,文件中的第一行被输出了。fgets是在实际应用中最常用到的一种方法,通常通过循环读取的方式获得文件的全部内容,并且可以方便地对文件的每一行进行处理。
3.读取文件中任意长字符
函数fread用来读取文件中任意长字符,语法格式如下。
string fread(file_resource, int length)
其中file_resource是使用fopen函数打开文件时返回的资源对象,length是要读取的字符长度。以下代码是一个使用fread函数读取文件的例子。
<?php $file = fopen("Test\\file.txt", "r"); echo fread($file, 20); //读取文件中的前20个字符 fclose($file); ?>
从该程序的运行结果可以看出,文件中的前20 个字符被输出了。需要注意的是如果指定的length参数超过了文件的长度,文件的全部内容将被返回。
通常结合使用fread函数和filesize函数来获取文件的全部内容。filesize函数用于返回文件大小的字节数,语法格式如下。
int filesize(string filename)
其中,filename 是文件的文件名及其所在路径。以下代码是一个返回文件所有内容的例子。
<?php $filename = "Test\\file.txt"; $file = fopen($filename, "r"); $filesize = filesize($filename); //获取文件长度 echo fread($file, $filesize); //获取文件全部内容 fclose($file); ?>
1.2.4 写入文件
PHP中使用fwrite函数将数据写入文件,语法格式如下。
int fclose(file_resource, string str [,int length])
其中file_resource是使用fopen函数打开文件时返回的资源对象,str是要写入文件的字符串,length是一个可选的指定长度的参数。如果指定length,则只将str的前length长度的字符写入文件。以下代码实现了一个写文件的操作。
<?php $filename = "Test\\file.txt"; $file = fopen($filename, "w"); //以写模式打开文件 fwrite($file, "Hello, world!\n"); //写入第一行 fwrite($file, "This is a test!\n"); //写入第二行 fclose($file); //关闭文件 ?>
上面的代码运行后在file.txt中写入了两行,如下所示。
Hello, world! This is a test!
1.2.5 删除文件
PHP中使用unlink函数删除文件,语法格式如下所示。
bool unlink(string filename)
其中,filename是文件的文件名及其所在路径。以下代码实现了一个删除文件的操作。
<?php $filename = "Test\\file.txt"; unlink($filename); //删除文件 ?>
上面的代码运行后,文件file.txt将被删除。
1.2.6 复制文件
PHP中使用copy函数复制文件,语法格式如下。
bool copy(string filename1, string filename2)
其中,filename1 是源文件的文件名及其所在路径,filename2 是目标文件的文件名及其所在路径。该函数的执行结果是将filename1复制到filename2。以下代码实现了一个复制文件的操作。
<?php $filename1 = "Test\\file.txt"; $filename2 = "Test\\file.bak"; copy($filename1, $filename2); //复制文件 ?>
上面的代码运行后,文件file.txt将被复制到file.bak。
1.3 本地文件的操作实例——小型留言本
前面介绍了一些对文件的基本操作,对于一些小型并且对安全要求不高的项目来说,完全可以使用一个本地文本文件来存放数据。本节将要实现一个小型留言本的编写。这个留言本实现了两个最基本的功能,即留言和查看留言。
1.3.1 留言发表模块
留言发表模块提供给访问者的是一个简单的表单,用户在输入留言标题、留言内容和留言者姓名以后,程序会在文件夹DB下创建一个新的文本文件,并将用户输入的内容保存到这个文件中。
留言发表模块包括两个文件。Post.htm是一个静态的HTML页面,提供一个表单供用户输入。Post.php是一个PHP页面,用来接收用户的输入并将结果保存在文件夹DB中。
以下是Post.htm的HTML代码。
<html> <head> <title>发表新的留言</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head> <body> <H1><p align="center">发表新的留言</p></H1> <form name="form1" method="post" action="Post.php"> <table width="500" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td>标题</td> <td><input name="title" type="text" id="title" size="50"></td> </tr> <tr> <td>作者</td> <td><input name="author" type="text" id="author" size="20"></td> </tr> <tr> <td>内容</td> <td><textarea name="content" cols="50" rows="10" id="content"></textarea></td> </tr> </table> <p align="center"> <input type="submit" value="Submit"> <input type="reset" value="Reset"> </p> </form> </body> </html>
该页面在浏览器中如图1-1所示。
图1-1 发表新留言界面
Post.php的代码如下所示。
<?php $path = "DB/"; //指定存储路径 $filename = "S".date("YmdHis").".dat"; //由当前时间产生文件名 $fp = fopen($path.$filename, "w"); //以写方式创建并打开文件 fwrite($fp, $_POST["title"]."\n"); //写入标题 fwrite($fp, $_POST["author"]."\n"); //写入作者 fwrite($fp, $_POST["content"]."\n"); //写入内容 fclose($fp); //关闭文件 echo "留言发表成功!"; //提示发表成功 echo "<a href='Index.php'>返回首页</a>"; ?>
上面的代码将在DB文件夹内创建一个以当前时间为文件名命名的文本文件,并且逐行写入标题、作者和内容。访问者在图1-1所示的表单中输入信息后,一个新的文件就会在DB文件夹中创建。需要注意的是在设计本例的文件名时的方法,为了避免文件名的冲突,采用当前系统时间作为文件名。
1.3.2 浏览模块
前面介绍了如何把用户的输入存放到文本文件中。本节中将要介绍的是将这些文件显示出来。代码如下所示。
<?php $path = "DB/"; //定义路径 $dr = opendir($path); //打开目录 while($filen = readdir($dr)) //循环读取目录中的文件 { //如果文件名不是当前目录或父目录则对该文件进行读取 if($filen != "." and $filen != "..") { $fs = fopen($path.$filen, "r"); echo "<B>标题:</B>".fgets($fs)."<BR>"; echo "<B>作者:</B>".fgets($fs)."<BR>"; echo "<B>内容:</B><PRE>".fread($fs, filesize($path.$filen))."</PRE>"; echo "<HR>"; //输入一条线用来隔开每条留言 fclose($fs); } } closedir($dr) //关闭目录 ?>
上面代码的运行结果如图1-2所示。上面的代码首先对文件夹DB进行读取并获得文件夹内的全部文件,针对每一个文件分别打开、读取并输出。每读取一个文件输出一条分隔线以标识该条留言的结束。
图1-2 浏览模块的输出结果
1.4 远程文件的操作实例
远程文件的操作与操作本地文件类似,只是将文件路径用网址代替。需要注意的是读取远程文件时一般仅使用读操作。PHP提供了一个配置参数来控制是否允许读取远程网址,该配置参数即php.ini文件中的allow_url_fopen选项,只要打开这个选项,就可以使用网址来代替文件名。
以下代码是一个简单的读取远程文件的例子,该实例获取了远程网址的前100个HTML字符。
<?php $fp = fopen("http://127.0.0.1/test/test1.php", "r"); //打开文件 echo fread($fp, 100); //读取文件中的前100个字符 fclose($fp); //关闭文件 ?>
可以看到,原来写在fopen的第一个参数中的文件路径在这里使用一个网址代替了。
1.5 文件的上传与下载
除了前面介绍的读取和写入文件的功能,在实际应用中还有一个经常用到的功能,就是文件的上传与下载。通过文件的上传与下载,可以实现访问者客户端与服务器的文件交换。
1.5.1 文件的上传
文件的上传与前面介绍的复制文件的方法类似。文件的上传通过函数move_uploaded_file来实现,语法格式如下。
bool move_uploaded_file(string filename1, string filename2)
其中,filename1 是客户端源文件的文件名及其所在路径,filename2 是在服务器上的目标文件的文件名及其所在路径。源文件的地址可以从客户端获取,在表单上使用file控件即可。需要注意的是在文件上传时需要指明表单的属性为 enctype="multipart/form-data",这样就可以上传文件了。
以下代码是一个实现简单文件上传的例子。文件 Upload.htm 用来显示供用户输入的表单,文件Upload.php用来实现文件上传。
Upload.htm的HTML代码如下所示。
<html> <head> <title>文件上传</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head> <H1>文件上传</H1> <form enctype="multipart/form-data" action="Upload.php" method="post"> <input name="upfile" type="file"><BR> <input type="submit" value="Submit"> </form> <body> </body> </html>
Upload.php的代码如下。
<?php $uploadfile = "upfiles/".$_FILES['upfile']['name']; //上传后文件所在的文件名和路径 move_uploaded_file($_FILES['upfile']['tmp_name'], $uploadfile); //上传文件 print_r($_FILES); //输出上传文件信息
?>
这里需要说明的是$_FILES。$_FILES 是一个全局变量二维数组。该数组中每一行由5个元素组成。主要包括以下几项。
➢ $_FILES[]['name']:客户端源文件名。
➢ $_FILES[]['type']:上传文件的类型。
➢ $_FILES[]['size']:上传文件的字节数。
➢ $_FILES[]['tmp_name']:文件上传后在服务器上的临时存储文件名。
➢ $_FILES[]['error']:文件上传的错误代码。如果为0则表示没有错误发生。
上述程序的运行结果如下。
Array ( [upfile] => Array ( [name] => simon.txt [type] => text/plain [tmp_name] => C:\php\tmp\phpA3.tmp [error] => 0 [size] => 8 ) )
从上面输出的数组可以看出:上传的文件在客户端的文件名为 simon.txt;文件类型为text/plain,即文本型文件;上传后的临时存储路径为C:\php\tmp\phpA3.tmp;文件的大小为8字节;在文件上传过程中没有错误发生。
1.5.2 文件的下载
文件的下载与文件的读取方法基本相同,其基本原理是通过PHP代码读取文件然后将读取的内容输出到浏览器端。使用PHP程序进行文件下载的好处在于可以将文件的真实路径隐藏起来。然而,由于下载的文件的类型不同,在 PHP 程序中,需要使用 header 来定义文件的类型、大小等参数。以下代码实现了对downloads文件夹中的文件进行浏览和下载的功能。
<?php $dir = "downloads/"; //定义路径 if(!isset($_GET['file'])) //如果在参数中没有指定文件名,则读取文件列表 { $dir_res = opendir($dir); //打开目录 echo "<H1>文件下载</H1>"; while($filen=readdir($dir_res)) //循环读取目录中的文件 { if($filen != "." and $filen != "..") echo "<a href='?file=".$filen."'>".$filen."</a><br>" ; } closedir($dir_res); //关闭目录 } else { $file_name = $dir . $_GET['file']; //获得当前文件名 if ($fh = fopen($file_name, "r")) //打开文件 { $fsize = filesize($file_name); //获得文件大小 $path_parts = pathinfo($file_name); //获得文件路径信息 header("Content-type: application/octet-stream"); //定义文件类型 header("Content-Disposition: filename=\"" . $path_parts["basename"] . "\""); //定义文件名 header("Content-length: " . $fsize); //定义文件大小 while(!feof($fh)) //读取文件并输出 { $buffer = fread($fh, 2048); echo $buffer; } } } ?>
代码运行结果如图1-3所示。
图1-3 文件下载页面
单击相应的文件链接,浏览器会将文件名作为参数传入程序并提示相应的下载对话框,如图1-4所示。
图1-4 文件下载对话框
1.6 小结
本章主要介绍了PHP中的文件操作。在实际应用中,对文件的操作是非常普遍的,掌握好操作文件的方法非常重要。对于文件的操作通常与对字符串的操作结合使用,下一章将主要介绍对字符串的操作方法。在实际应用中,经常结合文件的读写操作和字符串的处理方法实现需求中的功能。