php清理文件夹 WSTMALL处理的错误思想解析

2016-12-09 09:50:00
hainuo
原创 820
在php7.1 下使用WSTMALL出现一下问题,关于php的文件操作 WSTMALL的处理方式如下 ``` function WSTDelDir($dirpath) { $dh = opendir($dirpath); while (($file = readdir($dh))!==false) { //=====>C if ($file != "." && $file != "..") { $fullpath = $dirpath . "/" . $file; if (!is_dir($fullpath)) { unlink($fullpath); } else { WSTDelDir($fullpath); //=======>A rmdir($fullpath); } } } closedir($dh);//=========>B $isEmpty = 1; $dh = opendir($dirpath); while (($file = readdir($dh)) != false) { if ($file != "." && $file != "..") { $isEmpty = 0; break; } } return $isEmpty; } ``` 我调试了一下发现文件夹正常删除,但是 最后总会遇到一个TEMP文件夹内有文件。 所以个人感觉WSTMALL的删除有问题。 通过个人跟踪发现 标记为A处的命令并没有执行第二次,只执行到第一处就结束了。也就是说。这个方法没有深度递归。 于是我用了另一个opensns的实现 ``` function WSTDelDir($dirname) { if (!file_exists($dirname)) { return 0; } if (is_file($dirname) || is_link($dirname)) { return unlink($dirname); } $dir = dir($dirname); if($dir){ while (false !== $entry = $dir->read()) { if ($entry == '.' || $entry == '..') { continue; } WSTDelDir($dirname . DIRECTORY_SEPARATOR . $entry); } } $dir->close(); return rmdir($dirname); } ``` 对比之后发现原来是原先的实现有问题。 关键就在于 `B标记`之后. 1. WSTMALL的写法有读取了一遍文件夹。这个是有问题的。原因在于当前进程虽然在之前成功删除了文件夹,但是并没有保证其他进程不会生成缓存文件。所以WSTMALL的失败就在此处。 2. 另一点就是OPENSNS的处理方式,成功的删除了所有缓存文件,而 WSTMALL无法成功处理也在于`B标记`之后的数据,他提前返回了。并没有循环完毕所有的目录。 3. 最后说一下 > 关于在PHP7.1正式版下为什么WSTMALL的清理方法不执行了。 原因是PHP7.1 修正一处bug 。[x] Fixed bug #72667 (opendir() with ftp:// attempts to open data stream for non-existent directories). 这导致`opendir()`打开一个不存在目录返回的是null而不是false