Skip to content
← Back to Functions
Code

Mime Type Policy Checker

Checks whether a file path and detected MIME type match allowed site policies.

Function signature

ogCheckMimeTypePolicy(file_path, allowed_mimes = array(), options = array())

Categories

  • File and Upload Safety

Parameters

file_pathFilesystem path supplied for inspection or planning.allowed_mimesStructured allowed mimes data supplied by the caller.optionsOptional policy, formatting, or behavior controls for this helper. Recognized keys: `allowed_extensions`, `max_bytes`.

Return value

Public-safe status string returned by the function.

  • success
  • message
  • data

Compatibility

Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.

Minimum PHP version: 7.4

Security notes

Use caller-owned allowlists and procedural mysqli prepared execution where SQL plans are returned; validate file paths, MIME policies, and permissions before file or download workflows.

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

/**
 * Checks whether a file path and detected MIME type match allowed site policies.
 *
 * Primary use case: Uploads and static asset serving.
 * Typical inputs: file path, detected MIME, policy.
 * Typical output: valid/invalid result.
 *
 * Implementation note: Do not trust extensions alone.
 *
 * @return array Structured result data with success, message, and data keys.
 */
function ogCheckMimeTypePolicy($file_path, $allowed_mimes = array(), $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$file_path = (string)$file_path;
	if (!is_array($allowed_mimes)) {
		$allowed_mimes = array();
	}
	if (!is_array($options)) {
		$options = array();
	}
	if (empty($allowed_mimes)) {
		$allowed_mimes = array('image/jpeg', 'image/png', 'image/webp', 'text/plain', 'text/csv', 'application/pdf');
	}

	$real_path = realpath($file_path);
	if ($real_path === false || !is_file($real_path) || is_link($real_path)) {
		$result['message'] = 'File path is invalid.';
		return $result;
	}

	$max_bytes = 20971520;
	if (!empty($options['max_bytes'])) {
		$max_bytes = (int)$options['max_bytes'];
	}
	$size = filesize($real_path);
	if ($size === false || $size > $max_bytes) {
		$result['message'] = 'File is too large or unreadable.';
		return $result;
	}

	$detected_mime = '';
	if (function_exists('finfo_open')) {
		$finfo = finfo_open(FILEINFO_MIME_TYPE);
		if (!empty($finfo)) {
			$detected_mime = finfo_file($finfo, $real_path);
			finfo_close($finfo);
		}
	}
	if (empty($detected_mime)) {
		$detected_mime = 'application/octet-stream';
	}

	$extension = strtolower(pathinfo($real_path, PATHINFO_EXTENSION));
	$allowed_extensions = array();
	if (!empty($options['allowed_extensions']) && is_array($options['allowed_extensions'])) {
		foreach ($options['allowed_extensions'] as $allowed_extension) {
			$allowed_extensions[] = strtolower(trim((string)$allowed_extension, '. '));
		}
	}

	if (!empty($allowed_extensions) && !in_array($extension, $allowed_extensions, true)) {
		$result['message'] = 'File extension is not allowed.';
		$result['data'] = array('mime' => $detected_mime, 'extension' => $extension);
		return $result;
	}
	if (!in_array($detected_mime, $allowed_mimes, true)) {
		$result['message'] = 'MIME type is not allowed.';
		$result['data'] = array('mime' => $detected_mime, 'extension' => $extension);
		return $result;
	}

	$result['success'] = true;
	$result['message'] = 'File MIME policy passed.';
	$result['data'] = array(
		'path' => $real_path,
		'mime' => $detected_mime,
		'extension' => $extension,
		'bytes' => (int)$size
	);

	return $result;
}