Skip to content
← Back to Snippets
Code

Check if a File Exists

Checks whether a relative file exists under an approved base directory and rejects traversal-style paths.

Purpose

Checks whether a relative file exists under an approved base directory and rejects traversal-style paths.

Snippet details

ContextFilesystemLevelProductionCopy-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.
 */

/**
 * Check if a File Exists.
 *
 * Purpose:
 * Checks a relative file path under a known base directory without allowing
 * absolute paths or parent-directory traversal.
 *
 * @param string $base_directory Approved base directory.
 * @param string $relative_file Relative file path to check.
 * @return array File existence status and basic file details.
 */
function ogSnippetCheckIfFileExists(string $base_directory, string $relative_file): array {
	$base_real = realpath($base_directory);
	$relative_file = trim($relative_file);

	if ($base_real === false || is_dir($base_real) === false) {
		return array('exists' => false, 'path' => '', 'size_bytes' => 0, 'message' => 'Base directory is invalid.');
	}

	if ($relative_file === '' || substr($relative_file, 0, 1) === '/' || strpos($relative_file, '..') !== false) {
		return array('exists' => false, 'path' => '', 'size_bytes' => 0, 'message' => 'Relative file path is invalid.');
	}

	$target_path = $base_real.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $relative_file);
	$target_real = realpath($target_path);

	if ($target_real === false || strpos($target_real, $base_real.DIRECTORY_SEPARATOR) !== 0) {
		return array('exists' => false, 'path' => $target_path, 'size_bytes' => 0, 'message' => 'File does not exist inside the approved directory.');
	}

	if (is_file($target_real) === false) {
		return array('exists' => false, 'path' => $target_real, 'size_bytes' => 0, 'message' => 'Path exists but is not a file.');
	}

	return array(
		'exists' => true,
		'path' => $target_real,
		'size_bytes' => filesize($target_real),
		'message' => 'File exists.'
	);
}

/*
$result = ogSnippetCheckIfFileExists(__DIR__.'/data', 'reports/enterprise-ncc-1701.txt');
print_r($result);
*/