PHP碎碎念(二)——文件读取基础
距离上一次更新PHP又过了很久……太多东西要学了。这次更新主要是因为遇到了新的需求,要用PHP开发一个平台后端,不得不再捡起来……
总之,继续启动!
这章我们主要粗略的过一遍PHP的数据储存和读取,节奏会比较快。之所以快马加鞭,是因为PHP的精髓不在这里。本章只涉及最基本的读取文件操作,大部分和C语言类似,而且目前储存数据更常用的是采取DBMS数据库来管理数据储存。所以本章只做简单的归纳,快速掌握就行。
文件处理
PHP的处理文件方式和C语言大致相同,都分为三步:
- 打开文件。如果文件不存在就创建(写模式)或者报错/退出(读模式)
- 从文件中读取/写入数据
- 关闭文件
接下来我们先从打开文件开始介绍,主要讲解一下函数。
打开文件
在PHP中打开文件,一般使用fopen()函数。除了传递需要打开的文件名外,还需要指定文件模式。
fopen()
上文中提到的文件模式,主要有三点需要注意:
- 只读/只写或者读/写
- 如果选择写模式,是覆盖原内容还是追加
- 可以使用二进制模式处理文件
fopen支持上述三种模式,使用方法为fopen(file_path,file_mode,[include_path,protocol])
。文件路径和文件模式是必选的,使用方法和C相同。主要参数如下,b表示二进制读/写。
- r,rb读文件
- w,wb写文件
- a,ab追加写文件
后两者是可选的,include_path是一个布尔值,PHP根据它判断是否要搜索include_path,这个值在PHP的配置中设置;后者则是协议前缀,比如http://
。
通过FTP或者HTTP打开文件
除了打开一个本地文件进行操作外,fopen()函数还支持通过FTP、HTTP等协议打开其他文件,这点可以在php.ini文件中设置。如果文件名以http://
开头,则fopen()函数将建立一个到指定服务器的连接,并返回一个指向HTTP响应的指针。FTP情况同理。
错误抑制符
调用fopen()函数时可能会产生各种错误,比如权限不够无法读取文件,或者文件不存在。可以在调用fopen()函数前加上@
错误抑制符来阻止PHP报错并用if语句来设置一个对用户更友好的自定义报错信息。
@$fp=fopen("order.txt","ab"); |
readfile()
向函数传递文件名,这个函数会把文件中所有的内容读取并输出至标准输出(浏览器)上,然后再关闭这个文件。
fpassthru()
像这个函数传递文件指针,其余作用和readfile()函数相同。
file()
file()函数和readfile()函数用法和效果相同,除此之外它还会把读取到的文件数据作为返回值发送到一个数组里。其中每一行都对应数组的一个元素。
file_get_contents()
作用与readfile()函数相同,但是这个函数不会把文件内容回显到浏览器上,而是以字符串的形式返回。
fread()
向函数传递一个文件指针和一个长度,函数将读取指定长度或者网络数据包结束前的部分。
写文件
在PHP中有很多写入文件的函数,下面一一列举。
fwrite()/fputs()
fwrite的使用方法为fwrite($fp,$outputstring);
,要求传入一个文件指针并将保存在$outputstring
的字符串写入文件。fputs()是fwrite()函数的别名。
file_put_contents
该函数原型如下所示。
int file_put_contents(string filename, |
它不需要使用fopen函数打开文件就可以将包含在data中的字符串写入到文件中。与之相匹配的函数是file_get_contents()。
fgets()
传入一个文件指针,每次读入一行,直到读取到换行符\n
或者文件结束符EOF
结束。
fgetss()
fgets()函数的变体,更加安全。它会把读取到的文件中所有的PHP和HTML标记符过滤。这样可以防止自己的HTML代码被破坏格式,或者读取到恶意的PHP代码。
fgetcsv()
fgets()函数的另一个变体,向函数传入文件指针,读取长度和分隔符。函数会在读取到分隔符时自动换行,分隔符可以是制表符\t
,空格等。如果不希望限制读取长度,可以将此参数设置为0。
fgetc()
传入一个文件指针,一次读取一个字符。
文件锁定
之所以引入这个概念,是因为PHP会遇到与C语言中不一样的情况。假如在一个订单系统中有两位用户同时下单了最后一个商品,如果没有文件锁定就会导致紊乱。所以引入flock()函数,在一个用户打开文件进行操作时,其他用户无法对该文件进行操作。
flock()
在任何一个文件被打开且在进行读写前,应该使用这个函数进行锁定。函数原型如下。
bool flock(resource fp,int operation[,int&wouldblock]) |
除了传入文件指针外,一样的要指定锁定模式。第三个参数是可选的,如果文件锁定导致进程堵塞,那么第三个参数的值将为true。
其中锁定模式总结如下。
操作值 | 意义 |
---|---|
LOCK_SH | 读操作锁定。意味着文件可以共享,其他人可以读文件 |
LOCK_EX | 写操作锁定。代表互斥,文件不能共享 |
LOCK_UN | 释放锁定 |
LOCK_NB | 防止在请求加锁时发生阻塞(Windows系统不支持)(我也不知道这是什么鬼) |
如果要使用flock()函数,就必须将其添加到所有使用文件的脚本中,否则没有意义。
使用flock()函数后,代码更加健壮,但是还不够好。因为加锁时仍然会产生竞争条件,这时候我们就需要DBMS数据库管理系统来帮助我们解决这个问题,后面再慢慢讲。
关闭文件
fclose()
和C语言相同,向其传入一个文件指针,关闭成功返回true,否则返回false。
其他
feof()
判断一个文件是否读到文件结尾。
file_exist()
判断一个文件是否存在。
filesize()
查看一个文件的大小,单位为字节。
unlink()
删除一个文件。
rewind()、fseek()、ftell()
用于在文件中定位,用法和C语言相同,不多赘述(无论是PHP还是C语言用的都极少)。