【问题标题】:PHP: Unlink All Files Within A Directory, and then Deleting That DirectoryPHP:取消链接目录中的所有文件,然后删除该目录
【发布时间】:2012-07-01 07:09:06
【问题描述】:

我有一种方法可以使用 RegExp 或通配符搜索快速删除文件夹中的所有文件,然后在 PHP 中删除该文件夹,而不使用“exec”命令?我的服务器没有授权我使用该命令。某种简单的循环就足够了。

我需要一些东西来完成以下语句背后的逻辑,但显然是有效的:

$dir = "/home/dir" unlink($dir . "/*"); # "*" being a match for all strings rmdir($dir);

【问题讨论】:

标签: php unlink rmdir


【解决方案1】:

要删除所有文件,您可以删除目录并再次制作.. 使用简单的代码行

<?php 
    $dir = '/home/files/';
    rmdir($dir);
    mkdir($dir);
?>

【讨论】:

    【解决方案2】:

    试试简单的方法:

    $dir = "/home/dir";
    array_map('unlink', glob($dir."/*"));
    rmdir($dir);
    

    在函数中删除目录:

    function unlinkr($dir, $pattern = "*") {
            // find all files and folders matching pattern
            $files = glob($dir . "/$pattern"); 
            //interate thorugh the files and folders
            foreach($files as $file){ 
                //if it is a directory then re-call unlinkr function to delete files inside this directory     
                if (is_dir($file) and !in_array($file, array('..', '.')))  {
                    unlinkr($file, $pattern);
                    //remove the directory itself
                    rmdir($file);
                    } else if(is_file($file) and ($file != __FILE__)) {
                    // make sure you don't delete the current script
                    unlink($file); 
                }
            }
            rmdir($dir);
        }
    
    //call following way:
    unlinkr("/home/dir");
    

    【讨论】:

    • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
    【解决方案3】:

    使用Standard PHP Library,具体来说是RecursiveIteratorIteratorRecursiveDirectoryIterator,递归删除所有文件和文件夹的简单而有效的方法。重点在RecursiveIteratorIterator::CHILD_FIRST标志,迭代器会先循环遍历文件,最后循环遍历目录,所以一旦目录为空就可以安全使用rmdir()

    foreach( new RecursiveIteratorIterator( 
        new RecursiveDirectoryIterator( 'folder', FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS ), 
        RecursiveIteratorIterator::CHILD_FIRST ) as $value ) {
            $value->isFile() ? unlink( $value ) : rmdir( $value );
    }
    
    rmdir( 'folder' );
    

    【讨论】:

      【解决方案4】:

      您可以使用Symfony Filesystem component,避免重新发明轮子,所以您可以这样做

      use Symfony\Component\Filesystem\Filesystem;
      
      $filesystem = new Filesystem();
      
      if ($filesystem->exists('/home/dir')) {
          $filesystem->remove('/home/dir');
      }
      

      如果您更喜欢自己管理代码,这里是相关方法的 Symfony 代码库

      class MyFilesystem
      {
          private function toIterator($files)
          {
              if (!$files instanceof \Traversable) {
                  $files = new \ArrayObject(is_array($files) ? $files : array($files));
              }
      
              return $files;
          }
      
          public function remove($files)
          {
              $files = iterator_to_array($this->toIterator($files));
              $files = array_reverse($files);
              foreach ($files as $file) {
                  if (!file_exists($file) && !is_link($file)) {
                      continue;
                  }
      
                  if (is_dir($file) && !is_link($file)) {
                      $this->remove(new \FilesystemIterator($file));
      
                      if (true !== @rmdir($file)) {
                          throw new \Exception(sprintf('Failed to remove directory "%s".', $file), 0, null, $file);
                      }
                  } else {
                      // https://bugs.php.net/bug.php?id=52176
                      if ('\\' === DIRECTORY_SEPARATOR && is_dir($file)) {
                          if (true !== @rmdir($file)) {
                              throw new \Exception(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
                          }
                      } else {
                          if (true !== @unlink($file)) {
                              throw new \Exception(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
                          }
                      }
                  }
              }
          }
      
          public function exists($files)
          {
              foreach ($this->toIterator($files) as $file) {
                  if (!file_exists($file)) {
                      return false;
                  }
              }
      
              return true;
          }
      }
      

      【讨论】:

        【解决方案5】:

        使用glob()轻松循环目录删除文件,然后您可以删除目录。

        foreach (glob($dir."/*.*") as $filename) {
            if (is_file($filename)) {
                unlink($filename);
            }
        }
        rmdir($dir);
        

        【讨论】:

        • 这段代码很危险,路径应该像glob($dir."/*.*")一样包含在全局中。我试过了,它清除了所有目录,包括我辛勤工作的顶级目录
        【解决方案6】:

        使用glob 查找与某个模式匹配的所有文件。

        function recursiveRemoveDirectory($directory)
        {
            foreach(glob("{$directory}/*") as $file)
            {
                if(is_dir($file)) { 
                    recursiveRemoveDirectory($file);
                } else {
                    unlink($file);
                }
            }
            rmdir($directory);
        }
        

        【讨论】:

        • 我收到错误maximum function nesting level of '100' reached
        • 我在代码中遇到了scandir 函数的权限问题,现在它与这个版本完美配合!
        • glob 处理隐藏文件?
        • 很棒的解决方案:D
        • 而不仅仅是} else { 使用} else if(!is_link($file)) { 是符号链接安全
        【解决方案7】:

        glob() 函数可以满足您的需求。如果您使用的是 PHP 5.3+,则可以执行以下操作:

        $dir = ...
        array_walk(glob($dir . '/*'), function ($fn) {
            if (is_file($fn))
                unlink($fn);
        });
        unlink($dir);
        

        【讨论】:

          【解决方案8】:

          一种方法是:

          function unlinker($file)
          {
              unlink($file);
          }
          $files = glob('*.*');
          array_walk($files,'unlinker');
          rmdir($dir);
          

          【讨论】:

            猜你喜欢
            • 2011-03-27
            • 1970-01-01
            • 1970-01-01
            • 2023-03-08
            • 2010-11-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多