SyntaxStudy
Sign Up
PHP Intermediate 10 min read

File Upload Handling

PHP makes uploaded files available via the $_FILES superglobal. Safe file upload handling requires validating type, size, and name before moving the file to its destination.

  • Check $_FILES['file']['error'] first — never proceed if it's not UPLOAD_ERR_OK.
  • Validate MIME type using finfo, not the browser-supplied type.
  • Generate a new filename; never trust the user-supplied name.
Example
<?php
function handleFileUpload(string $field, string $uploadDir): array
{
    $result = ['success' => false, 'error' => '', 'path' => ''];

    if (!isset($_FILES[$field]) || $_FILES[$field]['error'] !== UPLOAD_ERR_OK) {
        $result['error'] = 'Upload error: ' . ($_FILES[$field]['error'] ?? 'no file');
        return $result;
    }

    $file = $_FILES[$field];

    // Validate size (max 2 MB)
    if ($file['size'] > 2 * 1024 * 1024) {
        $result['error'] = 'File exceeds 2 MB limit.';
        return $result;
    }

    // Validate MIME type using finfo (not browser type)
    $finfo    = new finfo(FILEINFO_MIME_TYPE);
    $mimeType = $finfo->file($file['tmp_name']);
    $allowed  = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

    if (!in_array($mimeType, $allowed, true)) {
        $result['error'] = 'Only JPEG, PNG, GIF, and WebP images are allowed.';
        return $result;
    }

    // Generate a safe filename
    $ext      = pathinfo($file['name'], PATHINFO_EXTENSION);
    $safeName = bin2hex(random_bytes(16)) . '.' . strtolower($ext);
    $dest     = rtrim($uploadDir, '/') . '/' . $safeName;

    if (!move_uploaded_file($file['tmp_name'], $dest)) {
        $result['error'] = 'Failed to move uploaded file.';
        return $result;
    }

    $result['success'] = true;
    $result['path']    = $dest;
    return $result;
}
Pro Tip

Tip: Store uploaded files outside the web root (e.g., /var/uploads/) and serve them through a PHP script that sets the correct Content-Type header. This prevents users from uploading PHP files and executing them via the browser.