文件编程的初步认识
目录
文件编程的必要性
文件编程指利用PHP代码针对文件(文件夹)进行增删改操作。
在实际开发项目中,会有很多内容(文件上传,配置文件等)具有很多不确定性,不能在一开始就手动创建,需要根据实际需求和数据本身来进行管理,这个时候就可以使用PHP文件编程来实现代码批量控制和其他操作。
文件操作的分类
1)目录操作:文件夹,用来存放文件的 特殊文件
2)文件操作:用来存放内容
目录操作
文件操作创建目录结构
1)mkdir(路径名字):创建成功返回true,创建失败返回false
有些操作为的就是得到一个想要的结果,如果结果本身存在,那么可以忽略得到过程的错误:
抑制错误
删除目录
1)rmdir (string $dirname):移除文件夹
读取目录
读取方式:将文件夹(路径)按照资源方式打开
1)opendir():打开资源,返回一个路径资源,包含指定目录下的所有文件(文件夹)
2)readdir():从资源中读取指针所在位置的文件名字,然后指针下移,直到指针移出资源
在任何一个文件夹下都有这两个文件。
读取所有内容:遍历操作
关闭目录
1)closedir():关闭资源
其他目录操作
1)dirname(提供一个路径):得到的是路径的上一层路径
2)realpath(一个路径):得到真实路径
3)is_dir():判断指定路径是否是一个目录
4)scandir():封装版的opendir\readdir\closedir,获取一个指定路径下的所有文件信息,以数组形式返回。
递归遍历目录
递归遍历目录:指定一个目录的情况下,将其下的所有文件和目录,以及目录内部的所有内容都输出出来。
递归遍历目录的思维逻辑:
1、设计一个能够遍历一层文件的函数
a.创建函数
b.安全判定:是路径才访问
c.读取全部内容,遍历输出
2、找到递归点:遍历得到的文件是目录,应该调用当前函数
a.遍历得到的结果只是文件的名字,需要构造路径
b.需要排除.和..
c.判断是路径还是文件
d.是路径,递归调用本身
3、找到递归出口:遍历完这个文件夹之后,发现没有任何子文件夹:自带出口
4、如何显示层级关系?函数第一次运行遍历的结果是最外层目录,内部调用一次说明进入一个子目录,子目录。。。。如果能够在第一次调用的时候给个标记,然后在进入的时候,通过标记的变化来识别层级关系,就可以达到目的:该标记还能代表层级关系:缩进
a.在函数参数中增加一个标记:默认值为0
b.递归调用的时候也需要使用该参数:但是是属于当前层级的子层,所以加一
c.根据层级来实现缩进:str_repeat()
PHP代码实现:
<?php
//递归遍历文件夹
//定义路径
$dir = '../uploads';
/*
*创建函数:能够访问指定路径下的所有文件,且判断出,目录还是文件
*@param1 string $dir,指定路径
*@param2 int $level=0,层级,默认顶层
*/
function my_scandir($dir,$level=0){
//保证文件的安全:如果不是路径没有必要往下
if(!is_dir($dir)) dir($dir.'<br/>');
//读取全部路径信息,遍历输出
$files = scandir($dir);
foreach($files as $file){
//$file就是一个个文件名
echo str_repeat(' ',$level),$file.'<br/>';
//排除.和..
if($file == '.' || $file == '..') continue;
//构造路径
$file_dir = $dir.'/'.$file;
//echo $file_dir.'<br />';
//判断路径
if(is_dir($file_dir)){
//递归点
my_scandir($file_dir,$level+1);
}
}
}
//测试
my_scandir($dir,$level=0);
文件操作
常见文件操作函数
字符串形式处理:
1)file_get_contens($filename): 将整个文件读入一个字符串,如果路径不存在,最好做错误处理。
2)file_put_contens($filenmae):将一个字符串写入文件,如果当前路径下不存在指定的文件,函数会自动创建(如果路径不存在,不会创建路径)
资源类型处理:不论读还是写,都依赖资源指针:文件内容指针所在的位置
1)fopen(string $filename , string $mode):打开一个文件资源或者 URL,限定打开模式
2)fread(resource $handle , int $length):从打开的资源中读取指定长度的内容(字节)
3)fwrite(resource $handle , string $string [, int $length ]):向打开的资源中写入指定的内容
4)fclose(resource $handle):关闭
5)feof(resource $handle): 测试文件指针是否到了文件结束的位置
其他文件操作函数
1)is_file(string $filename):判断文件是否正确,不识别路径
2)filesize(string $filename):获取文件大小
3)file_exists(string $filename):判断文件是否存在,识别路径
4)unlink(string $filename [, resource $context ]):取消文件名字与磁盘地址的连接(删除文件)
5)filemtime(string $filename):获取文件最后一次修改的时间
6)fseek(resource $handle , int $offset [, int $whence = SEEK_SET ]):设定fopen打开的文件的指针位置
7)fgetc(resource $handle):一次获取一个字符,文件指针必须是有效的,必须指向由 fopen() 或 fsockopen() 成功打开的文件(并还未由 fclose() 关闭)。
8)fgets(resource $handle [, int $length ]):一次获取一行字符串(默认),也可以指定长度,长度大于一行取一行。
9)file(string $filename):读取整个文件,类似file_get_contents(),区别是按行读取,返回一个数组
文件下载
文件下载:从服务器将文件通过HTTP协议传输到浏览器,浏览器不解析保存成响应的文件
提供下载方式可以使用HTML中的a标签:<a href=”文件路径”>单机下载</a>
1、缺点1:a标签能够让浏览器自动下载的内容有限:浏览器是发现如果解析不了才会启用下载,如果是HTML等不会下载。
2、缺点2:a标签下载的文件存储路径会需要通过href属性写出来,这样会暴露服务器存储数据的位置(不安全)
PHP下载:读取文件内容,以文件流的形式传递给浏览器:在响应头中告知浏览器不要解析,激活下载框实现下载
1)指定浏览器解析字集
2)设定响应头:
a)设定文件返回类型:image/jpg ||application/octem-stream
b)设定返回文件计算方式:Accept-ranges:bytes
c)设定下载提示: Content-disposition:attachment;filename=’文件名字’
d)设定文件大小:Accept-length:文件大小(字节)
3)读取文件
4)输出文件
方式1:如果文件较小,可以使用:file_get_contents
方式2:如果文件比较大或者网络不好,可以使用:资源指针