在 PHP 中将整个目录复制到另一个目录


什么是 PHP?

PHP(代表超文本预处理器)是一种广泛使用的服务器端脚本语言,主要用于 Web 开发。它为开发人员提供了一个强大而灵活的平台来创建动态网页和应用程序。PHP 可以嵌入到 HTML 代码中,从而实现服务器端功能与客户端元素的无缝集成。其语法类似于 C 和 Perl,对于熟悉这些语言的程序员来说,相对容易学习和使用。PHP 允许在 Web 服务器上执行服务器端脚本,生成可以传递到用户浏览器的动态内容。它支持各种数据库,使其适合开发数据库驱动的网站。此外,PHP 提供了一个庞大的开源库和框架生态系统,有助于加快开发速度并增强代码的可重用性。凭借其强大的社区支持和丰富的文档,PHP 仍然是全球 Web 开发人员的首选语言之一。

在 PHP 中将整个目录复制到另一个目录

这里我们使用 scandir() 函数和 RecursiveIteratorIterator 类来复制整个目录的内容到另一个目录。

方法 1

使用 scandir()

然后 scandir() 接受多个参数并返回目录中文件名的列表(如果未发生错误)。

语法

array scandir(string $directory, int $sorting_order = 
SCANDIR_SORT_ASCENDING, resource|null $context = null)
  • $directory (字符串):要扫描的目录的路径。

  • $sorting_order (整数,可选):指定结果的排序顺序。它可以取以下值之一

  • SCANDIR_SORT_ASCENDING(默认):按升序排序结果。

  • SCANDIR_SORT_DESCENDING:按降序排序结果。

  • SCANDIR_SORT_NONE:不执行任何排序。

  • $context (资源|空,可选):指定使用 stream_context_create() 创建的上下文资源。它用于修改 scandir() 函数的行为。如果未提供,则使用 null。

  • 返回值:scandir() 函数返回指定目录中文件名和目录的数组。它包括普通文件和目录。生成的数组包含特殊条目 . 和 ..,分别表示当前目录和父目录。

示例

以下是如何使用 scandir() 在 PHP 中将整个目录的内容复制到另一个目录的示例。

<?php
function copyDirectory($source, $destination) {
   if (!is_dir($destination)) {
      mkdir($destination, 0755, true);
   }
   $files = scandir($source);
   foreach ($files as $file) {
      if ($file !== '.' && $file !== '..') {
         $sourceFile = $source . '/' . $file;
         $destinationFile = $destination . '/' . $file;
         if (is_dir($sourceFile)) {
            copyDirectory($sourceFile, $destinationFile);
         } else {
            copy($sourceFile, $destinationFile);
         }
      }
   }
}
$sourceDirectory = '/source/directory';
$destinationDirectory = '/destination/directory';
copyDirectory($sourceDirectory, $destinationDirectory);
?>

输出

There will be no output if the process is successful.

代码解释

代码定义了一个名为 copyDirectory 的函数,该函数负责将源目录的内容递归复制到目标目录。该函数首先检查目标目录是否存在,如果不存在,则使用 mkdir() 创建它。然后,它使用 scandir() 获取源目录中文件和目录的列表。它遍历每个项目,排除 . 和 .. 条目,并构造源和目标文件路径。如果该项目是目录,则该函数会使用新路径递归调用自身。如果它是文件,则它使用 copy() 函数将文件从源复制到目标。此过程将继续,直到源目录的所有内容(包括子目录及其相应的文件)都复制到目标目录。最后,使用提供的源目录和目标目录作为参数调用该函数以执行复制操作。

方法 2

使用 RecursiveIteratorIterator 类以及 RecursiveDirectoryIterator

这里我们将使用两个类来完成任务。

语法

bool mkdir(string $pathname, int $mode = 0777, bool $recursive = 
false, resource|null $context = null)
  • $pathname (字符串):要创建的目录的路径。

  • $mode (整数,可选):要为新创建的目录设置的权限。它以八进制值指定。

  • $recursive (布尔值,可选):如果设置为 true,则启用父目录的递归创建。

  • $context (资源|空,可选):指定使用 stream_context_create() 创建的上下文资源。

  • 返回值:mkdir() 函数在成功时返回 true,失败时返回 false。

示例

以下是如何使用上述方法的示例。

function copyDirectory($source, $destination) {
   if (!is_dir($destination)) {
      mkdir($destination, 0755, true);
   }
   $iterator = new RecursiveIteratorIterator(
      new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
      RecursiveIteratorIterator::SELF_FIRST
   );
   foreach ($iterator as $item) {
      if ($item->isDir()) {
         $dir = $destination . '/' . $iterator->getSubPathName();
         if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
         }
      } else {
         $file = $destination . '/' . $iterator->getSubPathName();
         copy($item, $file);
      }
   }
}
$sourceDirectory = '/source/directory';
$destinationDirectory = '/destination/directory';
copyDirectory($sourceDirectory, $destinationDirectory);

输出

There will be no output if the process is successful.

代码解释

代码定义了一个名为 copyDirectory 的函数,该函数负责将源目录的内容递归复制到目标目录。该函数首先检查目标目录是否存在,如果不存在,则使用 mkdir() 创建它。然后,它使用 scandir() 获取源目录中文件和目录的列表。它遍历每个项目,排除 . 和 .. 条目,并构造源和目标文件路径。如果该项目是目录,则该函数会使用新路径递归调用自身。如果它是文件,则它使用 copy() 函数将文件从源复制到目标。此过程将继续,直到源目录的所有内容(包括子目录及其相应的文件)都复制到目标目录。最后,使用提供的源目录和目标目录作为参数调用该函数以执行复制操作。

方法 2

使用 RecursiveIteratorIterator 类以及 RecursiveDirectoryIterator

这里我们将使用两个类来完成任务。

语法

bool mkdir(string $pathname, int $mode = 0777, bool $recursive = 
false, resource|null $context = null)
  • $pathname (字符串):要创建的目录的路径。

  • $mode (整数,可选):要为新创建的目录设置的权限。它以八进制值指定。

  • $recursive (布尔值,可选):如果设置为 true,则启用父目录的递归创建。

  • $context (资源|空,可选):指定使用 stream_context_create() 创建的上下文资源。

  • 返回值:mkdir() 函数在成功时返回 true,失败时返回 false。

示例

以下是如何使用上述方法的示例。

function copyDirectory($source, $destination) {
   if (!is_dir($destination)) {
      mkdir($destination, 0755, true);
   }
   $iterator = new RecursiveIteratorIterator(
      new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
      RecursiveIteratorIterator::SELF_FIRST
   );
   foreach ($iterator as $item) {
      if ($item->isDir()) {
         $dir = $destination . '/' . $iterator->getSubPathName();
         if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
         }
      } else {
         $file = $destination . '/' . $iterator->getSubPathName();
         copy($item, $file);
      }
   }
}
$sourceDirectory = '/source/directory';
$destinationDirectory = '/destination/directory';
copyDirectory($sourceDirectory, $destinationDirectory);

代码解释

在这种方法中,RecursiveDirectoryIterator 用于遍历目录结构,包括所有子目录和文件。RecursiveIteratorIterator 有助于递归遍历迭代器。它使用 SKIP_DOTS 标记跳过 . 和 .. 条目。在循环内,它检查当前项目是否为目录。如果是,则使用 mkdir() 在目标路径中创建相应的目录(如果它尚不存在)。如果该项目是文件,则它构造目标文件路径并使用 copy() 复制文件。此方法消除了对单独的递归函数的需求,并通过利用内置的 PHP 迭代器类的功能简化了代码。

结论

总之,这两种方法都可以达到预期的效果,但使用迭代器的第二种方法提供了一种更优雅和高效的解决方案,尤其是在涉及大型目录结构的情况下。但是,两种方法之间的选择最终取决于开发人员的具体需求和偏好。

更新于: 2023-07-28

2K+ 浏览量

启动你的 职业生涯

通过完成课程获得认证

开始学习
广告