PHP Folder and File Copy/Move Operations
Learn how to efficiently manage files in PHP by utilizing built-in functions to copy and move files. This tutorial includes detailed explanations and examples for practical usage.
How to Copy Files Using PHP
The copy()
function in PHP allows you to duplicate files from one location to another. Below is a simple example:
How to Move Files Using PHP
To move files, PHP provides the rename()
function. This can be used to move a file to a new location or rename it. Here's an example:
How to Copy All Files in a Folder Using PHP
The copyFolderContents
function is a versatile and efficient utility designed to copy the contents of a source folder to a destination folder, with optional recursive copying of sub directories. It incorporates robust error handling to ensure reliability, providing detailed feedback on successes and failures during the operation. The function automatically creates destination directories if they don't exist, normalizes file paths for consistency, and ensures compatibility across different operating systems.
The following code demonstrates how to copy all files from one folder to another:
<?php
/**
* Enhanced folder and file copying function with an overwrite option.
*
* @param string $source Source directory path
* @param string $destination Destination directory path
* @param bool $recursive Whether to copy subdirectories recursively
* @param bool $overwrite Whether to overwrite existing files in the destination
* @return array Operation results with success and error details
*/
function copyFolderContents(string $source, string $destination, bool $recursive = true, bool $overwrite = true): array {
// Normalize paths to remove trailing slashes
$source = rtrim($source, '/\\');
$destination = rtrim($destination, '/\\');
// Initialize results tracking
$results = [
'success' => true,
'error' => null,
'copied_files' => [],
'failed_files' => []
];
// Validate source directory
if (!is_dir($source)) {
$results['success'] = false;
$results['error'] = "Source folder does not exist or is not a directory: $source";
return $results;
}
// Create destination folder if it doesn't exist
if (!file_exists($destination) && !mkdir($destination, 0755, true)) {
$results['success'] = false;
$results['error'] = "Cannot create destination folder: $destination";
return $results;
}
// Ensure destination is a valid directory
if (!is_dir($destination)) {
$results['success'] = false;
$results['error'] = "Destination is not a valid directory: $destination";
return $results;
}
// Read contents of the source directory
$items = scandir($source);
if ($items === false) {
$results['success'] = false;
$results['error'] = "Failed to read source folder: $source";
return $results;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$sourceItem = $source . DIRECTORY_SEPARATOR . $item;
$destinationItem = $destination . DIRECTORY_SEPARATOR . $item;
// Handle files
if (is_file($sourceItem)) {
if (!$overwrite && file_exists($destinationItem)) {
// Skip overwriting the existing file
$results['failed_files'][] = $destinationItem; // Track skipped files
continue;
}
// Copy file and track the result
if (@copy($sourceItem, $destinationItem)) {
$results['copied_files'][] = $destinationItem;
} else {
$results['failed_files'][] = $sourceItem;
$results['success'] = false;
}
}
// Handle directories recursively
elseif ($recursive && is_dir($sourceItem)) {
$subResults = copyFolderContents($sourceItem, $destinationItem, true, $overwrite);
// Merge results from subdirectories
$results['copied_files'] = array_merge($results['copied_files'], $subResults['copied_files']);
$results['failed_files'] = array_merge($results['failed_files'], $subResults['failed_files']);
if (!$subResults['success']) {
$results['success'] = false;
}
}
}
return $results;
}
?>
Usage Copy Function
<?php
// Example usage
$sourceFolder = '/path/to/source/folder';
$destinationFolder = '/path/to/destination/folder';
$overwrite = false; // Set to true to enable overwriting files
$copyResults = copyFolderContents($sourceFolder, $destinationFolder, true, $overwrite);
// Output results
echo "<pre>";
if ($copyResults['success']) {
echo "Successfully copied " . count($copyResults['copied_files']) . " files.\n";
echo "Copied files:\n" . implode("\n", $copyResults['copied_files']) . "\n";
} else {
echo "Errors occurred during copying:\n";
if (!empty($copyResults['failed_files'])) {
echo "Failed or skipped files:\n" . implode("\n", $copyResults['failed_files']) . "\n";
}
echo "Error details: " . $copyResults['error'] . "\n";
}
echo "</pre>";
?>
Download copy files and folder function code
Download copy functionFeatures copy files
Recursive Copying:
- Supports copying subdirectories and their contents recursively.
Error Handling:
- Detects and reports issues such as:
- Source folder not existing or not being a directory.
- Failure to create the destination folder.
- Read or write errors on files.
- Invalid destination directory.
- Detects and reports issues such as:
Customizable Behavior:
- Allows enabling/disabling recursive copying via a boolean parameter.
Overwrite Support:
- Allows users to enable or disable overwriting of files in the destination directory through the $overwrite parameter.
Detailed Logging:
- Tracks:
- Successfully copied files.
- Files that failed to copy.
- Overall operation success or failure.
- Tracks:
Path Normalization:
- Ensures source and destination paths are formatted consistently by removing trailing slashes.
Destination Directory Creation:
- Automatically creates the destination directory if it does not exist, using permissions of
0755
.
- Automatically creates the destination directory if it does not exist, using permissions of
Cross-Platform Compatibility:
- Uses
DIRECTORY_SEPARATOR
for compatibility with Windows and Unix-based systems.
- Uses
Performance Optimization:
- Skips unnecessary checks like copying
.
and..
directories. - Uses efficient merging of results from subdirectories.
- Skips unnecessary checks like copying
Usability:
- Returns a structured result array, making it easy to programmatically inspect the operation results (e.g., success status, error details, and lists of files).
Human-Readable Error Messages:
- Provides clear and specific error messages for debugging and logging purposes.
Suppression of Non-Fatal Errors:
- Suppresses warnings during file copy operations with
@copy()
to prevent unnecessary interruption of execution.
- Suppresses warnings during file copy operations with
How to Move All Files in a Folder Using PHP
The following code shows how to move all files from one folder to another:
<?php
/**
* Moves folder contents from source to destination with an overwrite option.
*
* @param string $source Source directory path
* @param string $destination Destination directory path
* @param bool $recursive Whether to move subdirectories recursively
* @param bool $overwrite Whether to overwrite existing files in the destination
* @return array Operation results with success and error details
*/
function moveFolderContents(string $source, string $destination, bool $recursive = true, bool $overwrite = true): array {
// Normalize paths to remove trailing slashes
$source = rtrim($source, '/\\');
$destination = rtrim($destination, '/\\');
// Initialize results tracking
$results = [
'success' => true,
'error' => null,
'moved_files' => [],
'failed_files' => []
];
// Validate source directory
if (!is_dir($source)) {
$results['success'] = false;
$results['error'] = "Source folder does not exist or is not a directory: $source";
return $results;
}
// Create destination folder if it doesn't exist
if (!file_exists($destination) && !mkdir($destination, 0755, true)) {
$results['success'] = false;
$results['error'] = "Cannot create destination folder: $destination";
return $results;
}
// Ensure destination is a valid directory
if (!is_dir($destination)) {
$results['success'] = false;
$results['error'] = "Destination is not a valid directory: $destination";
return $results;
}
// Read contents of the source directory
$items = scandir($source);
if ($items === false) {
$results['success'] = false;
$results['error'] = "Failed to read source folder: $source";
return $results;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$sourceItem = $source . DIRECTORY_SEPARATOR . $item;
$destinationItem = $destination . DIRECTORY_SEPARATOR . $item;
// Handle files
if (is_file($sourceItem)) {
if (!$overwrite && file_exists($destinationItem)) {
// Skip overwriting the existing file
$results['failed_files'][] = $destinationItem; // Track skipped files
continue;
}
// Move file and track the result
if (@rename($sourceItem, $destinationItem)) {
$results['moved_files'][] = $destinationItem;
} else {
$results['failed_files'][] = $sourceItem;
$results['success'] = false;
}
}
// Handle directories recursively
elseif ($recursive && is_dir($sourceItem)) {
$subResults = moveFolderContents($sourceItem, $destinationItem, true, $overwrite);
// Merge results from subdirectories
$results['moved_files'] = array_merge($results['moved_files'], $subResults['moved_files']);
$results['failed_files'] = array_merge($results['failed_files'], $subResults['failed_files']);
if (!$subResults['success']) {
$results['success'] = false;
}
}
}
// Remove the source folder after moving its contents
if ($results['success'] && is_dir($source)) {
@rmdir($source);
}
return $results;
}
?>
Usage Move Files Function
<?php
// Example usage
$sourceFolder = '/path/to/source/folder';
$destinationFolder = '/path/to/destination/folder';
$overwrite = false; // Set to true to enable overwriting files
$moveResults = moveFolderContents($sourceFolder, $destinationFolder, true, $overwrite);
// Output results
echo "<pre>";
if ($moveResults['success']) {
echo "Successfully moved " . count($moveResults['moved_files']) . " files.\n";
echo "Moved files:\n" . implode("\n", $moveResults['moved_files']) . "\n";
} else {
echo "Errors occurred during moving:\n";
if (!empty($moveResults['failed_files'])) {
echo "Failed or skipped files:\n" . implode("\n", $moveResults['failed_files']) . "\n";
}
echo "Error details: " . $moveResults['error'] . "\n";
}
echo "</pre>";
Download folder and files move function code
Download move functionFeatures Move Files
- File and Folder Handling
- Copy and move entire directory contents
- Copy and move single files
- Recursive directory traversal (with optional toggle)
- Handles nested folder structures
- Allows users to enable or disable overwriting
- Error Management
- Detailed error reporting
- Track successfully processed and failed files
- Comprehensive path validation
- Informative error messages
- Boolean success indicator
- Path and Directory Management
- Automatic destination folder creation
- Path normalization (remove trailing slashes)
- Cross-platform compatibility using
DIRECTORY_SEPARATOR
- Handle existing and non-existing directories
- Validate source and destination paths
- Flexibility and Customization
- Configurable recursive option
- Separate parameters for source and destination
- Handles various input scenarios (files, folders)
- Minimal configuration required
- Performance Considerations
- Efficient file system operations
- Minimal overhead in processing
- Use of native PHP functions (
rename()
,copy()
) - Lightweight implementation
- Result Tracking
- Returned associative array with operation details
- List of successfully moved/copied files
- List of failed files
- Overall operation success status
- Optional error message
- Safety Features
- Skip system directories (. and ..)
- Prevent overwriting without confirmation
- Robust error handling
- Cleanup of empty source directories (move function)
- Logging and Reporting
- Detailed result array for custom logging
- Easy-to-use output method
- Counts of processed files
- Ability to integrate with custom logging systems
- Permissions and Access
- Set default directory creation mode (0755)
- Implicit handling of file and directory permissions
- Silent failure with error tracking for permission issues
- Extensibility
- Modular function design
- Easy to extend or modify
- Can be integrated into larger file management systems
- Adaptable to specific project requirements