PHP:如何正确检查文件的 MIME 类型?

emm*_*mea 2 php mime

我有一个输入,您可以在其中上传图像,唯一允许的图像类型是:

png, jpg, jpeg
Run Code Online (Sandbox Code Playgroud)

在将图像插入数据库之前,它会检查图片是否为 png、jpg、jpeg。但现在出于安全原因,我需要在第一次检查之前或之后检查 MIME 类型。

我该怎么做呢?这是我的代码:

<?php

$iAmountOfFiles = count($_FILES['Filename']['name']);

while($iAmountOfFiles >= 1) {

    $iAmountOfFiles--;

    $aFileProperties = pathinfo($_FILES['Filename']['name'][$iAmountOfFiles]);
    if(!in_array(strtolower($aFileProperties["extension"]), $aExtensionWhitelist)) {
        echo "Bestands type niet toegestaan";
        // exit;
        continue;
    }

    $sTarget = ROOT.BACKEND."/pages/bezienswaardigheden-toevoegen/uploads/";
    $sUniqueFileNameHash = hash('adler32', time().rand());
    $Filename = basename($sUniqueFileNameHash."-".$_FILES['Filename']['name'][$iAmountOfFiles]);
    $Filename = basename($aFileProperties["filename"]."-".$sUniqueFileNameHash.".".strtolower($aFileProperties["extension"]));

    // Writes the Filename to the server
    if(move_uploaded_file($_FILES['Filename']['tmp_name'][$iAmountOfFiles], $sTarget.$Filename)) {

    // here needs to come the mime check
Run Code Online (Sandbox Code Playgroud)

unc*_*exo 6

要获得 MIME 类型,开发人员通常依赖于$_FILE['input_name']['type']. 但这绝对是脆弱的。因为恶意用户可以设置之一image/jpgimage/pngimage/gif等等MIME类型的文件,它是不实际的图像。在这种情况下,恶意用户可能会获取您的脚本传递以上传其他文件而不是图像并为他们的目的执行您的脚本,这是危险的。

因此,我建议您不要依赖以下代码段来获取文件的 MIME

$_FILE['input_name']['type'];
Run Code Online (Sandbox Code Playgroud)

相反,我建议使用此mime_content_type()函数来获取 MIME 类型,但要借助其他 PHP 的内置函数。这就是is_uploaded_file()功能。它的作用是:

这有助于确保恶意用户没有试图欺骗脚本处理它不应该处理的文件——例如,/etc/passwd。

如果对上传的文件所做的任何操作可能会向用户甚至同一系统上的其他用户透露其内容,则此类检查尤其重要。

所以为了使这个函数正常工作,它需要一个特定的参数。看看下面的代码:

if (is_uploaded_file($_FILE['input_name']['tmp_name'])) {
    // do other stuff
}
Run Code Online (Sandbox Code Playgroud)

此函数true在成功时返回,false否则返回。因此,如果它返回,true那么您就可以处理该文件。感谢这个功能。现在mime_content_type()功能开始发挥作用。如何?看看下面的代码:

if (is_uploaded_file($_FILE['input_name']['tmp_name'])) {
    // Notice how to grab MIME type
    $mime_type = mime_content_type($_FILE['input_name']['tmp_name']);

    // If you want to allow certain files
    $allowed_file_types = ['image/png', 'image/jpeg', 'application/pdf'];
    if (! in_array($mime_type, $allowed_file_types)) {
        // File type is NOT allowed
    }

    // Set up destination of the file
    $destination = '/path/to/move/your/file/';

    // Now you move/upload your file
    if (move_uploaded_file ($_FILE['input_name']['tmp_name'] , $destination)) {
        // File moved to the destination
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,对于新手,不要尝试使用此功能的远程 url 来获取 MIME 类型。下面的代码将不起作用:

mime_content_type('http://www.example.com/uploads/example.png');
Run Code Online (Sandbox Code Playgroud)

但是下面的一个会起作用:

mime_content_type('/source/to/your/file/etc.png');
Run Code Online (Sandbox Code Playgroud)

希望您从现在开始喜欢上传文件。