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.
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 dot, which is important for names such as .
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:
$filenamestores the stringprofile.Picture.PNG.pathinfo($filename, PATHINFO_EXTENSION)finds text after the final dot and returnsPNG.strtolower(...)convertsPNGtopng.- The strict comparison checks whether the normalized value is exactly
png. - The condition is true, so PHP outputs
PNG file selected.
For a filename without an extension:
$extension = pathinfo('README', PATHINFO_EXTENSION);
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, andwebp. - 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.
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[][];
= ( (FILEINFO_MIME_TYPE))->();
= [, , ];
(!(, , )) {
();
}
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.
Comparisons
| Approach | Result for report.final.pdf | Best use |
|---|---|---|
pathinfo($name, PATHINFO_EXTENSION) | pdf | Extracting a filename extension clearly |
explode('.', $name) | ['report', 'final', 'pdf'] | When every dot-separated part is needed |
strrpos() with substr() | pdf after manual work | Special parsing rules, but usually unnecessary |
Client MIME field: $_FILES['image']['type'] | Browser-provided value | Do not trust for validation |
finfo(FILEINFO_MIME_TYPE) |
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 and . For image-specific validation, can provide an additional check.
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.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.