php基础系列之 数据的存储和读取

·文件处理
·写入一个文件
1,打开这个文件。如果这个文件不存在,需要先创建它
2,将数据写入这个文件
3,关闭这个文件
·从一个文件读出数据
1,打开这个文件。如果这个文件不能打开(例如,文件不存在),就应该意识到这一点并且正确退出
2,从这个文件中读出数据
3,关闭这个文件
·打开文件
要在php中打开一个文件,可以使用fopen()函数。当打开一个文件的时候,还需要指定如何使用它。也就是文件模式
·选择文件模式
打开一个文件,有三种选择,只读、只写、或者读和写。函数fopen()支持这三种方式的组合
·fopen()
·$_SERVER['DOCUMENT_ROOT'] :PHP预定义的几个变量之一;作用:获取当前Web服务器文档树的根目录(绝对路径)
使用'..'表示这个文档根目录的父目录
·在UNIX环境下,目录中的间隔符是正斜线(/)。如果是window平台,可以使用正斜线或者反斜线。如果使用反斜线,就必须使用
转义(标记为一个特殊)字符.
$fp = fopen("$_SERVER['DOCUMENT_ROOT']\..\orders\orders.txt",'w');
·在PHP代码中,很少人使用反斜线,因为这意味着代码只能在Windows上运行
·fopen()函数的第二个参数是文件模式,它是一个字符串,指定了将对文件进行的操作
模式 模式名称 意义
r 只读 读模式---打开文件,从文件头开始读
r+ 只读 读写模式---打开文件,从文件头开始读写
w 只写 写模式---打开文件,从文件头开始写。如果该文件已存在,将删除所有文件已有内容。如果文件不存在,函数将创建这个文件
w+ 只写 写模式---打开文件,从文件头开始读写。如果该文件已存在,将删除所有文件已有内容。如果文件不存在,函数将创建这个文件
x 谨慎写 写模式打开文件,从文件头开始写,如果文件已存在,该文件将不会被打开,fopen()函数将返回false,而PHP将产生一个警告
x+ 谨慎写 写模式打开文件,从文件头开始读写,如果文件已存在,该文件将不会被打开,fopen()函数将返回false,而PHP将产生一个警告
a 追加 追加模式---打开文件,如果该文件已有内容,将从文件末尾开始追加写,如果该文件不存在,函数将创建这个文件
a+ 追加 追加模式---打开文件,如果该文件已有内容,将从文件末尾开始追加写(或者读),如果该文件不存在,函数将创建这个文件
b 二进制 二进制模式---用于与其他模式进行连接。如果文件系统能够区分二进制文件和文本文件,你可能会使用它。Windows系统可以区分,而UNIX则不区分。推荐一直使用这个选项,以便获得最大程度的可移植性。二进制模式是默认的模式
t 文本 用于与其他模式的结合,这个模式只是windows系统下一个选项。它不是推荐选项,除非你曾经在代码中使用了b选项

·正确的文件模式取决于系统如何使用它。我们已经使用了"w",这表示只可以将一个订单写入文件中。每当一个新订单被写入文件,它将覆盖以前的订单。这样做可能没有
什么意义,所有最好使用追加模式(以及推荐的二进制模式):
$fp = fopen("$_SERVER['DOCUMENT_ROOT']/../orders/orders.txt",'ab');
·fopen ()成功打开一个文件,该函数将返回一个指向这个文件的文件指针。在上面这个示例中
,文件指针保存在$fp中,当读者的确希望能够读写这个文件时,将使用这个变量来访问文件。
·解决打开文件时可能遇到的问题
当打开文件时,可能经常遇到的错误是试图也会在Windows平台上遇到)打开一个没有读写权限的文件(这种错误通常只会在类似UNIX的操作系统中见到,但是偶尔会在Windows平台上遇到。
·写文件
在php中写文件相对比较简单。可以使用fwrite()
·fwrite()参数
实际上,fwrite()具有3个参数,但是第3个参数是可选的。fwrite()的原型如下代码所示:
int fwrite ( resource handle , string [, int length])
第3个参数length是写入的最大字符数。如果给出了这个参数,fwrite()将向handle指向的文件写入字符串string,一直写到字符串的末尾,或者已经写入了length
字节,满足这两个条件之一就停止写入。
可以通过php的内置strlen()函数获得字符串的长度:
fwrite($fp , $outputstring , strlen($outputstring));
当使用二进制模式执行写操作时,你可能希望使用第3个参数,因为它可以帮助你避免一些跨平台兼容问题
·关闭文件
当使用完文件后,应该将其关闭。应该按照如下所示的方式调用fclose()函数
fclose($fp);
如果该文件成功地关闭,函数将返回一个null值。反之,该函数将返回false。通常,关闭文件的操作并不像打开文件容易出错,所以这个示例中并没有对该操作进行测试
·读文件
//以只读模式打开文件:fopen()
$fp = fopen("$document_root/../orders/orders.txt",'rb');
flock($fp,LOCK_SH) // lock file for reading
//feof($fp) 知道何时读完文件,feof()的唯一参数是文件指针。如果文件指针指向了文件末尾,它将返回true
while(!feof($fp)){
$order = fgets($fp); // 从文件中每次读取一行内容。
echo "$order<br />";
}
flock($fp,LOCK_UN); // release read lock
fclose($fp);

·每次读取一行数据
·fgets() //每次读取一行内容。这样,它将不断地读入数据,直至读到一个换行字符 ( ),或者文件结束符EOF
·fgetss() //fgets()的一个变体
原型:string fgetss(resource fp[, int length[,string allowable_tags]]);
与fgets()非常相似,但是它可以过滤字符串中包含的PHP和HTML标记。如果需要保留任何特殊的标记,可以将它们包含在allowable_tags字符串中
出于安全考虑可以使用fgetss()函数
·读取整个文件
·readfile()
//你几乎可以使用下述语句代替前面所编写的所有脚本
readfile("$document_root/../orders/orders.txt")
//执行流程:打开这个文件,并将文件内容输出到标准输出(浏览器中),然后再关闭这个文件,原型如下:
int readfile(string filename ,[bool use_include_path[,resource content]]);
//返回值是从文件中读取的字节数
·file_get_contents()
//该函数与readfile()相同,但是该函数将以字符串的形式返回文件内容,而不是将文件内容回显到浏览器中。
·读取任意长度
fread()
读取一个文件的最后一种方法是使用fread() 函数从文件中读取最大任意长度的字节
string fread(resource fp, int length);
注:本人测试,此方法不适合网络资源(http)
·使用其他文件函数
·查看文件是否存在:file_exists()
在不打开一个文件的前提下,检查一个文件是否存在
file_exists("demo.php");
·确定文件大小:filesize()
它以字节为单位返回一个文件的大小,结合 fread()函数,可以使用它们一次读取整个文件(或者文件的某部分)
filesize("demo.php");
·删除一个文件unlink()
unlink("demo.php");
如果无法删除这个文件,该函数将返回false。通常原因是对该文件的访问权限不够或者该文件不存在
·文件锁定
为了解决并发问题,建议使用文件锁定。在PHP中,文件锁定是通过flock()函数来实现的。当一个文件被打开并且在进行读写操作之前,应该调用这个函数。原型:
bool flock ( resource fp , int operation [, int &wouldblock);
还必须将一个指向被打开的文件的指针和一个表示锁定类型的常数作为参数传递给这个函数。如果锁定成功,则返回true。如果获得文件锁将导致当前的进程被阻塞(也就是,不得不等待)
操作值:
LOCK_SH --- 读操作锁定。意味着文件可以共享,其他人可以读该文件
LOCK_EX --- 写操作锁定。这是互斥的,该文件不能共享
LOCK_UN --- 释放已有的锁定
LOCK_NB --- 方式在请求加锁时发生阻塞(windows不支持)
联想:如果有两个脚本同时申请对一个文件加锁,情况又会如何呢?这将导致竞争条件的问题,这两个进程将竞争加锁,但是无法确定哪个进程将会成功,这样
就会导致更多的问题。使用数据库管理系统,可以很好的解决这写问题
·当文件变大,使用普通文件将会变得非常慢
·在一个普通文件查找特定的一个或者一组记录将会非常困难
·处理并发访问可能会遇到问题。如果有太多的访问量,在能够创建订单之前大量的用户就可能必须等待该文件解锁
·在文件中文插入记录和删除记录太难
·没办法区分不同权限的数据访问
·最简单的方法:
·file_get_contents
//将整个文件读入一个字符串
//file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来增强性能。
file_get_contents(path,include_path,context,start,max_length)
·file_put_contents()
//函数把一个字符串写入文件中。与依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
file_put_contents(file,data,mode,context)
参数data --- 可选。规定要写入文件的数据。可以是字符串、数组或数据流。