文件操作
文件
广义角度: 任何一个在磁盘上可以看到的符号(包含真正的文件及文件夹)
狭义角度: 真实存储数据的载体(不包含文件夹, 如doc文件,txt文件等)
文件操作: 对文件的增删改查
文件分成两类: 文件夹(路径)和文件(普通文件)操作
路径操作
对路径(文件夹)进行增删改查(CRUD)
C: create 新增
R: read/retrive 读取
U: update 更新
D: delete 删除
在计算机中: 操作仅有两类: 读和写(增删改)
读取路径
文件(路径)对于PHP来说,都属于外部数据: PHP以资源形式进行操作.
- 获取路径资源:resource opendir(路径); //路径可以是相对路径和绝对路径
-
//路径操作: 读取 header('Content-type:text/html;charset=utf-8'); //获取路径资源 $dir = '../'; //本质就是: D:/server/apache/htdocs $o = opendir($dir); //如果路径无效: 返回的false //var_dump($o);
- 获取资源中的数据: string readdir(路径资源): 资源操作是指针操作, 读取一个之后就会下移,如果读到最后,返回false
//获取路径资源 $dir = '../'; //本质就是: D:/server/apache/htdocs $o = opendir($dir); //如果路径无效: 返回的false //var_dump($o); //读取资源(取得其中包含的文件名) echo '<pre>'; var_dump(readdir($o)); var_dump(readdir($o)); var_dump(readdir($o));
- 遍历读取整个文件夹: readdir + 循环
//遍历文件夹 while($file = readdir($o)){ //输出 echo $file,'<br/>';
- 若想重复使用资源,需要重置指针: rewinddir(路径资源)
//查看当前指针 var_dump(readdir($o)); //重置指针 rewinddir($o); //查看重置后效果 var_dump(readdir($o));
- 关闭资源: closedir(路径资源)
//关闭资源-释放内存 closedir($o);
7,完整代码
<?php //路径操作: 读取 header('Content-type:text/html;charset=utf-8'); //获取路径资源 $dir = '../'; //本质就是: D:/server/apache/htdocs $o = opendir($dir); //如果路径无效: 返回的false //var_dump($o); //读取资源(取得其中包含的文件名) echo '<pre>'; //var_dump(readdir($o)); //var_dump(readdir($o)); //var_dump(readdir($o)); //遍历文件夹 while($file = readdir($o)){ //输出 echo $file,'<br/>'; //文件从目录中读取出来(操作系统是中文系统:GBK) //转码函数: iconv('原数据GBK','目标字符集UTF-8','转换内容'); //echo iconv('GBK','UTF-8',$file),'<br/>'; //iconv是一个转义字符编码的函数 } //var_dump(readdir($o)); //重置指针 //rewinddir($o); //var_dump(readdir($o)); //关闭资源 closedir($o);
路径相关函数
file_exists: 判断一个文件是否存在(广义文件: 包括路径和文件)
//路径操作相关函数:(包含增删改) //定义路径 $dir1 = '../'; //有效路径(相对路径) $dir2 = 'D:/server'; //绝对路径 $dir3 = 'test'; //当前目录下的test目录: 20150924/test/ $file1 = 'demo01_dir_read.php'; //有效文件 $file2 = 'test.txt'; //无效文件(当前目录不存在) echo '<pre/>'; //判断文件有效性(广义) var_dump(file_exists($dir1)); //true var_dump(file_exists($dir2)); //true var_dump(file_exists($dir3)); //false: 没有 var_dump(file_exists($file1)); //true var_dump(file_exists($file2)); //false: 不存在
is_dir: 判断路径是否有效
//路径操作相关函数:(包含增删改) //定义路径 $dir1 = '../'; //有效路径(相对路径) $dir2 = 'D:/server'; //绝对路径 $dir3 = 'test'; //当前目录下的test目录: 20150924/test/ $file1 = 'demo01_dir_read.php'; //有效文件 $file2 = 'test.txt'; //无效文件(当前目录不存在) //判断 echo '<pre>'; //路径判断 var_dump(is_dir($dir1)); //true var_dump(is_dir($dir2)); //true var_dump(is_dir($dir3)); //false: 不存在 var_dump(is_dir($file1)); //false: 不是路径是文件
is_file: 判断文件是否有效
Mkdir: mk: make,创建路径(文件夹)
//加@符号防止已经创建再次创建出现错误 //创建目录 //var_dump(@mkdir('test'));
Rmdir: remove, 删除路径
//删除目录 var_dump(@rmdir('test'));
文件夹读取
有一个函数: 已经将遍历读取文件夹这件事进行了封装: array scandir(有效路径), 返回一个数组,数组中包含所有当前路径下的文件名.
//定义路径 $dir = '../'; //获取路径下的所有文件名 $files = scandir($dir); //var_dump($files);
如果遍历出来的结果是一个文件夹: 那么用蓝色输出,如果是文件,使用红色输出.
//遍历输出 foreach($files as $file){ //判断: 文件夹蓝色,文件红色 //如果要判断一个文件是否有效: 一定要指定路径 if(is_dir($dir . '/' . $file)){ //$file只是一个文件名(字符串) //路径 echo '<font color="blue">',$inner,'</font><br/>'; }else{ //文件 echo '<font color="red">',$inner,'</font><br/>'; }
如果当前从文件夹中读出来的内容依然是一个文件夹: 说明内部还有文件需要遍历: 继续用scandir读取里面的内容,然后再遍历输出.
echo '<font color="blue">',$file,'</font><br/>'; //.和..是"无效路径": 无效子文件夹,要排除 if($file == '.' || $file == '..') continue; //路径下依然有文件: 再次读取 $innerfiles = scandir($dir . '/' . $file); //再次遍历 foreach($innerfiles as $inner){ //缩进 echo str_repeat(" ",4); //判断: 路径蓝色,文件红色 if(is_dir($dir . '/' . $file . '/' . $inner)){ //路径 echo '<font color="blue">',$inner,'</font><br/>'; }else{ //文件 echo '<font color="red">',$inner,'</font><br/>'; } } }else{ //文件 echo '<font color="red">',$file,'</font><br/>'; } }
遍历当前目录下的文件夹如果是空文件夹则蓝色,是文件则红色
<?php //利用函数scandir遍历路径 //定义路径 $dir = '../'; //获取路径下的所有文件名 $files = scandir($dir); //var_dump($files); //遍历输出 foreach($files as $file){ //判断: 文件夹蓝色,文件红色 //如果要判断一个文件是否有效: 一定要指定路径 if(is_dir($dir . '/' . $file)){ //$file只是一个文件名(字符串) //路径 echo '<font color="blue">',$file,'</font><br/>'; //.和..是"无效路径": 无效子文件夹,要排除 if($file == '.' || $file == '..') continue; //路径下依然有文件: 再次读取 $innerfiles = scandir($dir . '/' . $file); //再次遍历 foreach($innerfiles as $inner){ //缩进 echo str_repeat(" ",4); //判断: 路径蓝色,文件红色 if(is_dir($dir . '/' . $file . '/' . $inner)){ //路径 echo '<font color="blue">',$inner,'</font><br/>'; }else{ //文件 echo '<font color="red">',$inner,'</font><br/>'; } } }else{ //文件 echo '<font color="red">',$file,'</font><br/>'; } }
文件操作
针对狭义文件的增删改查.
PHP中文件操作分为两种: “高级版”操作和”低级版”操作.
高级版操作: PHP5操作, PHP5以后, PHP重新封装了一组函数用来操作文件
File_get_contents,file_put_contents,file: 都不涉及资源操作
低级版操作: PHP5以前的操作, 以资源形式进行操作.
“高级版”操作
文件读取操作
PHP高级操作中: 封装一个函数,可以直接从文件中读取所有内容
String File_get_contents(‘文件路径’);
//PHP5文件读取操作 header('Content-type:text/html;charset=utf-8'); //给定文件路径 $file = 'demo01_dir_read.php'; //读取其中内容 $str = file_get_contents($file); //var_dump($str); //file读取文件 $arr = file($file); var_dump($arr);
文件写操作
在PHP高级版中: PHP提供了一个函数,可以将要写入的数据直接写入到文件: int file_put_contents(目标文件,要写入的内容[,写入方式]); //该函数可以自动创建一个不存在的文件.
//PHP5文件写操作 //准备要写入文件的内容 $info = 'hello world'; //写入文件 $res = file_put_contents('hey.txt',$info); //var_dump($res);
PHP中: file_put_contents默认的永远是覆盖数据,若想追加数据,需要通过第三个参数控制(写入方式)
FILE_USE_INCLUDE_PATH : 值为1, 也是覆盖
FILE_APPEND: 值为8, 代表追加
//PHP5文件写操作 //准备要写入文件的内容 $info = 'hello world'; //写入文件 $res = file_put_contents('hey.txt',$info); //var_dump($res); //echo FILE_APPEND; //追加文件写入 file_put_contents('hey.txt','你好世界',FILE_APPEND);
“低级版”操作
低级版操作: PHP5以前对文件的操作方式: 采用资源形式进行操作.
不论读写,都是资源操作.
读操作
- 打开文件资源: resource fopen(文件路径,’操作模式’): 在一开始打开资源的时候,就必须指定打开是为了干什么: 读还是写
操作模式: 采用什么样的方式对数据进行操作: 读,写或者读写
-
读取模式打开数据(r)
//低版本文件读操作 header('Content-type:text/html;charset=utf-8'); //打开文件资源: r模式打开(只读) $f = fopen('hey.txt','r'); //var_dump($f); echo '<pre>';
- 读取数据: 所有的读取操作都是指针操作, 读完之后指针会下移到指定位置
Fgetc: c代表character, 一次读取一个字节
//读取数据 //按字节读取 //var_dump(fgetc($f));
Fgets: s代表string, 一次读取指定长度的字符串或者一行(最多一行)
//按行读取 //var_dump(fgets($f,5)); //var_dump(fgets($f,1024));
Fread: 获取指定长度的字符串
//读取指定长度 var_dump(fread($f,1024));
- 关闭资源: fclose(打开资源)
//关闭资源 fclose($f);
写操作
- 使用读写方式打开资源: w+
//PHP低版本文件写操作:读写 //打开资源: w+ $f = fopen('hey.txt','w+'); //var_dump($f);
- 写操作: fputs/fwrite(资源,要写的数据);
//写入内容 $res = fputs($f,'hello world'); //var_dump($res);
- 读取数据
-
当前模式是读写模式: 一上来就清空了所有数据, 然后重写: 写一个指针下移一个: 当写完之后指针在文件的最末尾: 永远读到false: 需要充值指针: fseek(资源,指针位置);
//重置指针 fseek($f,2); //读取数据 var_dump(fgets($f,1024));
- 关闭资源
//关闭资源 fclose($f);
文件操作相关函数
Copy: 复制
//文件复制 copy('hey.txt','hello.txt'); //默认都在当前目录操作
删除文件
//删除文件 @unlink('hey.xls');
//重命名 rename('hello.txt','hello.xls'); //如果文件不存在会报错
Rename可以指定新名字文件所在的路径: 可以实现文件的移动: 剪切
Filemtime: m代表modify, 文件最后修改时间
//获取文件修改时间 var_dump(date('Y-m-d H:i:s',filemtime('demo01_dir_read.php'))); //时间戳
Filesize: 文件大小
//获取文件大小 var_dump(filesize('hey.txt'));
Fileperms: perms: permission权限的意思, 获取文件的权限(linux): linux下的权限是分为三组: 创建者, 所属组,其他用户, 每种用户都有三种权限: 读1, 写1, 执行0 => 6: 默认是8进制数据
//获取文件权限 echo fileperms('demo01_dir_read.php'); printf('%o',fileperms('demo01_dir_read.php'));
代码
<?php //文件操作相关函数 echo '<pre>'; //获取文件权限 echo fileperms('demo01_dir_read.php'); printf('%o',fileperms('demo01_dir_read.php')); //获取文件修改时间 var_dump(date('Y-m-d H:i:s',filemtime('demo01_dir_read.php'))); //时间戳 //获取文件大小 var_dump(filesize('hey.txt')); //文件复制 copy('hey.txt','hello.txt'); //默认都在当前目录操作 //删除文件 @unlink('hey.xls'); //重命名 rename('hello.txt','hello.xls'); //如果文件不存在会报错 //move_uploaded_file('hello.xls','hey.xls'); //只能操作上传文件
文件下载
文件下载: 从服务器将文件获取到本机电脑的过程.
下载的本质: 服务器将文件读取到内存 -> 通过内存将数据打包发送给浏览器 -> 浏览器接收数据整理成文件.
实现文件下载有两种方式: a标签下载和PHP下载
A标签下载
刚好浏览器碰到了一个不能识别的文件: 浏览器解析不了, 保存
<a href="hey.txt">点我下载</a> <a href="demo10_php_download.php">点我PHP下载</a>
缺点
- 对文件格式有要求: 浏览器不可识别的文件
- 不安全: 会严格暴露文件的位置,文件的真实路径,名字等
-
PHP下载
PHP要实现下载需要解决一个问题: 浏览器不要解析
Header(‘Content-type:application/octet-stream’); //header之前不要输出内容
header('Content-type:application/octet-stream'); //二进制流浏览器不能解析
PHP下载
PHP要实现下载需要解决一个问题: 浏览器不要解析
Header(‘Content-type:application/octet-stream’); //header之前不要输出内容
//PHP实现文件下载 header('Content-type:text/html;charset=utf-8'); //告诉浏览器不要解析内容 header('Content-type:application/octet-stream'); //二进制流浏览器不能解析
将文件读取内存,输出给浏览器: echo
//读取文件输出给浏览器 echo file_get_contents('hey.txt');
解决文件名字问题: 服务器要告诉浏览器,建议用什么名字保存文件.
Header(‘Content-disposition:attachment;filename=建议的名字’);
//建议浏览器对文件进行命名处理 header('Content-disposition:attachment;filename=美女.jpg');
优点
- 任何文件都可以实现下载(浏览器不允许解析)
- 任何文件都不会暴露真实内容,真实路径,真实名字
<?php //PHP实现文件下载 header('Content-type:text/html;charset=utf-8'); //告诉浏览器不要解析内容 header('Content-type:application/octet-stream'); //二进制流浏览器不能解析 //建议浏览器对文件进行命名处理 header('Content-disposition:attachment;filename=美女.jpg'); //读取文件输出给浏览器 echo file_get_contents('hey.txt');