Rename or Move a File
Renames or moves a file inside an approved base directory after checking the source file, destination directory, overwrite rule, and path boundaries.
Purpose
Renames or moves a file inside an approved base directory after checking the source file, destination directory, overwrite rule, and path boundaries.
Snippet details
ContextFileLevelPracticalCopy-and-paste statusMarked safe after review.Categories
- Forms and Validation
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Rename or Move a File.
*
* Purpose:
* Moves a file from one approved path to another with explicit base-directory
* checks and an overwrite option.
*
* @param string $base_directory Directory that must contain the source and destination.
* @param string $source_file Existing source file path.
* @param string $destination_file Destination file path.
* @param bool $allow_overwrite Whether an existing destination may be replaced.
* @return array Move result with message and paths.
*/
function ogSnippetRenameOrMoveAFile(string $base_directory, string $source_file, string $destination_file, bool $allow_overwrite): array {
$base_real = realpath($base_directory);
$source_real = realpath($source_file);
$destination_directory = dirname($destination_file);
$destination_directory_real = realpath($destination_directory);
if ($base_real === false) {
return array(
'moved' => false,
'message' => 'Base directory was not found.',
'source' => '',
'destination' => ''
);
}
if ($source_real === false || is_file($source_real) === false) {
return array(
'moved' => false,
'message' => 'Source file was not found.',
'source' => '',
'destination' => ''
);
}
if ($destination_directory_real === false) {
return array(
'moved' => false,
'message' => 'Destination directory was not found.',
'source' => $source_real,
'destination' => ''
);
}
if (strpos($source_real, $base_real.DIRECTORY_SEPARATOR) !== 0) {
return array(
'moved' => false,
'message' => 'Source file is outside the approved base directory.',
'source' => $source_real,
'destination' => ''
);
}
if (strpos($destination_directory_real, $base_real.DIRECTORY_SEPARATOR) !== 0 && $destination_directory_real !== $base_real) {
return array(
'moved' => false,
'message' => 'Destination is outside the approved base directory.',
'source' => $source_real,
'destination' => $destination_file
);
}
if (file_exists($destination_file) === true && $allow_overwrite === false) {
return array(
'moved' => false,
'message' => 'Destination file already exists.',
'source' => $source_real,
'destination' => $destination_file
);
}
$moved = rename($source_real, $destination_file);
if ($moved === false) {
return array(
'moved' => false,
'message' => 'File move failed.',
'source' => $source_real,
'destination' => $destination_file
);
}
return array(
'moved' => true,
'message' => 'File moved.',
'source' => $source_real,
'destination' => $destination_file
);
}
$stargate_base = sys_get_temp_dir().'/phpog-stargate-file-move';
if (is_dir($stargate_base) === false) {
mkdir($stargate_base, 0755, true);
}
$source_path = $stargate_base.'/incoming-report.txt';
$destination_path = $stargate_base.'/archived-report.txt';
file_put_contents($source_path, 'SG-1 mission report');
$move_report = ogSnippetRenameOrMoveAFile($stargate_base, $source_path, $destination_path, false);
echo $move_report['message'];