Skip to content
← Back to Snippets
Code

Read a File with file_get_contents

Reads a file with `file_get_contents()` after resolving it against an approved base directory and rejecting traversal attempts.

Purpose

Reads a file with `file_get_contents()` after resolving it against an approved base directory and rejecting traversal attempts.

Snippet details

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

/**
 * Read a File with file_get_contents.
 *
 * Purpose:
 * Reads a file from an approved base directory without allowing path traversal
 * or arbitrary server file reads.
 *
 * @param string $base_directory Approved directory root.
 * @param string $relative_path File path relative to the approved root.
 * @return array Read status, public message, and file contents when successful.
 */
function ogSnippetReadAFileWithFileGetContents(string $base_directory, string $relative_path): array {
	$base_directory = rtrim($base_directory, DIRECTORY_SEPARATOR);
	$relative_path = ltrim(trim($relative_path), DIRECTORY_SEPARATOR);

	if ($base_directory === '' || $relative_path === '') {
		return array('success' => false, 'message' => 'Base directory and relative file path are required.', 'contents' => '');
	}

	if (strpos($relative_path, '..') !== false) {
		return array('success' => false, 'message' => 'Relative file path rejected.', 'contents' => '');
	}

	$full_path = $base_directory.DIRECTORY_SEPARATOR.$relative_path;
	$real_base = realpath($base_directory);
	$real_file = realpath($full_path);

	if ($real_base === false || $real_file === false) {
		return array('success' => false, 'message' => 'File was not found.', 'contents' => '');
	}

	if (strpos($real_file, $real_base.DIRECTORY_SEPARATOR) !== 0) {
		return array('success' => false, 'message' => 'File is outside the approved directory.', 'contents' => '');
	}

	if (is_readable($real_file) === false) {
		return array('success' => false, 'message' => 'File is not readable.', 'contents' => '');
	}

	$contents = file_get_contents($real_file);

	if ($contents === false) {
		return array('success' => false, 'message' => 'File read failed.', 'contents' => '');
	}

	return array(
		'success' => true,
		'message' => 'File read completed.',
		'contents' => $contents
	);
}

$result = ogSnippetReadAFileWithFileGetContents(__DIR__, 'stargate-mission-note.txt');

if ($result['success'] === true) {
	echo $result['contents'];
} else {
	echo $result['message'];
}