1. 打开文件
1.1 选择文件模式
在PHP中打开文件,需要指定文件模式。操作系统必须了解要对打开的文件进行的操作,在打开这个文件后是否允许其他脚本打开,使用者是否具有该文件的权限等。文件模式可以告诉操作系统服务器处理脚本访问的机制。
打开文件有3种选择。
1) 打开文件只读、只写或者读和写。
2) 如果写文件,可以覆盖所有文件内容或将新数据追加到文件末尾。如果文件已存在,可以终止程序运行而非覆盖文件。
3) 如果系统是区分二进制方式和纯文本方式,还必须指定采用的方式。
1.2 使用fopen()
调用fopen()需要传递2-4个参数,通常只使用两个,例如:
$fp = fopen("$DOCUMENT_ROOT/test.txt", 'w');
第一个参数表明要打开的文件的位置,第二个参数是文件模式,它是一个字符串,指定了对文件进行的操作。
模式 | 名称 | 含义 |
---|---|---|
r | 只读 | 读模式,从文件头开始读。 |
r+ | 只读 | 读模式,从文件头开始读写。 |
w | 只写 | 写模式,从文件头开始读,如果文件已存在,将覆盖已有内容,如果文件不存在,则创建文件。 |
w+ | 只写 | 写模式,从文件头开始读写,如果文件已存在,将覆盖已有内容,如果文件不存在,则创建文件。 |
x | 谨慎写 | 写模式,从文件头开始写,如果文件已存在,则产生一个警告。 |
x+ | 谨慎写 | 写模式,从文件头开读写,如果文件已存在,则产生一个警告。 |
a | 追加 | 追加模式,从文件末尾开始写,如果文件不存在,则创建文件。 |
a+ | 追加 | 追加模式,从文件末尾开始读写,如果文件不存在,则创建文件。 |
b | 二进制 | 二进制模式,用于与其他模式进行连接。 |
t | 文本 | 文本模式,用于与其他模式进行连接。 |
第三个参数是可选的,如果要在include_path(PHP的配置中设置)中搜索一个文件,可以使用第三个参数,将它设置为1,同时也就不需要提供路径,例如:
$fp = fopen('test.txt', 'ab', true);
第四个参数也是可选的,fopen()函数允许文件名称以协议名称开始(例如,http://),并且在远程位置打开文件。可以通过关闭PHP配置文件中的allow_url_fopen来禁用这个功能。
fopen()成功打开文件后,函数将返回一个指向这个文件的指针。
2. 读写文件
2.1 写文件
写文件可以使用fwrite()或者fputs()(fwirte()函数的别名),这个函数将一个字符串写入到文件中,例如:
fwrite($fp, $string);
它的可替代函数是file_put_contents(),这个函数不需要调用fopen()而将字符串写入到文件中,函数原型如下:
int file_put_contents(string filename, string data[, int flags[, resource context]])
fwrite()有第三个可选参数,它的原型如下:
int fwrite(resource handle, string data[, int length])
第三个参数是写入的最大字符数,如果给出这个参数,fwrite()将向文件写入字符串,直到字符串末尾或已写入了length字节,满足两个条件之一即停止写入。
2.2 测试文件是否读完
feof()可以测试文件是否结束,它的唯一参数是文件指针,如果该文件指向了文件末尾,它将返回true,例如:
while (!feof($fp)) { ...}
2.3 每次读取一行
fgets()函数可以用来读取文件内容,每次从文件中读取一行,它将不断读入数据,直到读到"\n"或文件结束符EOF,或是指定的最大长度减1B,例如:
$content = fgets($fp, 1000);
fgets()函数的一个变体是fgetss(),函数原型如下:
string fgetss(resource fp[, int length[, string allowable_tags]])
它与fgets()相似,但可以过滤字符串中包含的PHP和HTML标记,如果要过滤任何特殊的标记,可以将它们包含在allowable_tags字符串中。
gets()函数的另一个变体是fgetcsv(),函数原型如下:
array fgetcsv(resource fp, int length[, string delimiter[, string enclosure]])
当在文件中使用定界符时,可以使用fgetcsv()函数将文件分成多行。
2.4 读取整个文件
PHP提供了4种方式读取整个文件。第一种是readfile(),它的原型如下:
int readfile(string filename[, int use_include_path[, resource context]])
调用readfile()将打开一个文件并将文件内容输出到标准输出,再关闭这个文件。第二个可选参数指定了PHP是否在include_path中查找文件。第三个可选参数只有在文件被远程打开时才使用,这个函数的返回值是文件中读出的字节总数。
第二种方式是fpassthru(),这个函数必须先使用fopen()打开文件,再将文件指针传递给fpassthru(),将使文件内容输出到标准输出,最后使用fclose()关闭文件。如果读取成功,fpassthru()将返回true,否则返回false,例如:
$fp = fopen("$DOCUMENT_ROOT/test.txt");fpassthru($fp);fclose($fp);
第三种方式是file(),它与readfile()是一样的,只是它是把结果发送到数组中,例如:
$filearray = file("$DOCUMENT_ROOT/test.txt");
第四种方式是file_get_contents(),它与readfile()相似,但是它把文件内容以字符串形式返回而不是回显到浏览器中,例如:
$filestring = file_get_contents("$DOCUMENT_ROOT/test.txt");
2.5 读取一个字符
fgetc()可以从文件中一次读取一个字符,例如:
while (!feof($fp)) { $char = fgetc($fp); if (!eof($fp)) { echo $char; }}
fgetc()的缺点是它返回文件结束符EOF,读取之后还需判断feof()。
2.6 读取一定长度
使用fread()函数可以读取任意长度的字节。函数原型如下:
string fread(resource fp, int length)
当读满length参数指定的字节数或读到文件末尾,函数才停止读取。
3. 其他文件函数
3.1 关闭文件
当使用完文件后,应将其关闭,可以调用fclose()函数,例如:
fclose($fp);
如果文件成功关闭,函数将返回true,否则将返回false。
3.2 检查文件是否存在
如果要检查一个文件是否存在,可以使用file_exists()函数,例如:
if (file_exists("DOCUMENT_ROOT/test.txt")) { echo "File Exists!";}
3.3 确定文件大小
可以使用filesize()函数查看一个文件的大小,它以字节为单位返回,例如:
echo filesize("$DOCUMENT_ROOT/test.txt");
3.4 删除一个文件
可以使用unlink()函数删除一个文件,如果无法删除一个文件,它将返回false,例如:
unlink("$DOCUMENT_ROOT/test.txt");
3.5 在文件中定位
rewind()函数可以将文件指针复位到文件的开始,ftell()函数可以以字节数为单位报告指针当前在文件中的位置,也可以使用fseek()将文件指针指向文件的某个位置。fseek()的原型如下:
int fseek(resource fp, int offset[, int whence])
调用fseek()可以将文件指针fp从whence位置移动offset个字节。whence是可选参数,默认值SEEK_SET表示文件开始处,其他可选值为SEEK_CUR(指针当前位置)和SEEK_END(文件末尾)。
3.6 文件锁定
文件锁定通过flock()函数实现,原型如下:
bool flock(resource fp, int operation[, int & wouldblock])
这个函数需要一个指向被打开文件的指针fp和一个表示所需锁定类型的常数。如果文件锁定成功,将返回true,否则返回false,如果获得文件锁将导致当前进程阻塞,可选的第三个参数将包含值true。
flock()函数无法在NFS或其他网络系统中使用,也无法在其他更早不支持文件锁定的文件系统中使用。
操作值 | 意义 |
---|---|
LOCK_SH | 读操作锁定,文件可以共享,其他人可读。 |
LOCK_EX | 写操作锁定,互斥锁,文件不能被共享。 |
LOCK_UN | 释放已有锁定。 |
LOCK_NB | 防止在请求加锁时发生阻塞。 |