1、basename ,dirname ,pathinfo和realpath
basename(path) 返回路径中的文件名部份,包含扩展名,path表示路径;
dirname(path) 返回路径中的目录部份,path表示路径;
pathinfo(path,params) 返回文件路径信息,path表示路径,params表示配置信息 (params的配置有PATHINFO_DIRNAME-目录部份,PATHINFO_BASENAME-文件名部份含扩展名,PATHINFO_EXTENSION-扩展名部份和PATHINFO_FILENAME-文件名称不含扩展名);
realpath(path) 返回规范化的绝对路径,path表示路径
<?php header('Content-type:text/html;charset=utf-8'); $path = 'C:wnmp ginxwww est.info.php'; echo basename($path); //输出 test.info.php; echo dirname($path); //输出 C:wnmp ginxwww echo '<pre>'; print_r(pathinfo($path)); echo '</pre>'; //输出 //Array //( // [dirname] => C:wnmp ginxwww // [basename] => test . info . php // [extension] => php // [filename] => test . info //) var_dump(realpath('../../../../www/index.php')); //输出 string(16) "C:wwwindex.php" 这个返回的是实际文件所在的地址 ?>
2、filesize,filetype,fileatime,filectime,filemtime,touch
filesize(path) 返回的是文件的大小,如果出错,那么返回FALSE,path表示文件的路径
filetype(path) 返回的是文件的类型可能的值有 fifo,char,dir,block,link,file 和 unknown,如果出错,那么返回的值为FALSE。path表示文件的路径
filectime(path)返回的是文件的创建时间
filemtime(path)返回的是文件的更改时间
fileatime(path)返回的是文件的访问时间(注意Php的访问是不会更改fileatime的时间)
touch(path, int(time))触碰指定文件,改变文件的fileatime,也可以指定改变以的时间
<?php header('Content-type:text/html;charset=utf-8'); $path = 'C:wnmp ginxwww est.php'; var_dump(filetype($path)); //输出 string(4) "file" var_dump(filesize($path)); //输出 int(281) ?>
<?php header('content-type:text/html;charset=utf8'); ini_set('display_errors', true); ini_set('timezone', 'PRC'); $path =realpath(__DIR__)."/test.txt"; if(is_file($path)) { touch($path); echo date('Y-m-d H:i:s', fileatime($path)).'<br>'; echo date('Y-m-d H:i:s', filemtime($path)).'<br>'; echo date('Y-m-d H:i:s', filectime($path)); } //输出如下的时间 //2019-05-14 13:03:20 //2019-05-14 13:03:20 //2019-03-29 23:30:30 ?>
3、copy,rename
copy(source,dest) 表示拷贝文件,source表示源文件,dest表示目标地,注意dest要详细到文件的名称,相当于在复制的时候要把复制后的名称给定好,如果文件路径不存在,那么返回FALSE还则返回TRUE
rename(oldname,newname) 表示重命名文件,但同时也可以移动文件,oldname表示原来旧的文件名称,newname表示新的文件名称,如果成功返回TRUE,如果文件路径不存在或者失败则返回FALSE,
<?php header('Content-type:text/html;charset=utf8'); $path = 'D:filetestAcopy.txt'; if (file_exists($path)) { var_dump(copy($path, 'D:filetestBcopyB.txt')); //输出 bool(true) 同时在目标的路径下出现copyB.txt var_dump(rename($path, 'D:filetestBcopyA.txt')); //输出 bool(true) 同时会把原目录下的文件移动到目标文件夹下 } ?>
4、file_exists,is_dir,is_file,is_link
file_exists(path) 表示检查文件路径是否存在,path表示路径(可以检查文件或目录)
is_dir(filename) 表示判断给定的文件名是否是一个路径,filename表示是一个文件名
is_file(filename) 表示判断给定的文件名是否是一个文件,filename表示是一个文件名
is_link(filename) 表示判断给定的文件名是否是一个符号连接,filename表示一个文件名
<?php header('Content-type:text/html;charset=utf-8'); $path = 'D:/filetest/test.txt'; $filename='D:/filetest'; var_dump(file_exists($path)); //输出 bool(true) var_dump(is_dir($filename)); //输出 bool(true) var_dump(is_dir($path)); //输出 bool(false) var_dump(is_link($path)); //输出 bool(false) var_dump(is_file($path)); //输出 bool(true) ?>
5、disk_free_space 和 disk_total_space
disk_free_space(dir) 表示返回一个磁盘的剩余的空间容量 dir表示磁盘
disk_total_space(dir) 表示返回一个磁盘的总的空间容量 dir表示磁盘
<?php header('Content-type:text/html;charset=utf-8'); $path = 'D:/filetest/test.txt'; $filename='D:/filetest'; var_dump(disk_free_space('d:')/1024/1024/1024); //输出 float(30.699325561523) var_dump(disk_total_space('d:')/1024/1024/1024); //输出 float(117.7949180603) ?>
6、mkdir,rmdir
mkdir(path,mode,recursive) 表示新建文件夹,path表示文件的路径及名称,mode表示模式默认情况下是0777表示最大的访问量,recursive表示是否创建多级子目录
rmdir(path) 表示删除文件夹,path表示文件的路径及名称,如果文件夹内有文件,那么删除失败
<?php header('Content-type:text/html;charset=utf-8'); $dir = 'D:/filetest'; if (!is_dir($dir . '/yftest')) { mkdir($dir . '/yftest', 0777); //在指定目录下新建一个新的文件夹yftest; } if (is_dir($dir . '/yftest')) { rmdir($dir . '/yftest'); //删除了指定文件夹yftest } ?>
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); ini_set('date.timezone', 'PRC'); class CreateFile { private $path; private $content; private $num; private function isDirExists(){ return file_exists($this->path); } private function createFile() { $name = date('Ymd', time()); $str = str_repeat($this->content." ", $this->num); return file_put_contents($this->path."/{$name}.txt", $str, FILE_APPEND); } public function init() { !$this->isDirExists()?mkdir($this->path, 0777, true): null; return $this->createFile(); } public function __construct(string $addr, string $content, int $num){ $this->path = $addr; $this->content = $content; $this->num = $num; } } $file = new CreateFile('d:/aaa/bbb/ccc/ddd','are you ok???',20); var_dump($file->init()); ?>
7、chdir,chroot
chdir(dirname) 表示把当前的目录改成指定的名字,dirname表示新的文件夹名字,成功返回true失败返回false
chroot(dirname) 表示把根目录改成指定的名字,dirname表示新的文件夹名字,成功返回true失败返回false
8、opendir,closedir,readdir,rewinddir,scandir
opendir(dirname) 表示打开路径名称,dirname表示路径名称,如果路径名称不存在,那么返回false
closedir(handle) 表示关闭指定的文件句柄,(即已经打开的文件系统)handle表示打开的文件句柄
readdir(handle) 表示读取指定的文件句柄,(即已经打开的文件系统)handle表示打开的文件句柄,如果读取失败则返回false;
rewinddir(handle) 表示指定的目录流重置到目录的开头,(即已经打开的文件系统)handle表示打开的文件句柄
scandir(dirname) 表示读取指定路径的文件夹内容,并且以数组的形式返回,如果读取失败,则返回false;
<?php header('Content-type:text/html;charset=utf8'); $dir = 'D:/filetest'; if (is_dir($dir)) { $handle = opendir($dir); while (false !== $file = readdir($handle)) { echo $file . '<br>'; }; closedir($handle); } //输出如下信息 // . // .. // haha // test.txt ?>
<?php header('Content-type:text/html;charset=utf8'); $dir = 'D:/filetest'; var_dump(scandir($dir)); //输出 array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(4) "haha" [3]=> string(8) "test.txt" } ?>
删除文件夹下的所有内容,以及获取所有文件的大小,复制文件夹
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); class removeFile { private $path; private $compareArr = ['.', '..']; /**删除文件或者文件夹 * @param $p * @return bool */ private function removeAll($p) { if(is_file($p)) { return unlink($p); } else if (is_dir($p)) { $tmp = array_diff(scandir($p), $this->compareArr); $dirname = realpath($p); array_walk($tmp, function ($val) use ($dirname) { $this->removeAll($dirname.'/'.$val); }); return rmdir($p); } return false; } /**获取所有文件的大小 * @param $p * @return bool|false|int */ private function getAllSize($p) { if(is_file($p)) { return filesize($p); } else if(is_dir($p)) { $num = 0; $tmp = array_diff(scandir($p), $this->compareArr); $dirname = realpath($p); array_walk($tmp, function ($val) use ($dirname, &$num) { $num += $this->getAllSize($dirname.'/'.$val); }); return $num; } return false; } /**复制文件 * @param $source * @param $target * @return bool */ private function copyAllFile($source, $target) { if(is_file($source)) { return copy($source, $target.'/'.basename($source)); } else if (is_dir($source)) { $tmp = array_diff(scandir($source), $this->compareArr); $basename = basename($source); $dirname = realpath($source); !file_exists($target.'/'.$basename) ? mkdir($target.'/'.$basename, 0777, true): null; $targetBase = $target.'/'.$basename; array_walk($tmp, function($val)use($basename, $dirname, $targetBase) { $this->copyAllFile($dirname.'/'.$val, $targetBase); }); return true; } return false; } public function remove(){ if(file_exists($this->path)){ return $this->removeAll($this->path); } return false; } public function getSize() { if(file_exists($this->path)){ return $this->getAllSize($this->path); } return false; } public function copy($targetPath) { if(file_exists($this->path) && (is_dir($targetPath) || mkdir($targetPath, 0777, true))) { return $this->copyAllFile($this->path, $targetPath); } return false; } public function __construct($path){ $this->path = $path; } } $t = new removeFile('d:/yii-docs-2.0-en'); var_dump($t->remove()); ?>
9、dir,getcwd
dir(dirname) 表示返回指定路径的相关信息,返回结果是一个对象,如果失败则返回false
getcwd() 表示返回当前工作的路径
<?php header('Content-type:text/html;charset=utf8'); $dir = 'D:/filetest'; var_dump(dir($dir)); //输出 object(Directory)#1 (2) { ["path"]=> string(11) "D:/filetest" ["handle"]=> resource(3) of type (stream) } var_dump(getcwd()); //输出 string(17) "C:wnmp ginxwww" ?>
10、file,fopen,fstat,ftell,fseek,fread,fwrite,fpassthru,fclose,rewind
file($filename) 把整个文件读入一个数组中 即把整个文件件的内容写入一个数组中
fopen($filename, $type) 打开文件或者 URL 返回一个handle句柄,$type常用的模式都有如下:
'r' | 只读方式打开,将文件指针指向文件头。 |
'r+' | 读写方式打开,将文件指针指向文件头。 |
'w' | 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 |
'w+' | 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 |
'a' | 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。 |
'a+' | 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之 |
为移植性考虑,强烈建议在用 fopen() 打开文件时总是使用 'b' 标记。
fstat($handle) 返回的是文件的信息,里有size,atime,ctime,mtime等信息
fseek($handle, offset) 对文件进行定位,即把文件指针移动到offset的位置,但如果fopen模式为a|a+则会失效
ftell($handle) 返回的是文件指针指向的位置
fread($handle, $length) 从文件指针 handle
读取最多 length
个字节,length常用的是filesize($path);
fclose($handle) 关闭文件句柄
fwrite($handle, $str) 在文件中的指针处写入指定的字符串
rewind($handle) 重置指针指向文件头
feof($handle) 表示判断是否到了文件的末尾
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); $path = realpath(__DIR__) . "/test.txt"; //var_dump(file($path)); //输出 //array(9) { // [0]=>string(18) "are you ok???" // [1]=>string(22) "today is good day!!!" // [2]=>string(19) "nice to meet you!" // [3]=>string(14) "how are you?" // [4]=>string(26) "昨天,今天,明天" // [5]=>string(20) "很高兴见到你" // [6]=>string(13) "function(){" // [7]=>string(31) " console.log('are you ok???)" // [8]=>string(1) "}" //} $handle = fopen($path, 'a+b'); fseek($handle, 5); var_dump(ftell($handle)); //输出 int(5) rewind($handle); //输出 int(0); var_dump(ftell($handle)); var_dump(fpassthru($handle)); //输出当前位置之后的所有内容 $info = fstat($handle); var_dump($info); //输出当前的文件信息 $content = fread($handle, filesize($path)); var_dump(nl2br($content)); //输出指定长度的文件内容 echo '<hr>'; echo ftell($handle); fwrite($handle, 'aaaaaaaaaaa'); //在文件的末尾处添加入指定的字符串 ?>
注意: 以上的fread($handle, length)虽然可以读取内容,但是,当文件过大的时候,会导致程序的负荷过重,因为,如果遇到大文件的时候可以设置缓冲区,实现部份文件的循环读取,具体如下:
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); $path = realpath(__DIR__) . "/test.txt"; if(file_exists($path)) { $handle = fopen($path, 'rb'); rewind($handle); $read_size = 10; $all_content = ''; while(!feof($handle)) { $all_content .= htmlspecialchars(fread($handle, $read_size)); } fclose($handle); //关闭文件 echo $all_content; } else { echo '文件不存在'; } ?>
写入内容的案例
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); $path = realpath(__DIR__); $handle = fopen($path.'/test.txt','a+b'); $str = str_repeat("are you ok??? ", 10); fwrite($handle, $str); fclose($handle); ?>
11、file_get_contents,file_put_contents,mime_content_type,parse_ini_file,fgets,unlink
file_get_contents($filename) 表示读取的文件里的内容,在PHP的底层,是用fopen,fread,fclose来封装的,如果文件的流不是很大,推荐使用这个方法,否则推荐使用上面的做法
file_put_contents($filename, $data,$type)表示写入文件里的内容,在PHP的底层,是用fopen,fwrite,fclose来封装的,$type表示是类型,常规是覆盖写,如果改成FILE_APPEND,那么就是追加写,如果没有目标文件,则会进行创建
mime_content_type($filename) 获取文件的类型
parse_ini_file($filename) 表示读入一个配置文件,并且以一个数组的方式输出,如果是一个非ini文件,那么返回false
fgets($handle, $length) 从文件中获取一行的数据,主要是以文件中的 进行分割, $length表示长度,最大是一行数据中的length-1个数据,该函数会自动过滤掉html,javascript以及php的标签
unlink($filename) 删除文件
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); $path = realpath(__DIR__ . '/test.txt'); $content = file_get_contents($path); var_dump($content); echo '<hr>'; //可以输出文件里的所有内容 $data = "are you ok??? today is good day , nice to meet you!!!"; $res = file_put_contents($path, $data); var_dump($res); //输出 int(53) var_dump(file_get_contents($path)); //输出 string(53) "are you ok??? today is good day , nice to meet you!!!" //进行parse_ini_file函数测试 if(file_exists($path)) { var_dump(parse_ini_file($path)); //输出 //array(3) { ["name"]=> string(4) "aaaa" ["age"]=> string(2) "30" ["like"]=> string(13) "are you ok???" } } else { echo '文件不存在'; } ?>
<?php header('content-type:text/html;charset=utf8'); ini_set('display_errors', true); $path = realpath(__DIR__ . '/test.html'); $handle = fopen($path, 'rb'); $content = ''; while(!feof($handle)) { $content .= fgets($handle); } fclose($handle); echo $content; //输出所有非html, javascript, php的内容 unlink($path); //删除文件 ?>
12、iconv
因为文件操作函数是早期开发的功能,因些对gbk,gb2312支持的比较好,但是对utf8支持的不好,因此在使用中文给文件名命名的时候,需要用以上的函数进行转义;
iconv($in_charset, $out_charset, $str)
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); $path = realpath(__DIR__); $fromFile = $path.'/test.txt'; $toFile = $path.'/你好.txt'; $toFile = iconv('utf-8', 'gbk', $toFile); var_dump(rename($fromFile, $toFile)); ?>
注意:在文件名的字符比对的时候也要进行转化后进行处理比对
13、文件的上传
文件的上传,如果通过表单上传应具备如下条件
A、上传的方式必需为Post方式
B、在form里面应指定上传的属性 enctype="multipart/form-data"
C、在PHP接收端通过$_FILES来接收
<?php header('content-type:text/html;charset=utf-8'); ini_set('display_errors', true); echo '<pre>'; var_dump($_FILES['file']); //也可以使用$_FILES来获取全部的数组 ?>
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <form action="./test.php" enctype="multipart/form-data" method="post"> <input type="file" name="file"> <input type="submit" value="提交"> </form> </body> </html>
is_uploaded_file,move_uploaded_file
is_uploaded_file($filename) 判断文件是否是通过 HTTP POST 上传的
move_uploaded_file($filename, $destination) 将上传的文件移动到新位置,$filename表示文件的路径,$destination表示目标路径,成功返回true,失败返回false
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <form action="./test.php" enctype="multipart/form-data" method="post"> <input type="file" name="file"> <input type="submit" value="提交"> </form> </body> </html>
<?php header('content-type; charset=utf-8'); header('refresh:5, url= test.html'); ini_set('display_errors', true); class UploadFile{ private $file; private $limitSize = 2*1024*1048; private $limitType = ['image/jpg', 'image/png', 'image/jpeg', 'text/plain']; private $targetDir = 'd:/uploadFile'; public function __construct($name) { if($_FILES[$name]['error'] === 4) { die('请上传文件'); } $this->file = $_FILES[$name]; } /**检查大小 * @return bool */ private function checkSize() { if($this->file['size'] > $this->limitSize) { return true; } return false; } private function getExtension() { return strtolower(substr(strrchr($this->file['name'], '.'),1)); } /**检查类型 * @return bool */ private function checkType() { //检测实际的文件类型 $finfo = new finfo(FILEINFO_MIME_TYPE); $type = $finfo->file($this->file['tmp_name']); return !in_array($type, $this->limitType) || !in_array($this->file['type'], $this->limitType); } /**存放的目录及文件名 * @return string */ private function getFileDir() { $dir = $this->targetDir.'/'.date('Ymd'); if(!file_exists($dir)) { mkdir($dir, 0777, true); } $dir .= sprintf('/%s.%s',uniqid('up_', true), $this->getExtension()); return $dir; } public function init() { if(is_uploaded_file($this->file['tmp_name'])) { $this->checkSize()? die(sprintf('上传的内容过大,你只能上传%dK的文件,而你的文件是%dK', $this->limitSize, $this->file['size'])): null; $this->checkType()? die(sprintf('上传的文件类型不正确,你只能上传%s,类型的文件', implode(',', $this->limitType))): null; $newName = $this->getFileDir(); if(move_uploaded_file($this->file['tmp_name'], $newName)) { return $newName; }else { return false; } } return 'unKnow'; } } $f = new UploadFile('file'); $f->init(); ?>
如果有多个类似的功能,可以做成一个抽象类,进行继承。或者做成一个普通类进行继承
14、文件的下载(注意文件头的设置)
<?php class DownLoad { private $dir = 'd:yii-basic-app-2.0.15.tgz'; public function __construct() { if(!$_GET['name'] || $_GET['name'] !== 'test') { die('请指定特定的文件名'); } } private function setHeader(int $filesize, string $filename) { //告诉浏览器我向你回应的内容是文件请保存 //返回的文件 header("Content-type: application/octet-stream"); //按照字节大小返回 header("Accept-Ranges: bytes"); //显示文件大小 header("Content-Length: {$filesize}"); //这里客户端的弹出对话框,对应的文件名 header("Content-Disposition: attachment; filename={$filename}"); } public function init() { $this->setHeader(filesize($this->dir), sprintf('test.%s', pathinfo($this->dir,PATHINFO_EXTENSION))); $handle = fopen($this->dir, 'rb'); $size = 1024; $content = ''; while(!feof($handle)) { $content .= fread($handle, $size); } fclose($handle); echo $content; } } $t = new DownLoad(); $t->init(); ?>
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <a href="./index.php?name=test">下载</a> </body> </html>