1、文件检测
1.1、存在性检测:bool file_exists(string $filename);
1.2、类型检测: string filetype(string $filename),可能的返回值有 fifo,char,dir,block,link,file 和 unknown,出错返回false
bool is_file(string $filename);判断是否是文件
bool is_dir(string $filename);判断是否是目录
1.3、文件大小检测:filesize(string $filename);文件大小或目录大小
2、打开和关闭文件
2.1、resource fopen(string filename,string mode):打开文件或URL,mode可设置文件的打开模式
打开模式:
"r" 只读方式打开,将文件指针指向文件头
"r+" 读写方式打开,将文件指针指向文件头
"w" 写入方式打开,将文件指针指向文件头并将文件大小截为零,文件不存在则新建文件
"w+" 读写方式打开,将文件指针指向文件头并将文件大小截为零,文件不存在则新建文件
"a" 写入方式打开,将文件指针指向文件结尾,如果文件不存在则创建文件
"a+" 读写方式打开,将文件指针指向文件结尾,如果文件不存在则创建文件
返回值:函数执行成功返回一个文件句柄,否则返回 FALSE。
fopen()函数也用于创建文件:如果用 fopen() 打开并不存在的文件,则会创建文件 例:创建名为 "testfile.txt" 的新文件:$myfile = fopen("testfile.txt", "w");
touch函数也可以创建一个文件
2.2、bool fclose(resource $handle):关闭一个已打开的文件
3、文件指针操作
3.1、bool rewind(resource $handle);将指针设为文件流的开头
3.2、int fseek(resource $handle, int offset);;将指针在文件中定位,成功则返回 0;否则返回 -1
3.3、ftell(resource $handle);返回文件指针的读/写位置
4、读取文件内容
4.1、读取相关检测函数
is_readable(string $filename);判断给定文件名是否可读
feof(resource $handle);检查是否已到达文件末尾 "end-of-file" (EOF) 如果文件指针到了 EOF 或者出错时则返回 TRUE,否则返回一个错误(包括 socket 超时),其它情况则返回 FALSE。
4.2、读取fopen打开的文件资源
fread()从文件读取最多length个字节。length参数常搭配filesize()函数使用
string fread(resource $handle,int $length)
应用:读取图片内容并输出
header('content-type:image/jpeg'); $file='test.jpg'; $fr=fopen($file,'r') or die("Unable to open file!"); echo fread($fr,filesize($file)); fclose($fr);
fgets()从文件资源中读取一行,调用此函数后,文件指针会移动到下一行。
string fgets(resource $handle[, int $length ])
拓展:fgetss函数从文件指针中读取一行并过滤掉 HTML 标记
fgetc() 从文件资源中读取一个字符,调用此函数后,文件指针会移动到下一个字符。
string fgetc(resource $handle)
应用:逐字符读取文件,直到 end-of-file:
$myfile = fopen("test.txt", "r") or die("Unable to open file!"); while(!feof($myfile)) { echo fgetc($myfile); } fclose($myfile);
4.3、不需要资源,直接读取
readfile() 读取文件并写入到输出缓冲,不用echo,读取后直接输出
int readfile(string $filename[, bool $use_include_path = false[,resource $context ]])
file()将文件的每一行作为一个元素存入数组中返回
array file(string $filename)
$f_arr = file('test.txt'); foreach($f_arr as $cont){ echo $cont." "; }
file_get_contents() 将整个文件读入一个字符串,此函数性能比fread函数性能好
string file_get_contents(string $filename[,bool $use_include_path=false[,resource $context[,int $offset = -1[,int $maxlen ]]]])
应用:网站数据采集器
$url='http://www.baidu.com'; $str=file_get_contents($url); echo $str;
5、写入文件
5.1、fwrite()将字符串写入指定文件,返回写入的字符数,出现错误时则返回 FALSE
int fwrite(resource $handle,string $string[,int $length ])
5.2、file_put_contents()
int file_put_contents(string $filename, mixed $data[,int $flags=0[,resource $context]]) file_put_contents($file,'abc'); //覆盖写入 file_put_contents($file,'abc',FILE_APPEND);//追加写入 等同于依次调用 fopen(),fwrite()以及fclose()
应用:页面静态化
$url='http://www.baidu.com'; $str=file_get_contents($url); file_put_contents('baidu.html',$str);
6、重命名、复制、删除、移动
bool rename(string $oldname,string $newname[,resource $context]) //重命名 bool copy(string $source,string $dest[,resource $context]) //复制 bool unlink(string $filename[,resource $context]) //删除 $sfile='1.jpg'; $dfile='img/'.$sfile; copy($sfile,$dfile);sleep(3); unlink($sfile);//移动(先复制,再删除)
7、文件上传与下载
7.1、常见数据格式
图片文件 image/gif、image/jpg、image/jpeg、image/png
纯文件和html text/plain、text/html
二进制文件 application/octet-stream
音频格式 audio/mpeg
视频格式 video/avi、video/x-ms-wmv
7.2、HTML部分
7.1.1、上传文件一般使用POST方法提交
7.1.2、上传文件必须设置enctype="multipart/form-data"
<form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="upFile"> <input type="submit" value="上传"> </form>
7.3、PHP部分
7.3.1、上传的文件在PHP中可以通过$_FILES获取,超全局数组$_FILES存储的相关数据:
$_FILES['myfile']['name'] //文件名 $_FILES['myfile']['type'] //文件类型 $_FILES['myfile']['size'] //文件大小 $_FILES['myfile']['tmp_name'] //文件保存在临时目录中的路径 $_FILES['myfile']['error'] //错误级别
错误级别:
0 表示没有发生任何错误
1表示上传文件的大小超出了约定值,约定值是upload的值,但不能超过post的值
2表示上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值
3表示文件只有部分被上传
4表示没有上传任何文件
7.3.2、PHP中文件默认会上传到一个临时目录, 接收完毕之后会自动删除
7.3.3、PHP上传文件四部曲
a.获取上传文件对应的信息
b.获取上传文件的名称
c.获取上传文件保存的临时路径
d.移动文件
$fileInfo = $_FILES["upFile"]; $fileName = $fileInfo["name"]; $filePath = $fileInfo["tmp_name"]; move_uploaded_file($filePath, "./source/".$fileName);
7.4、限制上传
7.3.1、php文件上传相关配置(pho.ini)
file_uploads = On ; 是否允许上传文件 On/Off 默认是On
upload_max_filesize = 2048M ; 上传文件的最大限制
post_max_size = 2048M ; 通过Post提交的最多数据
max_execution_time = 30000 ; 脚本最长的执行时间 单位为秒
max_input_time = 3000 ; 接收提交的数据的时间限制 单位为秒
memory_limit = 2048M ; 最大的内存消耗
7.3.2、限制大小
客户端限制:
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
服务端限制:
$filesize=$_FILES['files']['size'];
if($filesize>1000000){
echo "对不起,您上传的文件超过规定的大小!!";
echo "<meta http-equiv="Refresh" content="3;url=index.php">将在3秒钟后返回前页...";
}
7.3.3、限制类型
获取文件后缀
$farr=explode('.',$_FILES['upFile']['name']);
$fext=array_pop($farr);
限制文件上传类型
$allows=array('jpg','png','gif'); if(in_array($fext,$allows)){ ··· }else{ echo "<script>alert('文件类型不允许,只允许上传png|jpg|gif!')</script>"; }
7.5、上传文件管理
创建上传日期目录
$year=date('Y'); $month=date('m'); $day=date('d'); $datedir=$uploaddir.'/'.$year.'-'.$month.'-'.$day; if(!file_exists($datedir)){ mkdir($datedir); }
获取文件后缀
$farr=explode('.',$_FILES['img']['name']); $fext=array_pop($farr);
文件名中加入时间戳和随机数,预防文件同名和猜测攻击
$frand=time().mt_rand();
最终上传路径和文件名
$dfile=$datedir.'/'.$frand.'.'.$fext;
//文件上传函数封装 /* *@param1 array $file,要上传的文件信息,包含5个元素 *@param2 string $path,存储位置 *@param3 string &error, 错误信息 *@param4 array $type = array(),MIME类型限定 *@param5 int $size = 2000000, 默认限制最大2M *@return mixed, 成功返回文件名,失败返回false */ function fileupload($file,$path,&$error,$type = array(),$size = 2000000){ if(!isset($file['error'])){ $error = '文件无效'; return false; } //有效路径判定 if(!is_dir($path)){ $error = '存储路径无效'; return false; } //文件上传错误类型判定 switch($file['error']){ case 1: case 2: $error = '文件超过服务器允许大小'; return false; case 3: $error = '文件没有上传完整'; return false; case 4: $error = '用户没有选择要上传的文件'; return false; case 6: case 7: $error = '服务器出错'; return false; } //判断类型 if(!empty($type) && !in_array($file['type'],$type)){ $error = '文件类型不符合'; return false; } //大小限制 if($file['size'] > $size){ $error = '文件大小超出允许的范围,允许最大大小为:'.string($size/1000000).'M'; return false; } //转存文件 $newfilname = getNewName($file['name']); if(@move_uploaded_file($file['tmp_name'],$path.'/'.$newfilname)){ return $newfilname; } else { $error = '文件上传失败'; return false; } } function getNewName($filename,$rand = 4){ $newname = date('YmdHis'); $arr = array_merge(range('a','z'),range('A','Z')); shuffle($arr); for($i = 0; $i < $rand; $i++){ $newname .= $arr[$i]; } return $newname.strstr($filename,'.'); } $file = $_FILES['file']; $res = fileupload($file,'upload/',$error); if($res){ echo '文件上传成功'; }else{ echo $error; }
7.6、多文件上传 使用数组格式的表单元素,例:
<form action="" method="post" enctype="multipart/form-data">
<input name="file[]" type="file"> <input name="file[]" type="file"> <input name="file[]" type="file">
<input type="submit" value="上传" /> </form>
<?php if(!empty($_FILES['u_file']['name'])){ $file_name = $_FILES['file']['name']; $file_tmp_name = $_FILES['file']['tmp_name']; for($i = 0; $i < count($file_name); $i++){ if($file_name[$i] != ''){
move_uploaded_file($file_tmp_name[$i],$i.$file_name[$i]); echo '文件'.$file_name[$i].'上传成功。更名为'.$i.$file_name[$i].'<br>';
}
}
} ?>
<?php
echo '<pre>';
var_dump($_FILES);
$files = $_FILES['file']; for($i = 0, $len = count($files['name']); $i < $len; $i++){ $file = array( 'name' =>$files['name'][$i], 'type' =>$files['type'][$i], 'tmp_name' =>$files['tmp_name'][$i], 'error' =>$files['error'][$i], 'size' =>$files['size'][$i] ); $res = fileupload($file,'upload/',$error); if($res){ echo '文件上传成功'; }else{ echo $error; } }
7.7、文件下载
$file=$_GET['file']; $downfile='img/'.$file; $filesize=filesize($downfile); header('content-type:application/octet-stream'); header("content-disposition:attachment;filename={$file}"); header("content-length:{$filesize}"); readfile($downfile);
8、目录操作
8.1、mkdir()创建目录
bool mkdir(string $pathname[,int $mode=0777[,bool $recursive=false[,resource $context]]])
创建已经存在的目录时会报错,容错写法:
file_exists($pathname) or mkdir($pathname); //或@mkdir($pathname);
8.2、遍历目录
opendir()打开目录句柄
resource opendir(string $path [,resource $context ]);
readdir()返回目录中下一个文件的文件名。文件名以在文件系统中的排序返回,失败时返回 FALSE
string readdir([resource $dir_handle]);
closedir()关闭目录句柄
closedir(resource $dir_handle);
使用资源方式遍历目录
$res = opendir('E:/webdev/www'); $file = ''; while($file = readdir($res)){ echo $file."<br>"; } closedir($res);
补充:rewinddir(resource $dir_handle):将opendir打开的资源指针重新回到第一个
使用非资源方式遍历目录:
scandir() 返回指定路径中的文件和目录数组,,失败返回false
//array scandir(string $directory[,int $sorting_order[,resource $context]])
$arr=scandir($dir); foreach($arr as $key=>$val){ if($key>1){ echo $val.'<br>'; } }
递归深入遍历目录:
function myscandir($dir,$deep=0){ $files = scandir($dir); foreach($files as $file){ if($file == '.' || $file == '..') continue; echo str_repeat(' ',$deep*4),$file.'<br>'; $tmp_dir = $dir.'/'.$file; if(is_dir($tmp_dir)){ $func_name = __FUNCTION__; $func_name($tmp_dir,$deep+1); } } }
8.3、删除空目录rmdir(string $pathname);
容错写法:@rmdir($dir);
8.4、删除非空目录
操作步骤:遍历、递归
function delDir($dir){ $files=scandir($dir); foreach($files as $key=>$val){ if($key>1){ $file=$dir.'/'.$val; if(is_dir($file)) delDir($file); else unlink($file); } } rmdir($dir); }
延伸:清空目录及所有子目录文件
function clearDir($dir){ $files=scandir($dir); foreach($files as $key=>$val){ if($key>1){ $file=$dir.'/'.$val; if(is_dir($file)){ clearDir($file); }else{ unlink($file); } } } }
8.6、移动完整目录=>先执行8.5->后执行8.4
8.7、取得当前工作目录:string getcwd ( void )
8.8、改变当前目录:bool chdir(string $directory)
8.9、重命名:同文件重命名,使用rename函数
9、其他函数
pathinfo($str) 返回关于文件路径的信息数组
basename($str) 返回路径中的文件名部分
dirname($str) 返回路径中的目录名称部分
disk_free_space($str)返回目录的可用空间
disk_total_space() 返回一个目录的磁盘总容量