Safely upload a file

Dani 1 Tallied Votes 35 Views Share

Here's a quick bit of code to upload a file in PHP.

rproffitt commented: I always liked little Johnny Drop Tables. +17
// We start out by setting this to false,
// and we'll change it to true if the upload is successful
$upload_successful = false;

// If it's a POST request (e.g. we are submitting a form)
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
    // If the form included a file upload called "upload"
    if (isset($_FILES['upload']))
    {    
        // If the file was uploaded without error
        if ($_FILES['upload']['error'] === UPLOAD_ERR_OK)
        {
            // The temporary location the file was uploaded to (e.g. in /tmp)
            $tmpPath = $_FILES['upload']['tmp_name'];

            // The "trailing name component of a path"
            // We do this to prevent filesystem traversal attacks
            $filename = basename($_FILES['upload']['name']);
    
            // Create an array of allowed MIME types
            $allowedTypes = [
                'image/jpeg',
                'image/png',
                'application/gif'
            ];

            // Get the MIME type of the file that was uploaded
            $finfo = new finfo(FILEINFO_MIME_TYPE);
            $mime = $finfo->file($tmpPath);

            // If the MIME type of the file is in the array of allowed MIME types
            if (in_array($mime, $allowedTypes))
            {
                // Create a safe name for the file by stripping all characters other than alphanumeric and .-_
                $safeName = preg_replace('/[^a-zA-Z0-9\._-]/', '_', $filename);

                // Make sure a file with this name doesn't already exist
                if (!file_exists( __DIR__ . "/uploads/{$safeName}"))
                {    
                    // The move_uploaded_file() built-in PHP function moves uploaded files to their permanent location
                    if (move_uploaded_file($tmpPath, __DIR__ . "/uploads/{$safeName}") === true)
                    {
                        $upload_successful = true;
                    }
                }
            }
        }
    }
}
Dani 4,675 The Queen of DaniWeb Administrator Featured Poster Premium Member

I realize I could have done better when coming up with a safe name. As it stands, a file uploaded that has a file name in non-Latin characters will just end up with a bunch of underscores. I’m not even sure if that suffices as a file name, but for sure there will be collisions as multiple files are attempting to be saved with the same _ name.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.