PHP之路 PHP基础【第八篇】文件操作
一、概述
1.1 文件类型
文件在windows系统下分为3种不同:文件、目录、未知
在linux/unix系统下分为7种不同:block、char、dir、fifo、file、link和unknown七种类型
1.2 文件的常用函数
* filetype() --获取文件类型的函数 * is_dir( ) -- 判断给定文件名是否是一个目录 语法结构:bool is_dir(名称) 返回类型:如果文件名存在并且是一个目录则返回 true,否则返回 false。 is_executable( ) -- 判断给定文件名是否可执行 语法结构:bool is_executable(名称) 返回类型:如果文件存在且可执行则返回 true ,否则返回 false 。 * is_file( ) -- 判断给定文件名是否为一个正常的文件 语法结构:bool is_file(名称) 返回类型:如果文件存在且为正常的文件则返回 true 。 is_link( ) -- 判断给定文件名是否为一个符号连接 语法结构:bool is_link(名称) 返回类型:如果文件存在并且是一个符号连接则返回 true。 is_readable( ) -- 判断给定文件名是否可读 语法结构:bool is_readable(文件名称) 返回类型:如果文件存在并且可读则返回 true 。 * is_writable( ) -- 判断给定的文件名是否可写 语法结构:bool is_writable(文件名称) 返回类型:如果文件存在并且可写则返回 true 。 *file_exists( ) 检查文件或目录是否存在 *filesize() 取得文件大小(不能获取目录大小) is_readable() 判断文件是否可读 is_writable() 判断文件是否可写 *filectime() 获取文件的创建时间 filemtime() 获取文件的修改时间 fileatime() 获取文件的访问时间 stat() 获取文件大部分属性
二、目录的相关操作
2.1 路经的方式
windows系统:D:/a/b/c.php 或 D:\a\b\c.php
linux/unix系统: /a/b/c.php
为统一建议使用"/"作为目录之间的分割符
2.2 路径的相关函数
1. basename("url地址"[,去除部分]) -- 获取指定url的文件名
2. dirname("url地址") -- 获取地址的路径值
$url = "http://www.baidu.com/a/b/c.php"; echo $url."<br/>"; //http://www.baidu.com/a/b/c.php echo basename($url)."<br/>"; //c.php echo basename($url,".php")."<br/>"; //c (去掉".php") echo dirname($url)."<br/>"; //http://www.baidu.com/a/b
3. pathinfo
(文件路径[,需要的下标])--获取文件路径的详细信息,返回一个关联数组
结果:下标:dirname 路径名
basename 文件名
extension 后缀名
filename 文件名(去掉后缀的)
$url = "http://www.baidu.com/a/b/c.php"; *echo pathinfo($url,PATHINFO_DIRNAME); //http://www.baidu.com/a/b *echo pathinfo($url,PATHINFO_EXTENSION); //php 后缀名 *echo pathinfo($url,PATHINFO_BASENAME); //c.php 文件名 $a = pathinfo($url); $a结果: array(4) { ["dirname"]=> string(24) "http://www.baidu.com/a/b" ["basename"]=> string(5) "c.php" ["extension"]=> string(3) "php" ["filename"]=> string(1) "c"
4. realpath()--获取指定文件的绝对路径
示例: echo realpath("1.php"); //D:\AppServ\www\lamp45\09_file_dir\1.php
2.3 目录的遍历函数
*opendir("") -- 打开一个目录,返回此目录的资源句柄
*readdir(资源句柄) -- 从目中读取一个目录或文件,并指针向下移动一位。
*closedir(资源句柄)-- 关闭打开的目录
rewinddir(资源句柄) -- 倒回目录指针(移至首位)
<?php //使用目录遍历操作函数输出aa目录中的所有文件信息 echo "<h2>目录中文件遍历操作</h2>"; echo "<table width='700' border='1'>"; echo "<tr><th>文件名</th><th>类型</th><th>大小</th><th>创建时间</th></tr>"; //1. 打开目录 $path="./aa/"; $dd = opendir($path); //2. 遍历打开的目录 while($f = readdir($dd)){ //跳过两个特殊目录 if($f=="." || $f==".."){ continue; } //为当前文件添加目录: $file = rtrim($path,"/")."/".$f; echo "<tr>"; echo "<td>{$f}</td>"; echo "<td>".filetype($file)."</td>"; echo "<td>".filesize($file)."</td>"; echo "<td>".date("Y-m-d H:i:s",filectime($file))."</td>"; echo "</tr>"; } //3. 关闭目录 closedir($dd); echo "</table>";
2.4 统计空间的大小
echo "当前磁盘可用大小:".(disk_free_space("./")/1024/1024/1024)."G<br/>";
echo "当前磁盘共计大小:".(disk_total_space("./")/1024/1024/1024)."G<br/>";
2.5 目录的操作
*mkdir() -- 创建一个目录
*rmdir() -- 删除一个目录(只支持删除空目录)
*unlink() -- 删除一个文件
<?php //目录的创建和删除等操作 //mkdir("./bb/cc"); //创建cc目录 //rmdir("./bb/cc"); //删除cc目录 //rmdir("./bb"); //删除bb目录 //删除bb目录,要求bb目录中只有文件 $dir = "./bb"; //1.打开目录bb $dd = opendir($dir); //遍历目录中的每个文件 while(false!==($f=readdir($dd))){ //过滤掉特殊目录 if($f=="."||$f==".."){ continue; } //为每个文件添加目录 $file = rtrim($dir,"/")."/".$f; //删除该文件 unlink($file); } //关闭目录 closedir($dd); //执行目录删除 rmdir($dir);
2.6 复制文件
copy() --- 复制文件。不支持目录复制
三、文件基本操作
*1. fopen(文件名,打开模式) ---打开一个文件
模式:读(r、r+)、 清空写(w/w+), 追加写(a/a+)、 创建模式(x,x+) *打开模式: *r: 只读模式打开文件,文件指针执行首位。 r+: 可读可写模式打开文件,文件指针执行首位,若文件指针不是在最后,则是覆盖写。 *w: 以写方式打开文件,文件内容清空,若文件不存在,则尝试创建。 w+: 以写和读方式打开文件,文件内容清空,若文件不存在,则尝试创建。(也会覆盖写) *a: 以追加内容方式打开文件,指针移至最后,若文件不存在,则尝试创建。 a+: 以追加内容和可读方式打开文件,指针移至最后,若文件不存在,则尝试创建。 x: 以创建方式打开文件,可写。若文件已存在,则报错。 x+: 以创建方式打开文件,可写可读。若文件已存在,则报错。 附加模式: t: txt文本模式(字符流) b: byte字节模式(二进制)默认 (字节流) 如:fopen("a.txt","rb"); 文件的读写操作也叫流操作,其中流分为字符流(t)和字节流(b 二进制)
文件的读写操作也叫流操作,其中流分为字符流(t)和字节流(b 二进制)
*2. fread(打开的文件资源,读取的长度) -- 读取文件内容。
*3. fwrite(打开的文件资源,被写入的字串[,长度]) -- 向文件写入内容。
*4. fclose(打开的文件资源) -- 关闭文件
5. fgets() -- 从文件资源中读取一行
6. fgetc() -- 读取一个字符
<?php //文件操作: /* //以r+模式打开文件b.txt, $f = fopen("b.txt","r+"); echo fread($f,10); fwrite($f,"###"); //写入字串,若文件指针不在最后则会覆盖写。 fclose($f);//关闭文件 */ /* //请追加写模式打开文件b.txt,若b.txt文件不存在则会尝试创建 $f = fopen("b.txt","a"); fwrite($f,"zhangsan"); //写入字串 fclose($f);//关闭文件 */ /* //请清空写模式打开文件b.txt,若b.txt文件不存在则会尝试创建 $f = fopen("b.txt","w"); fwrite($f,"zhangsan"); //写入字串 fclose($f);//关闭文件 */ /* //以只读方式打开文件a.txt. $f = fopen("a.txt","r"); //读取文件a.txt的内容。 echo fread($f,"4"); //hell echo fread($f,"4"); //owor //关闭文件 fclose($f); */
<?php //打开c.txt,使用一行一行的读取信息 $f = fopen("c.txt","r"); while($row = fgets($f)){ echo $row."<br/>"; } fclose($f); echo "<hr/>"; //不用打开文件就可以读取的函数 // 一次性读取a.txt文件全部内容并返回 echo file_get_contents("a.txt")."<br/>"; // 一次性读取c.txt文件全部内容,并将每行作为一个数组单元返回 $a = file("c.txt"); echo "<pre>"; print_r($a); // 一次性读取a.txt文件全部内容并直接输出 readfile("a.txt");
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>下载网页</title> </head> <body> <center> <h3>网页下载神器</h3> <form action="8.php" method="post"> <table width="320" border="0"> <tr> <td>URL地址:</td> <td><input type="text" size="30" name="url"/></td> </tr> <tr> <td>保存文件:</td> <td><input type="text" name="filename"/></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" value="开始"/> <input type="reset" value="重置"/> </td> </tr> </table> </form> <?php //处理要下载的文件: //判断是否需要下载处理 if(!empty($_POST['url'])){ //获取信息 $url = $_POST['url']; $filename = $_POST["filename"]; //打开文件 $uf = fopen($url,"r"); $df = fopen("./down/".$filename,"w"); //开始读写 while($b = fread($uf,1024)){ fwrite($df,$b); } //都关闭 fclose($uf); fclose($df); echo "ok"; } ?> </center> </body> </html>
<?php //自定义copy()函数,文件复制函数 function mycopy($file1,$file2){ //分别打开这两个文件 $f1 = fopen($file1,"rb"); $f2 = fopen($file2,"wb"); //读写 while($b = fread($f1,1024)){ fwrite($f2,$b); } //关闭文件 fclose($f1); fclose($f2); } //测试 mycopy("a.txt","c.txt"); //mycopy("11.jpg","12.jpg");
<?php //自定义目录复制函数 function copyDir($srcdir,$dstdir){ //判断目标是否存在 if(!file_exists($dstdir)){ mkdir($dstdir); } //1.打开源目录 $dd = opendir($srcdir); //遍历目录中的每个文件 while(false!==($f=readdir($dd))){ //过滤掉特殊目录 if($f=="."||$f==".."){ continue; } //为每个文件添加目录 $srcfile = rtrim($srcdir,"/")."/".$f; $dstfile = rtrim($dstdir,"/")."/".$f; //判断是否是文件 if(is_file($srcfile)){ //复制该文件 copy($srcfile,$dstfile); } if(is_dir($srcfile)){ copyDir($srcfile,$dstfile);//执行递归目录删除 } } //关闭目录 closedir($dd); } //测试 copyDir("./bb","./ee");
<?php //自定义目录删除函数 function dirDel($dir){ //1.打开目录bb $dd = opendir($dir); //遍历目录中的每个文件 while(false!==($f=readdir($dd))){ //过滤掉特殊目录 if($f=="."||$f==".."){ continue; } //为每个文件添加目录 $file = rtrim($dir,"/")."/".$f; //判断是否是文件 if(is_file($file)){ //删除该文件 unlink($file); } if(is_dir($file)){ dirDel($file);//执行递归目录删除 } } //关闭目录 closedir($dd); //执行目录删除 rmdir($dir); } //测试 //dirDel("./cc/");
<?php //定义一个统计指定目录大小的函数 function dirSize($dir){ $total=0; //用于存放累加值的变量 //打开目录 $dd = opendir($dir); //遍历目录中的文件 while(false!==($f=readdir($dd))){ //跳出特殊目录 if($f=="." || $f==".."){ continue; } //为遍历的文件添加目录 $file = rtrim($dir,"/")."/".$f; //判断是否是文件 if(is_file($file)){ //获取当前文件大小 $total+=filesize($file); } //判断是否是目录 if(is_dir($file)){ $total+=dirSize($file); //此处为递归调用。 } } //关闭目录 closedir($dd); //返回结果 return $total; } //测试 echo dirSize("./aa");
------------不用打开文件可直接操作文件的函数-----------------------
*7. file() 将文件读出(内容是数组格式),并返回
*8. readfile() 将文件内容读出,并输出
9. file_get_contents() 读取文件内容
10.file_put_contents() 将指定内容写入文件
---------------------文件指针的操作--------------------------------
11. ftell() --返回文件指针的位置
12. fseek() --设置文件指针的位置
示例:
fseek($f,-2,SEEK_CUR); //从当前指针位置开始,向前移动2位
fseek($f,2,SEEK_SET); //从文件指针开始位置,向后移动2位
fseek($f,-5,SEEK_END); //从文件指针的最后位置开始,向前移动5位
13. rewind() --将文件指针移至首位
<?php //文件指针操作 helloworld!; $f = fopen("a.txt","r"); echo fread($f,4)."<br/>"; echo "当前指针的位置:".ftell($f)."<br/>"; rewind($f); //将文件指针移至首位 echo fread($f,4)."<br/>"; //fseek($f,5,SEEK_SET); //从头开始移动 //fseek($f,1,SEEK_CUR); //从当前位置移动 fseek($f,-6,SEEK_END); //从最后位置移动 echo fread($f,3); //wor
------------文件锁(了解)---------------------------
14. bool flock ( int $handle , int $operation [, int &$wouldblock ] )
轻便的咨询文件锁定
operation参数:
要取得共享锁定(读取的程序),将 operation 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)。
要取得独占锁定(写入的程序),将 operation 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)。
要释放锁定(无论共享或独占),将 operation 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)。
如果不希望 flock() 在锁定时堵塞,则给 operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)。
<?php $fp = fopen("/tmp/lock.txt", "w+"); if(flock($fp, LOCK_EX)) { // 进行排它型锁定 fwrite($fp, "Write something here\n"); flock($fp, LOCK_UN); // 释放锁定 } else { echo "Couldn't lock the file !"; } fclose($fp); ?>
----------------------------------------------
*15. rename() --修改文件名
16. ftruncate() — 将文件截断到给定的长度
四、文件上传与下载
文件上传
单文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Upload A File</title> </head> <body> <form action="upload.php" method="post" enctype="multipart/form-data"> <input type="hidden" name="MAX_FILE_SIZE" value="1024000" /> <input type="file" name="imooc_pic" /> <input type="submit" value="上传" /> </form> </body> </html>
<?php /** * Created by PhpStorm. * User: JasonLee * Date: 2018/11/11 * Time: 14:06 */ // 接收$_FILES数组 $key = 'imooc_pic'; $mimeWhiteList = ['image/jpeg', 'image/png', 'image/gif']; $extWhiteList = ['jpeg', 'jpg', 'png', 'gif']; $allowSize = 2*1024*1024; $destDir = './uploads'; $name = $_FILES[$key]['name']; // 源文件名称 $type = $_FILES[$key]['type']; // MIME 类型 $tmpName = $_FILES[$key]['tmp_name']; // 临时文件名称 $error = $_FILES[$key]['error']; // 错误信息 $size = $_FILES[$key]['size']; // 文件大小 字节 // 处理错误 // 0 - 无错误 if ($error > UPLOAD_ERR_OK) { switch($error) { // 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小 case UPLOAD_ERR_INI_SIZE: exit('文件大小超出了php.ini当中的upload_max_filesize的大小'); // 2 - 超出表单当中的MAX_FILE_SIZE的大小 case UPLOAD_ERR_FORM_SIZE: exit('超出表单当中的MAX_FILE_SIZE的大小'); // 3 - 部分文件被上传 case UPLOAD_ERR_PARTIAL: exit('部分文件被上传'); // 4 - 没有文件被上传 case UPLOAD_ERR_NO_FILE: exit('没有文件被上传'); // 6 - 临时目录不存在 case UPLOAD_ERR_NO_TMP_DIR: exit('临时目录不存在'); // 7 - 磁盘写入失败 case UPLOAD_ERR_CANT_WRITE: exit('磁盘写入失败'); // 8 - 文件上传被PHP扩展阻止 case UPLOAD_ERR_EXTENSION: exit('文件上传被PHP扩展阻止'); default: exit('未知错误'); } } // 限制文件的MIME if (!in_array($type, $mimeWhiteList)) { exit('文件类型' . $type . '不被允许!'); } // 限制文件的扩展名 $ext = pathinfo($name, PATHINFO_EXTENSION); if (!in_array($ext, $extWhiteList)) { exit('文件扩展名' . $ext . '不被允许!'); } // 限制文件大小 if ($size > $allowSize) { exit('文件大小 ' . $size . ' 超出限定大小 ' . $allowSize . ' !'); } // 生成新的随机文件名称 // md5(rand()); $fileName = uniqid() . '.' . $ext; // 移动临时文件到指定目录当中并重新命名文件名 if (!file_exists($destDir)) { mkdir($destDir, 0777, true); } if (is_uploaded_file($tmpName) && move_uploaded_file($tmpName, $destDir . '/' . $fileName)) { echo "恭喜,文件上传成功"; } else { echo "很抱歉,文件上传失败"; }
多文件
语法一
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Upload Multiple Files</title> </head> <body> <form action="multiple_upload.php" method="post" enctype="multipart/form-data"> <input type="hidden" name="MAX_FILE_SIZE" value="1024000" /> <input type="file" name="imooc_pic1" /> <input type="file" name="imooc_pic2" /> <input type="file" name="imooc_pic3" /> <input type="submit" value="上传" /> </form> </body> </html>
<?php /** * Created by PhpStorm. * User: JasonLee * Date: 2018/11/11 * Time: 14:54 */ $errors = []; $mimeWhiteList = ['image/jpeg', 'image/png', 'image/gif']; $extWhiteList = ['jpeg', 'jpg', 'png', 'gif']; $allowSize = 2*1024*1024; $destDir = './uploads'; foreach($_FILES as $key => $val) { // name type tmp_name error size // 接收$_FILES $name = $_FILES[$key]['name']; // 源文件名称 $type = $_FILES[$key]['type']; // MIME 类型 $tmpName = $_FILES[$key]['tmp_name']; // 临时文件名称 $error = $_FILES[$key]['error']; // 错误信息 $size = $_FILES[$key]['size']; // 文件大小 字节 // 处理错误 // 0 - 无错误 if ($error > UPLOAD_ERR_OK) { switch($error) { // 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小 case UPLOAD_ERR_INI_SIZE: $errors[$key] = '文件大小超出了php.ini当中的upload_max_filesize的大小'; continue 2; // 2 - 超出表单当中的MAX_FILE_SIZE的大小 case UPLOAD_ERR_FORM_SIZE: $errors[$key] = '超出表单当中的MAX_FILE_SIZE的大小'; continue 2; // 3 - 部分文件被上传 case UPLOAD_ERR_PARTIAL: $errors[$key] = '部分文件被上传'; continue 2; // 4 - 没有文件被上传 case UPLOAD_ERR_NO_FILE: $errors[$key] = '没有文件被上传'; continue 2; // 6 - 临时目录不存在 case UPLOAD_ERR_NO_TMP_DIR: $errors[$key] = '临时目录不存在'; continue 2; // 7 - 磁盘写入失败 case UPLOAD_ERR_CANT_WRITE: $errors[$key] = '磁盘写入失败'; continue 2; // 8 - 文件上传被PHP扩展阻止 case UPLOAD_ERR_EXTENSION: $errors[$key] = '文件上传被PHP扩展阻止'; continue 2; default: $errors[$key] = '未知错误'; continue 2; } } // 限制MIME if (!in_array($type, $mimeWhiteList)) { $errors[$key] = '文件类型' . $type . '不被允许!'; continue; } // 限制扩展名 $ext = pathinfo($name, PATHINFO_EXTENSION); if (!in_array($ext, $extWhiteList)) { $errors[$key] = '文件扩展名' . $ext . '不被允许!'; continue; } // 限制大小 if ($size > $allowSize) { $errors[$key] = '文件大小 ' . $size . ' 超出限定大小 ' . $allowSize . ' !'; continue; } // 生成随机文件名称 $fileName = uniqid() . '.' . $ext; // 移动文件 if (!file_exists($destDir)) { mkdir($destDir, 0777, true); } if (!is_uploaded_file($tmpName) || !move_uploaded_file($tmpName, $destDir . '/' . $fileName)) { $errors[$key] = "很抱歉,文件上传失败"; continue; } } if (count($errors) > 0) { var_dump($errors); } else { echo "文件全部上传成功"; }
语法二
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Upload Multiple Files</title> </head> <body> <form action="multiple_upload2.php" method="post" enctype="multipart/form-data"> <input type="hidden" name="MAX_FILE_SIZE" value="6024000" /> <input type="file" name="imooc_pic[]" /> <input type="file" name="imooc_pic[]" /> <input type="file" name="imooc_pic[]" /> <input type="submit" value="上传" /> </form> </body> </html>
<?php /** * Created by PhpStorm. * User: JasonLee * Date: 2018/11/11 * Time: 15:12 */ $key = 'imooc_pic'; $mimeWhiteList = ['image/jpeg', 'image/png', 'image/gif']; $extWhiteList = ['jpeg', 'jpg', 'png', 'gif']; $allowSize = 2*1024*1024; $destDir = './uploads'; // 接收和处理$_FILES if (!empty($_FILES[$key])) { $files = []; foreach($_FILES[$key]['name'] as $k => $v) { $files[$k]['name'] = $v; $files[$k]['type'] = $_FILES[$key]['type'][$k]; $files[$k]['tmp_name'] = $_FILES[$key]['tmp_name'][$k]; $files[$k]['error'] = $_FILES[$key]['error'][$k]; $files[$k]['size'] = $_FILES[$key]['size'][$k]; } } $errors = []; foreach($files as $file) { // name type error size $name = $file['name']; // 源文件名称 $type = $file['type']; // MIME 类型 $tmpName = $file['tmp_name']; // 临时文件名称 $error = $file['error']; // 错误信息 $size = $file['size']; // 文件大小 字节 // 处理错误 // 0 - 无错误 if ($error > UPLOAD_ERR_OK) { switch($error) { // 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小 case UPLOAD_ERR_INI_SIZE: $errors[$key] = $name . '文件大小超出了php.ini当中的upload_max_filesize的大小'; continue 2; // 2 - 超出表单当中的MAX_FILE_SIZE的大小 case UPLOAD_ERR_FORM_SIZE: $errors[$key] = $name . '超出表单当中的MAX_FILE_SIZE的大小'; continue 2; // 3 - 部分文件被上传 case UPLOAD_ERR_PARTIAL: $errors[$key] = $name . '部分文件被上传'; continue 2; // 4 - 没有文件被上传 case UPLOAD_ERR_NO_FILE: $errors[$key] = $name . '没有文件被上传'; continue 2; // 6 - 临时目录不存在 case UPLOAD_ERR_NO_TMP_DIR: $errors[$key] = $name . '临时目录不存在'; continue 2; // 7 - 磁盘写入失败 case UPLOAD_ERR_CANT_WRITE: $errors[$key] = $name . '磁盘写入失败'; continue 2; // 8 - 文件上传被PHP扩展阻止 case UPLOAD_ERR_EXTENSION: $errors[$key] = $name . '文件上传被PHP扩展阻止'; continue 2; default: $errors[$key] = $name . '未知错误'; continue 2; } } // 限制MIME类型 if (!in_array($type, $mimeWhiteList)) { $errors[$key] = '文件类型' . $type . '不被允许!'; continue; } // 限制扩展名 $ext = pathinfo($name, PATHINFO_EXTENSION); if (!in_array($ext, $extWhiteList)) { $errors[$key] = '文件扩展名' . $ext . '不被允许!'; continue; } // 限制文件大小 if ($size > $allowSize) { $errors[$key] = '文件大小 ' . $size . ' 超出限定大小 ' . $allowSize . ' !'; continue; } // 生成随机文件名称 $fileName = uniqid() . '.' . $ext; // 移动文件 if (!file_exists($destDir)) { mkdir($destDir, 0777, true); } if (!is_uploaded_file($tmpName) || !move_uploaded_file($tmpName, $destDir . '/' . $fileName)) { $errors[$key] = "很抱歉,文件上传失败"; continue; } } if (count($errors) > 0) { var_dump($errors); } else { echo "文件全部上传成功"; }