使用 php 检查文件大小和类型


Checking the file size and type using php

我的任务是制作一个php文件,用于将文件上传到目录。仅当文件大小小于 512kb 且文件类型为 txt、zip 或 jpg 时,用户才能上传文件。我的代码无法正常工作,因为如果文件不相关,它会忽略输出,并且也没有正确检查文件类型。谁能帮忙?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Files</title>
</head>
<body>

<form method="POST" enctype="multipart/form-data">
<input type="file" name="dat">
<input type="submit" value="Upload">
<div>(max. size: 512kb, Type: jpg,txt,zip)</div>
</form>
<?php
if(isset($_FILES["dat"])){
    $file=$_FILES["dat"];
    $name=$file["name"];
    $size=$file["size"];
    $location=$file["tmp_name"];
    $location_file=$location . basename($name);

    if($size>512000 or $location_file!="txt" or $location_file!="zip" or $location_file!="jpg"){
        echo "The file is too big or the format is not correct...";
    }
    else{
        move_uploaded_file($location,"files/".$name);
    }
}
?>
</body>
</html>

在 html 端

<input type="file" name="dat" accept=".txt, .zip, .jpg">

在服务器端:

<?php
$extension = array_pop(explode(".", $_FILES["dat"]["name"])); // return file extension
if(in_array($extension, array("zip", "txt", "jpg"))) // check if extension is valid
{
   if($_FILES['dat']['size'] > 512*1024) // check file size is above limit
   {
       echo "File size above limit";
   }
   else
   {
       move_uploaded_file($_FILES['dat']['tmp_name'],"files/".$_FILES['dat']['name']); // moving uploaded file
   }
}
else
{
  echo "Invalid file type";
}

首先尝试调试您上传的文件。其次,不要依赖文件名,因为它很容易被欺骗。tmp_name为您提供文件的临时位置,这将是一个随机字符串。您最好的选择是在tmp_name上调用getimagesize,对于图像,finfo_opennew finfo其他文件类型以比较其 MIME 类型,您还可以explode名称并使用end这也将为您提供扩展名。也许定义一个接受扩展的数组,并使用in_array来检查扩展是否有效。将提供我到达PC后的示例代码。

LE:正如承诺的那样,使用注释和安全概念进行更复杂的检查

<?php
// you can make sure you have every variable set
// then procced further
if(
    isset(
        $_FILES['dat'], $_FILES['dat']['tmp_name'],
        $_FILES['dat']['name'], $_FILES['dat']['size'],
        $_FILES['dat']['error']
    )
){
    $accepted = array(
        'image/jpeg'      => 'jpg',
        'text/plain'      => 'txt',
        'application/zip' => 'zip',
    );
    $file      = $_FILES['dat'];
    $maxSize   = 512 * 1024; // 512 KB
    // check if any upload error occured
    if( UPLOAD_ERR_OK !== $file['error'] ){
        // http://php.net/manual/en/features.file-upload.errors.php
        echo 'Upload error: ', $file['error'], '<br/>';
    // check if file size is bigger than $maxSize
    } elseif( $file['size'] > $maxSize ){
        // if filesize is bigger than upload_max_filesize directive in php.ini
        // script may timeout without any error
        // post_max_size and upload_max_filesize need to be high enough
        echo 'Error: File size is to big!<br/>';
    // can proceed further
    } else {
        // you will need to have the fileinfo enabled in php ini to use these
        $finfo    = finfo_open( FILEINFO_MIME );
        $mime     = finfo_file( $finfo, $file['tmp_name'] );
        // finfo may give you charset info as well
        // text/plain; charset=utf-8 or image/jpeg; charset=binary
        $mime     = array_shift( explode( ';', $mime ) );
        // change uploaded file name do to security reasons
        // google "php null char upload"
        // nice read http://resources.infosecinstitute.com/null-byte-injection-php/
        $filename = md5( time() . $file['name'] ) . '.';
        // if mime is accepted
        if( ! array_key_exists( $mime, $accepted ) /* or use isset: ! isset( $accepted[ $mime ] ) */ ){
            echo 'Error: Unsupported file type!<br/>';
        // you could check if file is image and check min-max width & height
        // for now move the uploaded file
        } elseif( ! @move_uploaded_file( $file['tmp_name'], 'files/' . $filename . $accepted[ $mime ] ) ){
            echo 'Unable to save uploaded image to <strong>',
                htmlspecialchars( 'files/' . $filename . $accepted[ $mime ] ),
            '</strong>';
        } else {
            echo '<a href="files/', htmlspecialchars( $filename . $accepted[ $mime ] ), '" target="_blank">',
                htmlspecialchars( $filename . $accepted[ $mime ] ),
            '</a>';
        }
    }
}

对于格式,您需要像这样从文件名中删除扩展名:

$explode = explode(".", $name);
$extension = $explode[sizeof($explode)-1]; //return "txt", "zip" or whatever
if(!in_array($extension, ["zip","txt", "jpg", "jpeg"])){
    //format error: not in correct format
} else {
    //format OK
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($finfo, $_FILES['dat']['tmp_name']);
    $allowed_mime_types = [
        "image/jpg",
        "image/jpeg",
        "application/zip",
        "plain/text"
    ];
    if(!in_array($mime, $allowed_mime_types)){
        //error format
    } else {
        //format OK
    }
}