1.文件操作函数
1.回顾:
文件常见分类:file(文件) 和 dir(文件夹)
路径: 相对路径 . 当前目录 .. 上级目录
绝对路径 (盘符型,网址型,根www)
2.文件属性:
1.文件类型:
filetype(' 文件路径 ') 输入一个文件路径,返回文件类型(file 文件|dir 文件夹)
2.文件大小:
filesize(' 文件路径 ') 输入一个文件路径,检测文件大小,单位是字节(不支持文件夹,结果不准确,以最小文件单元(4096字节)作为单元计算)
3.文件是否存在:
file_exists(' 文件路径 ') 输入一个路径,返回判断结果bool值
4.文件是否可读可写
is_readable(' 文件路径 ') 输入一个路径,判断是否可读,返回bool值
is_writeable(' 文件路径 ') 输入一个路径,判断是否可写,返回bool值
5.返回文件的创建/修改/访问时间
filectime(' 文件路径 ') 输入路径,返回文件的创建(creative)时间
filemtime(' 文件路径 ') 输入路径,返回文件的修改(modification)时间
fileatime(' 文件路径 ') 输入路径,返回文件的访问(access)时间
6.获取目录/文件名
dirname(' __FILE__ ') 输入当前文件路径,获取路径名(dir)
basename(' __FILE__ ') 输入当前文件路径,获取文件名(file)
1 2 3 4 5 6
| 需求:面试题 获取该地址的文件扩展名 $url = 'http://www.baidu.com/av/gt18/ka.n.g.mp4?age=18&type=人兽#xxoo'; $a=basename($url); $a=strtok($a,'?'); $a=strrchr($a,'.');
|
7.网址解析
parse_url(' url ')
1 2 3 4 5 6 7 8 9 10
| $url='http://www.baidu.com:80/av/gt18/ka.n.g.mp4?age=18&type=人兽#xxoo' var_dump(parse_url($ur;)); /*array (size=6) 'scheme' => string 'http' (length=4) #协议 'host' => string 'www.baidu.com' (length=13) #域名 'port' => int 80 #端口 'path' => string '/av/gt18/ka.n.g.mp4' (length=19) #路径 'query' => string 'age=18&type=人兽' (length=18) #参数 'fragment' => string 'xxoo' (length=4)*/ #锚点
|
8.盘符解析
pathinfo(' $path ')
1 2 3 4 5 6 7 8
| $path='D:\wamp\www\s86\0422\01-file.php'; var_dump($path); /*array (size=4) 'dirname' => string 'D:\wamp\www\s86\0422' (length=20) #路径名 'basename' => string '01-file.php' (length=11) #文件名 'extension' => string 'php' (length=3) #扩展名 'filename' => string '01-file' (length=7)*/ #文件名(无后缀)
|
3.递归函数(三元归一遍历)
1.函数
opendir(' path ') 打开一个目录,返回资源
readdir(' resource name ') 读取一个资源,返回当前资源名(实际上利用指针)
close(' resource name ') 关闭一个资源,释放内存
2.应用
需求:将./demo1 目录中的所有文件名,输出到屏幕上
1.原始访问方式:
1 2 3 4 5 6 7 8 9 10
| $handle=opendir('./demo1'); #windows中,每个文件夹中都有 . 和 .. 文件夹 var_dump(readdir($handle)); #当前目录 . var_dump(readdir($handle)); #上级目录 .. var_dump(readdir($handle)); ... var_dump(readdir($handle));
var_dump(readdir($handle)); #超出范围之外,返回false closedir($handle);
|
2.循环访问方式:
1 2 3 4 5 6 7 8 9 10
| $handle=opendir('./demo1'); while( ($file=readdir($handle))!=false ){ #循环访问方式 if($file=='.'||$file=='..'){ #排除显示 . 和 .. continue; } echo $file; echo '<br>'; } closedir($handle); #关闭资源
|
3.递归函数
1.函数:
is_file( 'path name' ) 判断当前路径是否为文件
is_dir( 'path name' ) 判断当前路径是否为目录
注:参数必须为完整的地址,否则输出false。相对,绝对都可以
2.递归函数:
1)函数自己调用自己
2)必须要有终止条件
3.应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 1.需求:函数功能-输出所有子目录下的所有文件和子目录 function getFile( $dir ) { $handle=opendir($dir); #打开目录,获取资源 while(($file=readdir($handle))!=false){ #读取资源 if($file=='.'|$file=='..'){ #排除 . 和 .. 文件夹 continue; } $path=$dir.'/'.$file; #拼凑完整路径 if(is_file($path)){ #判断是否为文件,是则输出文件名 echo $file.'<br>'; } if(is_dir($path)){ #判断是否为目录,是则输出目录名, echo $file.'<br>'; getFile($path); #调用函数打开子目录 } } closedir($handle); #关闭资源 }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 2.需求:函数功能-获取某个目录的大小 function getDirSize( $dir ) { $handle=opendir($dir); $sum=0; while(($file=readdir($handle))!=false){ if($file='.'|'..'){ continue; } $path=$dir.'/'.$file; if(is_file($path)){ $sum=$sum+fileseze($path); } if(is_dir($path)){ $sum+=getDieSize($path); } } closedir($handle); renturn $sum; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 3.需求:函数功能-统计某个目录下有多少个文件和文件夹 function getFileNumber( $dir ) { $handle=opendir($dir); $dirSum=0; $fileSum=0; while(($file=readdir($handle))!=false){ if($file='.'||$file='..'){ continue; } $path=$dir.'/'.$file; if(is_file($path)){ $fileSum+=1; } if(is_dir($path)){ $dirSum+=getFileNumber($path); $fileSum+=getFileNumber($path); } } closedir($handle); }
|
4.文件操作
1.拷贝文件
copy( 来源地址,目标地址 ) 将目标文件拷贝到目标文件中(不支持目录拷贝)
copy('./01-file.php','./demo1/01-file.php');
2.创建目录
mkdir( 目录路径 ) 在目标路径创建一个文件夹
mkdir( 目录路径,0777,true ) 在目标路径创建多级目录文件夹
mkdir('./x/y/z', 0777, true);
3.删除目录
rmdir( 目录路径 ) 只能删除空文件夹
rmdir('./x');
4.创建/删除文件
touch( 文件名 ) 创建文件
unlink( 文件名 ) 删除文件
touch('./demo1/test.php'); unlink('./demo1/test.php');
5.重命名/剪切文件
rename( 旧文件名,新文件名 ) 修改目录,剪切
rename('./test', './demo1/test.txt'); #修改目录,剪切
rename('./test.txt', './testxxx.txt'); # 目录不变,重命名
5.文件编码问题
Windows默认gbk编码,PHP默认utf-8编码,编码不一致时,会发生编码解析问题
iconv( 源编码,目标编码,内容 )
copy(iconv('utf-8','gbk','./递归.png'),'./xx.png')
6.baidu云盘递归遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>百度云盘</title> <style> table{width: 500px;/*height: 60px;*/margin:20px auto;border-collapse:collapse;font-size: 14px;} table tr:hover{background: #f4fbff;} table tr:hover th{border-color: #cbedff;} table tr:hover td{border-color: #cbedff;} table th{text-align: left;border-bottom:1px solid #ccc;/*line-height: 30px;*/border-color: #999;} table td{border-bottom:1px solid #ccc;border-color: #999;} .dir{background:url('./Baidu/icon.png') -380px -627px;width: 26px;height: 26px;display:inline-block;vertical-align: middle;} .file{background:url('./Baidu/icon.png') -380px -627px;width: 26px;height: 26px;display:inline-block;vertical-align: middle;} </style> </head> <body> <table> <tr> <th>文件名</th> <th>大小</th> <th>修改日期</th> </tr> <!-- <tr> <td><div class="dir"></div>我的卡包</td> <td>xxx</td> <td>xxxxxx</td> </tr> --> <?php $x=empty($_GET['path'])?'./demo1':$_GET['path']; getFileName($x); ?>
</table> </body> </html>
<?php
function getFileName($dir){
$handle=opendir($dir);
// $file=readdir($handle);
while(($file=readdir($handle))!=false){
echo '<tr>';
if ($file=='.'||$file=='..') { continue; }
$path=$dir.'/'.$file;
if (is_file($path)) { echo '<td><div class="file"></div>'.$file.'</td>'; echo '<td>'.filesize($path).'</td>'; }
if (is_dir($path)) { echo "<td><div class='dir'></div><a href='?path={$path}'>{$file}</a></td>"; echo '<td> - </td>'; } echo '<td>'.filemtime($path).'</td>';
echo '</tr>';
}
closedir($handle);
}
?>
|
7.文件加载
1.函数:
include ' 文件路径 ' #加载(当做关键字使用) 依赖 require ' 文件路径 '
include( 文件路径 ) #加载(当做函数使用) 依赖 require( 文件路径 )
include_once( 文件路径 ) #加载一次 依赖 require_once( 文件路径 )
include_once ' 文件路径 ' #加载一次 依赖 require_once ' 文件路径 '
2.作用:
将文件A加载到文件B中,文件B从而可以使用文件A中的所有数据
相当于将文件A的所有代码复制到文件B中的 include / require 处
3.使用
include './demo.php'; require './demo.php';
include_once './demo.php'; require_once './demo.php';
4.特性
1.include / require 可以重复加载
2.但被重复加载的文件内部,函数和常量会被重定义,报错
3.避免重复加载,可以通过include_once / require_once只加载一次
4.include 加载出错,不会终止程序,require 加载出错,立马终止程序
5.支持相对路径,盘符路径,不支持网址路径
8.文件内容操作函数
1.向文件赋予内容
file_put_contents('文件路径','文件内容');
若文件路径不存在,则自动创建;若路径存在,则先将文件大小截为0,再写入内容(覆盖)
代码实例:file_put_contents('./test.txt','how are you?');
2.获取文件的所有内容
file_get_contents('文件路径');
支持全格式地址,若输入网址地址,则爬取跳转当前页面(只有外表,无功能)
代码实例:echo file_get_contents('./test.txt');
echo file_get_contents('http://www.baidu.com');
3.打开一个文件
fopen('文件路径','打开模式'); 返回值:资源
#打开模式详解:
r 只读,指针指向文件开头,若文件不存在,报错
w 只写,指针指向文件开头,若文件不存在,则自动创建,且大小截为0
a 追加,指针指向文件末尾,若文件不存在,则自动创建
+ 增强,既可以读又可以写,但需要以上模式配合
代码实例: $handle=fopen('.test.txt','r');
4.读取内容
fread('文件资源','字节'); 读取资源,返回内容,每次读取指定字节数据
当函数读取资源超出资源范围时,返回空字符串
1 2 3 4 5
| 读取方式1: while( ($x=fread($handle,1)) !== '' ){ echo $x; }
|
1 2 3 4
| 读取方式2: echo fread($handle,11); echo fread($handle,filesize('./test.txt'));
|
5.写入内容
fwrite('文件资源','内容')
将内容写入目标文件,写入方式由 fopen() 的打开模式决定
代码实例:
1 2 3 4
| 1.写入: $handle=fopen('./text.txt','w'); fwrite($handle,'MVP'); #MVP
|
1 2 3 4
| 2.追加: $handle=fopen('.text.txt','a'); fwrite($handle,'ADD'); #MVPADD
|
1 2 3 4
| 3.增强:r+ $handle=fopen('./test.txt','r+'); fwrite($handle,'abc'); #abcADD(覆盖前面的)
|
1 2 3 4
| 4.增强:w+ $handle=fopen('./test.txt','w+'); fwrite($handle,'def'); #def(覆盖全部的)
|
1 2 3 4
| 5.增强:a+ $handle=fopen('./test.txt','a+'); fwrite($handle,'GG'); #defGG(覆盖全部的)
|
6.关闭资源
fclose($handle); 释放内存,节省空间
9.文件上传
1.文件上传限制:
表单限制 MAX_FILE_SIZE HTML页面自定义大小,一旦超过,error=2
可通过F12跳过限制(一般都是通过隐藏域MAX_FILE_SIZE修改赋值)
post协议限制 post_max_size 一旦超过8M,$_FILES直接为空
服务器限制 upload_max_filesize 一旦超过2M,error=1
2.文件上传相关函数
$_FILES 专门用于接收上传文件,返回结果为数组
$is_uploaded_file( 临时文件地址 ) 检测是否通过post发送,返回bool值
uniqid() 基于一微秒产生的唯一ID,适合低频率
file_exists( ) 文件是否存在,返回bool
move_uploaded_file( 临时文件,目标文件 ) 移动临时文件到存储目录
1 2 3 4 5 6 7 8 9 10
| array (size=1) 'icon' => array (size=5) icon => file表单的name名 name => 上传的文件名 type => 上传的文件类型 tmp_name => 临时文件 error => 错误号 0:没错 非0:有错 size => 上传的文件大小
|
上传文件初版:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| function upload() { #1.检测文件是否符合服务器大小限制($_FILES是否为空) $key=key($_FILES); if(is_null($key)){ #若超过8M,错误号2,post协议不通过,FILES数组为空 echo '文件太大,上传失败'; echo <meta http-equiv="refresh"content="3;url='.$_SERVER['HTTP_REFERER'].'">; die; #回到上一级 } #2.获取错误号,输出错误信息 $error=$_FILES[$key]['error']; #获取当前错误号 if($error!=0){ #若错误号不为0,即上传失败,输出原因 switch($error){ case1:echo '文件太大,上传失败';break; case2:echo '文件太大,上传失败';break; case3:echo '网络中断';break; case4:echo '未上传文件';break; case6:echo '服务器繁忙(服务器存储目录丢失)';break; case7:echo '服务器繁忙(权限不足)';break; } echo <meta http-equiv="refresh"content="3;url='.$_SERVER['HTTP_REFERER'].'">; die; } #3.检测是否是post上传过来的 $tmp=$_FILES[$key]['tmp_name']; #获取缓存目录 if(!is_uploaded_file($tmp)){ #是否通过post发送 echo '非法上传'; echo <meta http-equiv="refresh"content="3;url='.$_SERVER['HTTP_REFERER'].'">; die; } #4.检测文件类型是否符合要求 $type=strtok($_FILES[$key]['type'],'/'); #获取文件类型 $allowType=['image']; #准备允许的类型 if(!in_array($type,$allowType)){ echo '上传类型不符合要求'; echo <meta http-equiv="refresh"content="3;url='.$_SERVER['HTTP_REFERER'].'">; } #5.设计新的文件名(唯一)(格式:20190423xxxx.jpg) $suffix=strrchr($_FILES[$key]['name'],'.'); #4.1获取扩展名 $filename=date('Ymd').uniqid().$suffix; #产生唯一ID #6.设置存储目录 upload/年/月/日/ $dir='upload/'.date('/Y/m/d/'); if(!file_exists($dir)){ mkdir($dir,0777,true); } #7.移动临时文件到存储目录 if(move_upload_file($tmp,$dir.$filename)){ echo '上传成功'; }else{ echo '上传失败'; } }
|
上传文件完全版:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| /** * upload 单文件上传 * @param string $saveDir 存储目录 * @param array $allowType 允许类型 * @return string 错误信息 * @return array 新的文件名 */ function upload($saveDir='uploads/',$allowType=['image']) { #1.检测文件是否符合服务器大小限制($_FILES是否为空) $key=key($_FILES); if(is_null($key)){ #若超过8M,错误号2,post协议不通过,FILES数组为空 return '文件太大,上传失败'; #返回信息 } #2.获取错误号,输出错误信息 $error=$_FILES[$key]['error']; #获取当前错误号 if($error!=0){ #若错误号不为0,即上传失败,输出原因 switch($error){ case 1:return '文件太大,上传失败';break; case 2:return '文件太大,上传失败';break; case 3:return '网络中断';break; case 4:return '未上传文件';break; case 6:return '服务器繁忙(服务器存储目录丢失)';break; case 7:return '服务器繁忙(权限不足)';break; } } #3.检测是否是post上传过来的 $tmp=$_FILES[$key]['tmp_name']; #获取缓存目录 if(!is_uploaded_file($tmp)){ #是否通过post发送 return '非法上传'; } #4.检测文件类型是否符合要求 $type=strtok($_FILES[$key]['type'],'/'); #获取文件类型 if(!in_array($type,$allowType)){ return '上传类型不符合要求'; } #5.设计新的文件名(唯一)(格式:20190423xxxx.jpg) $suffix=strrchr($_FILES[$key]['name'],'.'); #4.1获取扩展名 $filename=date('Ymd').uniqid().$suffix; #产生唯一ID #6.设置存储目录 upload/年/月/日/ $dir=$saveDir.date('/Y/m/d/'); if(!file_exists($dir)){ mkdir($dir,0777,true); } #7.移动临时文件到存储目录 if(move_uploaded_file($tmp,$dir.$filename)){ return [$filename]; }else{ return '上传失败'; } }
$result=upload(); if(is_array($result)){ notice('上传成功','http://www.baidu.con'); }else{ notice($result); }
/** * notice 提示信息 * @param string $info 提示信息 * @param string $url 提示之后的跳转地址 * @param integer $time 几秒后进行跳转 */ function notice($info,$url=null,$time=3) { echo $info; if($is_null($url)){ $url=$_SERVER['HTTP_REFERER']; } echo "<meta http-equiv='refresh' content='{$time}; url={$url}'>"; die; }
|
10.文件下载
1.步骤
1.接收下载的文件名
1 2 3
| $name = $_GET['name']; $suffix=strchr($name,'');
|
2.凑完整的路径
1 2
| $path = './download/'.$name;
|
3.准备下载之后的名字
1 2 3
| $filename=str_shuffle(md5($name)).$suffix; header("content-disposition:attachment;filename={$filename}");
|
4.读取文件内容