What are best practices for handling file uploads securely in PHP applications?

When handling file uploads in PHP applications, it is crucial to validate file types, limit file sizes, and store files outside of the web root directory to prevent direct access. Additionally, renaming uploaded files and using secure upload directories can help enhance security.

// Check if file was uploaded without errors
if(isset($_FILES['file']) && $_FILES['file']['error'] == 0){
    $file_name = $_FILES['file']['name'];
    $file_tmp = $_FILES['file']['tmp_name'];
    
    // Validate file type
    $allowed_extensions = array('jpg', 'jpeg', 'png', 'pdf');
    $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);
    if(!in_array($file_extension, $allowed_extensions)){
        die('Invalid file type. Allowed file types: jpg, jpeg, png, pdf');
    }
    
    // Limit file size
    if($_FILES['file']['size'] > 5000000){
        die('File is too large. Max file size is 5MB');
    }
    
    // Move uploaded file to secure directory
    $upload_dir = 'uploads/';
    $new_file_name = uniqid() . '_' . $file_name;
    if(move_uploaded_file($file_tmp, $upload_dir . $new_file_name)){
        echo 'File uploaded successfully!';
    } else {
        echo 'Error uploading file.';
    }
} else {
    die('Error uploading file.');
}