mclee 's Blog
Love Leanote!
Toggle navigation
mclee 's Blog
主页
PHP
归档
标签
PHP 处理目录及文件信息
无
2018-02-09 05:30:50
374
0
0
mclee
# 简介 文件系统除了存储文件的具体内容之外,还会存储许多额外信息。这些信息包括文件大小、目录和访问权限等细节。处理文件时,还需要处理这些元数据。PHP 提供了大量函数来读取和处理目录、目录项和文件属性。这些函数与 C 函数类似,只有一些简化。 # 遍历目录 PHP 提供了很多方法来查看目录,查找其中哪些文件。DirectoryIterator 类提供了一个访问目录的全面的面向对象接口。这个类继承了 SplFileInfo 类。 ``` <?php foreach (new DirectoryIterator('f:/music') as $file) { // 跳过 . 和 .. 目录 if (!$file->isDot()) { // 迭代的每个元素都是 DirectoryIterator 实例,由于继承了 SplFileInfo 类,故可以调用获取文件信息的方法 echo $file->getPathname(), PHP_EOL; } } ``` > 结合阮一峰的博客(虽然有多处笔误但大概还是能正确理解)和手册看看 spl 的迭代器吧 http://www.ruanyifeng.com/blog/2008/07/php_spl_notes.html http://php.net/manual/zh/spl.iterators.php opendir()、readdir() 和 closedir() 函数提供了一种过程式方法完成同样的任务。 ``` <?php $d = opendir('f:/music') or die($php_errormsg); while (false !== ($f = readdir($d))) { if($f !== '.' || $f !== '..') echo $f, PHP_EOL; } closedir($d); ``` 注:PHP 还有一个 dir 类,提供了相应的过程式方法(打开,读和关闭)。由于 DirectoryIterator 功能更强大,更推荐使用。 # 递归遍历目录中的所有文件 ``` <?php $dir = new RecursiveDirectoryIterator('f:/music'); foreach (new RecursiveIteratorIterator($dir) as $file) { echo $file->getPathName(), PHP_EOL; } ``` # 文件信息函数 要查找一个文件、目录或链接的有关信息,必须检查它的 inode。函数 stat() 会获取一个 inode 中的元数据。PHP 还有很多函数在内部使用 stat() 来提供文件的一个特定信息。  关于 stat : * 由于 stat() 返回一个同时有数值索引和字符串索引的数组,所以使用 foreach 迭代处理返回的数组时,会生成每个值的两个副本。实际上,完全可以用一个 for 循环迭代处理返回数组中的元素 0 到元素 12。 * 在一个符号链接上调用 stat() 时,会返回这个符号链接指向的文件的有关信息。要想得到符号链接本身的信息,可以使用 lstat()。 * 与 stat() 函数类似的还有一个 fstat() 函数,它取一个文件句柄(由 fopen() 或 popen() 返回)作为参数。  关于获取权限要注意返回的是 10 进制。该是返回值的低 4 位对应 chmod() 中的参数意义。高几位则表示文件类型,根据不同平台差异会很大,但低4位通常是通用的,故获取权限信息时常转化为 8 进制数后再截取低 4 位信息。 ``` <?php // %o 控制符代表以 8 进制输出 echo substr(sprintf('%o', fileperms('/tmp')), -4); ``` PHP 的 stat() 函数使用低层 stat(2) 系统调用,这个系统调用的开销很大。为了尽量减少开销,PHP 会缓存调用 stat(2) 的结果。所以如果在一个文件上调用 stat(),然后改变它的权限,并在再次调用 stat(),会得到同样的结果(缓存结果)。要强制 PHP 重新加载文件的元数据,需要调用 clearstatcache() 函数,这会刷新输出 PHP 缓存的信息。PHP 还会对其他返回文件元数据的函数使用这个缓存,这包括以下: * file_exists() * fileatime() * filectime() * filegroup() * fileinode() * filemtime() * fileowener() * fileperms() * filesize() * filetype() * fstat() * is_dir() * is_executable() * is_file() * is_link() * is_readable() * is_writable() * lstat() ``` <?php $atime = fileatime('./mclee.txt'); echo $atime, PHP_EOL; // 1518113620 touch('./mclee.txt'); clearstatcache(); // 没有这一句,两次结果相同。 $atime = fileatime('./mclee.txt'); echo $atime; //1518113621 ``` # 改变文件权限或所有者 chmod()、chgrp() 和 chwon()。不过这些都无法再 windows上使用。 # DirectoryIterator 对象信息方法  > http://php.net/manual/zh/class.directoryiterator.php # 创建新目录 bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $context ]]] ) 默认只有当父目录存在时 mkdir() 才会创建目录。可以传入 true 作为第三个参数,递归的创建缺失的父目录。 # 删除一个目录 ``` <?php function delDirectory($dir) { try { $iter = new RecursiveDirectoryIterator($dir); // RecursiveIteratorIterator::CHILD_FIRST 表示先提供子元素在提供父元素(深度优先遍历) foreach (new RecursiveIteratorIterator($iter, RecursiveIteratorIterator::CHILD_FIRST) as $f) { $pathName = $f->getPathname(); if ($f->isDir()) { $pathNameSecions = explode(DIRECTORY_SEPARATOR, $pathName); // 跳过 . 和 .. 目录 if (!in_array(end($pathNameSecions), ['.', '..'])) rmdir($pathName); } else { unlink($pathName); } } rmdir($dir); } catch (Exception $e) { throw new Exception($e->getMessage()); } } delDirectory('./test'); ``` RecursiveIteratorIterator::__construct: public RecursiveIteratorIterator::__construct ( Traversable $iterator [, int $mode = RecursiveIteratorIterator::LEAVES_ONLY [, int $flags = 0 ]] ) 关于更多 mode:  分别对应只要叶节点,广搜,深搜的遍历方式。
上一篇:
cURL
下一篇:
PHP 处理文件
0
赞
374 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册