上一篇
"小王最近接手了一个网站维护项目,客户要求在用户上传图片时自动生成缩略图并保存到不同目录,更复杂的是,当用户创建新相册时,需要复制整个预设模板文件夹结构到用户目录下,面对这些需求,小王需要掌握PHP中文件和文件夹复制的各种技巧..."
$sourceFile = 'uploads/original.jpg'; $targetFile = 'thumbnails/small_original.jpg'; if (copy($sourceFile, $targetFile)) { echo "文件复制成功!"; } else { echo "文件复制失败,请检查权限或路径"; }
注意点:
function streamCopy($source, $dest) { $sourceHandle = fopen($source, 'rb'); $destHandle = fopen($dest, 'wb'); while (!feof($sourceHandle)) { fwrite($destHandle, fread($sourceHandle, 8192)); } fclose($sourceHandle); fclose($destHandle); } streamCopy('large_video.mp4', 'backups/large_video_backup.mp4');
优势:
$content = file_get_contents('config.json'); if ($content !== false) { $result = file_put_contents('backup/config.json', $content); if ($result !== false) { echo "JSON配置文件复制成功"; } }
适用场景:
function safeCopy($src, $dst) { if (!file_exists($src)) { throw new Exception("源文件不存在: $src"); } if (!is_readable($src)) { throw new Exception("源文件不可读: $src"); } $dstDir = dirname($dst); if (!file_exists($dstDir)) { if (!mkdir($dstDir, 0755, true)) { throw new Exception("无法创建目标目录: $dstDir"); } } if (!copy($src, $dst)) { throw new Exception("复制失败: $src 到 $dst"); } // 保持相同的文件权限 chmod($dst, fileperms($src)); return true; } // 使用示例 try { safeCopy('important.docx', 'archives/2025/important.docx'); } catch (Exception $e) { error_log("复制错误: " . $e->getMessage()); }
function copyDirectory($src, $dst) { if (!file_exists($dst)) { mkdir($dst, 0755, true); } $dir = opendir($src); while (($file = readdir($dir)) !== false) { if ($file != '.' && $file != '..') { $srcPath = $src . '/' . $file; $dstPath = $dst . '/' . $file; if (is_dir($srcPath)) { copyDirectory($srcPath, $dstPath); } else { copy($srcPath, $dstPath); } } } closedir($dir); } // 使用示例 copyDirectory('templates/default_album', 'user_data/album_123');
function copyFolder($source, $target) { if (!is_dir($target)) { mkdir($target, 0755, true); } $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $item) { $targetPath = $target . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); if ($item->isDir()) { if (!file_exists($targetPath)) { mkdir($targetPath); } } else { copy($item, $targetPath); } } } // 使用示例 copyFolder('system/modules', 'custom/modules_backup');
function linuxCopyDir($src, $dest) { if (!is_dir($src)) { return false; } $src = rtrim($src, '/') . '/'; $dest = rtrim($dest, '/') . '/'; $command = "cp -R {$src}* {$dest}"; exec($command, $output, $returnVar); return $returnVar === 0; } // 使用前请确保安全过滤$src和$dest参数 if (linuxCopyDir('/var/www/templates', '/var/www/user_data')) { echo "文件夹复制完成"; }
对于特别大的文件夹:
ini_set('memory_limit', '512M'); // 临时增加内存限制 set_time_limit(0); // 取消执行时间限制
// 复制后保留原文件的修改时间 touch($destFile, filemtime($srcFile));
function copyWithProgress($src, $dst, $callback = null) { $totalSize = filesize($src); $copied = 0; $srcHandle = fopen($src, 'rb'); $dstHandle = fopen($dst, 'wb'); while (!feof($srcHandle)) { $buffer = fread($srcHandle, 8192); fwrite($dstHandle, $buffer); $copied += strlen($buffer); if (is_callable($callback)) { $percent = ($copied / $totalSize) * 100; $callback($percent, $copied, $totalSize); } } fclose($srcHandle); fclose($dstHandle); } // 使用示例 copyWithProgress('bigfile.iso', 'backup/bigfile.iso', function($percent) { echo "进度: " . round($percent, 2) . "%\n"; });
realpath()
函数可以解析路径方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
简单copy() | 单个小文件 | 简单直接 | 功能有限 |
文件流方式 | 大文件复制 | 内存占用稳定 | 代码稍复杂 |
递归复制 | 完整目录结构 | 纯PHP实现,兼容性好 | 深层目录可能超时 |
RecursiveIterator | 现代PHP环境 | 代码简洁,面向对象 | PHP 5.3+ required |
系统命令 | Linux服务器,超大目录 | 最快性能 | 平台依赖,安全性风险 |
选择建议:
copy()
RecursiveIterator
掌握PHP文件与目录复制操作是Web开发中的基本功,根据实际场景选择合适的方法,既能保证功能实现,又能兼顾性能和安全性,记得在实际应用中添加完善的错误处理和日志记录,特别是在处理用户上传文件或敏感数据时。
本文由 容诗筠 于2025-08-01发表在【云服务器提供商】,文中图片由(容诗筠)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/501949.html
发表评论