Question

Get a File Extension in PHP with pathinfo()

phpfile-extension

Question

When uploading an image in PHP, how can I retrieve only the file extension from the uploaded filename?

$userfileName = $_FILES['image']['name'];
$userfileExtn = explode('.', strtolower($_FILES['image']['name']));

The code above returns an array. Is there a way to obtain just the extension, such as jpg or png?

Short Answer

You will learn why explode() returns an array, how to extract a filename extension with PHP's pathinfo() function, and why an uploaded filename alone is not safe proof of a file's type.

Concept

A file extension is the portion of a filename after its final dot, such as jpg in photo.jpg.

explode() splits a string into multiple pieces, so PHP correctly returns an array:

$parts = explode('.', 'holiday.photo.jpg');
// ['holiday', 'photo', 'jpg']

Although you could select the final array item, PHP provides a clearer tool for this task: pathinfo().

$extension = pathinfo('holiday.photo.jpg', PATHINFO_EXTENSION);
// 'jpg'

For uploads, $_FILES['image']['name'] is the original filename supplied by the client. It is useful for display and extension-based checks, but it is not trustworthy security evidence. A malicious user can rename a non-image file to photo.jpg. Validate the actual uploaded file type before accepting it.

Mental Model

Think of a filename as a label on a box:

  • pathinfo() is a label reader that can specifically return the extension section.
  • explode() is a pair of scissors that cuts the label at every dot and hands you all of the pieces.

If you need only the final label section, pathinfo() expresses that intention directly.

Take Quiz

Syntax and Examples

Use pathinfo() with PATHINFO_EXTENSION:

$filename = $_FILES['image']['name'];
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

echo $extension;

For an uploaded file named Summer.Photo.JPEG, this prints:

jpeg

strtolower() normalizes the extension so checks work consistently regardless of capitalization.

You can also inspect all filename parts:

$info = pathinfo('uploads/summer.photo.jpg');

print_r($info);

Typical output:

Array
(
    [dirname] => uploads
    [basename] => summer.photo.jpg
    [extension] => jpg
    [filename] => summer.photo
)

The filename value keeps everything before the last dot, which is important for names such as summer.photo.jpg.

Step by Step Execution

Consider this code:

$filename = 'profile.Picture.PNG';
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

if ($extension === 'png') {
    echo 'PNG file selected';
}

Step by step:

  1. $filename stores the string profile.Picture.PNG.
  2. pathinfo($filename, PATHINFO_EXTENSION) finds text after the final dot and returns PNG.
  3. strtolower(...) converts PNG to png.
  4. The strict comparison checks whether the normalized value is exactly png.
  5. The condition is true, so PHP outputs PNG file selected.

For a filename without an extension:

$extension = pathinfo('README', PATHINFO_EXTENSION);
// '' (an empty string)

Handle this case before treating a filename as a valid upload.

Real World Use Cases

File extensions are commonly used to:

  • Choose an icon in a document manager (pdf, docx, xlsx).
  • Suggest a download filename and set a suitable file naming convention.
  • Apply a preliminary allowlist such as jpg, jpeg, png, and webp.
  • Route uploaded files to different processing pipelines, such as image resizing or CSV import.
  • Reject obvious unsupported filenames before doing more expensive processing.

For file uploads, extension checking should be one layer in a larger validation process, not the only layer.

Take Quiz

Real Codebase Usage

In production code, developers usually normalize the extension, use an allowlist, and return early when the filename does not meet basic requirements:

$filename = $_FILES['image']['name'] ?? '';
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$allowedExtensions = ['jpg', 'jpeg', 'png', 'webp'];

if ($extension === '') {
    throw new RuntimeException('The selected file has no extension.');
}

if (!in_array($extension, $allowedExtensions, true)) {
    throw new RuntimeException('Unsupported file extension.');
}

For an image upload, also inspect the file itself with finfo and, when appropriate, getimagesize():

$tmpFile = $_FILES['image']['tmp_name'];
$mimeType = (new finfo(FILEINFO_MIME_TYPE))->file($tmpFile);
$allowedMimeTypes = ['image/jpeg', 'image/png', 'image/webp'];

if (!in_array($mimeType, $allowedMimeTypes, true)) {
    throw new RuntimeException('The uploaded file is not an allowed image type.');
}

A robust upload flow also checks $_FILES['image']['error'], verifies is_uploaded_file(), generates a server-side filename, and uses move_uploaded_file(). Do not use the client-provided filename as the final storage path.

Common Mistakes

Expecting explode() to return one value

This produces an array because the filename may contain multiple dots:

$extension = explode('.', 'archive.tar.gz');

If you must use explode(), take the final element:

$parts = explode('.', 'archive.tar.gz');
$extension = strtolower(end($parts)); // gz

However, pathinfo() is clearer for extracting an extension.

Selecting a fixed array index

This fails for filenames containing additional dots:

$parts = explode('.', 'my.photo.jpg');
$extension = $parts[1]; // photo, not jpg

Use pathinfo() or the final array element instead.

Forgetting case normalization

This check rejects PHOTO.JPG:

if ($extension === 'jpg') {
    // May fail when $extension is 'JPG'
}

Normalize first:

$extension = strtolower($extension);

Trusting the extension as security validation

This is not sufficient:

if ($extension === 'jpg') {
    move_uploaded_file($tmpFile, $destination);
}

A filename can be changed by the uploader. Validate the MIME type and image contents as well.

Confusing MIME type and extension

An extension is part of a name, such as png. A MIME type describes detected content, such as image/png. They are related but not interchangeable.

Comparisons

ApproachResult for report.final.pdfBest use
pathinfo($name, PATHINFO_EXTENSION)pdfExtracting a filename extension clearly
explode('.', $name)['report', 'final', 'pdf']When every dot-separated part is needed
strrpos() with substr()pdf after manual workSpecial parsing rules, but usually unnecessary
Client MIME field: $_FILES['image']['type']Browser-provided valueDo not trust for validation
finfo(FILEINFO_MIME_TYPE)For example, image/pngServer-side content-type validation

pathinfo() is usually the best choice when the requirement is simply “get the extension.” finfo answers a different, security-focused question: “What type of content does this uploaded file appear to contain?”

Take Quiz

Cheat Sheet

// Get an extension
$extension = pathinfo($filename, PATHINFO_EXTENSION);

// Normalize it for comparisons
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

// Check an allowlist strictly
$allowed = ['jpg', 'jpeg', 'png', 'webp'];
$isAllowed = in_array($extension, $allowed, true);

// Detect actual MIME type from an uploaded temporary file
$mimeType = (new finfo(FILEINFO_MIME_TYPE))->file($_FILES['image']['tmp_name']);

Rules to remember:

  • pathinfo(..., PATHINFO_EXTENSION) returns text after the final dot.
  • A filename with no extension produces an empty string.
  • Normalize with strtolower() before comparing extensions.
  • An extension is client-controlled metadata, not proof of file content.
  • Check upload errors and validate the file's detected MIME type before storing it.

FAQ

Why does explode() return an array in PHP?

explode() is designed to split a string at every occurrence of a separator. A filename can have several dots, so it returns all resulting pieces in an array.

What is the simplest way to get a file extension in PHP?

Use pathinfo($filename, PATHINFO_EXTENSION). Apply strtolower() if you will compare the result against lowercase allowed values.

Does pathinfo() include the dot in the extension?

No. For image.png, it returns png, not .png.

What happens if the filename has multiple dots?

pathinfo('backup.2025.zip', PATHINFO_EXTENSION) returns zip. It uses the final dot.

Can I trust $_FILES['image']['name'] and its extension?

No. It comes from the uploading client and can be renamed. Use it only as metadata and validate the uploaded temporary file server-side.

How do I check whether an uploaded file is actually an image?

Use finfo to detect its MIME type and allow only expected values such as image/jpeg and image/png. For image-specific validation, getimagesize() can provide an additional check.

Should I store uploads using the original filename?

Usually no. Generate a unique server-side filename to avoid collisions, unsafe characters, and accidental overwrites.

Take Quiz

Mini Project

Description

Build a small PHP upload validator for profile images. It extracts the filename extension for a basic allowlist check, then verifies the detected MIME type so a renamed non-image file is not accepted as an image.

Goal

Accept only valid JPEG, PNG, or WebP uploads and save accepted files with generated filenames.

Requirements

Check that a file was submitted without an upload error. Extract and normalize the original filename extension with pathinfo(). Allow only jpg, jpeg, png, and webp extensions. Validate the uploaded file's detected MIME type with finfo. Save accepted files using a generated filename rather than the original name.

Take Quiz

Keep learning

Related questions

View more