PHP Fileinfo reports the content type of a JPEG image as image/jpeg, while its filename may end in .jpg or .jpeg. Do not compare the MIME subtype directly with one extension. Define the valid mapping explicitly and verify both values.
Last updated: October 1, 2026.
<?php
$allowed = [
'image/jpeg' => ['jpg', 'jpeg'],
'image/png' => ['png'],
];
$file = $_FILES['image'] ?? null;
if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
throw new RuntimeException('The upload did not complete.');
}
$mime = (new finfo(FILEINFO_MIME_TYPE))->file($file['tmp_name']);
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!isset($allowed[$mime]) ||
!in_array($extension, $allowed[$mime], true)) {
throw new RuntimeException('Unsupported image type.');
}
$name = bin2hex(random_bytes(16)) . '.' . $extension;
$destination = __DIR__ . '/uploads/' . $name;
if (!move_uploaded_file($file['tmp_name'], $destination)) {
throw new RuntimeException('Could not store the upload.');
}Fileinfo examines the temporary file’s contents. pathinfo() reads the user-supplied filename, so the extension is supporting policy information rather than proof of file type.
Why image/jpeg and .jpg are both correct
MIME types and filename extensions are different naming systems. The PHP finfo_file() documentation shows that FILEINFO_MIME_TYPE returns values such as image/jpeg. PHP’s Fileinfo constants also note that JPEG can correspond to several extensions.
Use the upload error value before touching the temporary path, impose an application size limit, and generate the stored basename yourself. Keep the upload directory non-executable and outside the public document root when files do not need direct access.
Treat successful validation as one pipeline stage
Image decoding or re-encoding can provide another useful check when the application already creates thumbnails, but it does not replace size, authorization, storage, and output controls. For the complete flow, use the secure upload pipeline, review the focused PHP upload example, and clean abandoned temporary data with the temporary-file guide.