PHP - 通过$ _FILES循环检查文件类型

时间:2009-07-17 14:11:50

标签: php file-upload loops

关于SO的第一个问题,谢谢。 :)

我正在为我的公司开发支持问题日志系统,它必须允许上传文件以及提交到我们数据库的任何问题。 可能有0-6个不同的上传要检查,以及支持问题。通过一个隐藏的输入字段(imgcount),无论何时通过type =“file”输入选择图像,或从表单中删除,都可以通过js更新,从而设法得到一个准确的变量。

我的[input type =“file”]名称是image1,image2等。正如我认为这样循环它们会更容易。

提交表单时,以下代码会查看是否有任何文件并检查它们是否为有效类型(gif / jpeg / png),以便可以安全地上载它们。我不太担心病毒,因为支持系统有一个很好的安全登录,我们相信我们的客户。

$sscount = $_POST['imgcount'];
echo $sscount; //to test the variable
if($sscount>0){
    for($i = 1; $i <= $sscount; $i++){
        if (($_FILES["image$i"]["type"] == "image/gif")
        || ($_FILES["image$i"]["type"] == "image/jpeg")
        || ($_FILES["image$i"]["type"] == "image/png" )
        && ($_FILES["image$i"]["size"] < 500000))
        {

        }
        else
        {
        $errormsg .= "Error: Image $i must be either JPEG, GIF, or PNG and less than 500 kb.<br />";
        }
    }
}

但是这似乎没有正确地循环,任何人都有任何想法如何让它循环并正确返回?

7 个答案:

答案 0 :(得分:9)

&amp;&amp;运算符的precedence高于||,所以不是(A OR B OR C) AND D,而是A OR B OR (C AND D)实际上$allowed_types=array( 'image/gif', 'image/jpeg', 'image/png', ); $sscount = $_POST['imgcount']; if($sscount>0){ for($i = 1; $i <= $sscount; $i++){ if (in_array($_FILES["image$i"]["type"], $allowed_types) && ($_FILES["image$i"]["size"] < 500000)) { } } }

您可以使用括号来强制执行您想要的评估。

然而,这样的事情可能更清洁,更容易维护/阅读:

{{1}}

答案 1 :(得分:5)

这不是您问题的直接答案,但您可以将表单值作为数组传递给PHP,这应该更容易循环。 in_array()对于检查值是否在允许列表中也很有用。

HTML:

<input type="file" name="image[]">
<input type="file" name="image[]">
<input type="file" name="image[]">
<input type="file" name="image[]">

PHP:

<?php
if (isset($_FILES['image'])) {
    foreach ($_FILES['image'] as $file) {
        if (!in_array($file['type'], array("image/gif", "image/jpeg", "image/png"))
           || $file['size'] > 500000) {
           //error
        } else {
           //ok
        }
    }
}

答案 2 :(得分:4)

正如其他人所提到的,你对条件进行分组的方式是错误的。但是,我建议你完全分开这两个条件,而不是简单地添加一些括号;

// this declaration + the use of in_array() isn't necessary,
// it just makes things a bit cleaner.
$file_types = array("image/gif","image/jpeg","image/png"); 

if($_FILES["image$i"]["size"] < 500000)
{
    if(in_array($_FILES["image$i"]["type"], $file_types)))
    {
        // do stuff
    }
    else
    {
        // error about file type
    }
}
else
{
    // error about file size
}

这种分离使代码更具可读性,并且更容易建议条件层次结构,加上它可以使您的错误消息更有意义。将不同类型的条件语句分开是一种很好的做法,这样任何错误消息都仍然有用。如果您的代码错误,用户无法知道(无需了解自己)他们的图片是太大还是错误的类型。

答案 3 :(得分:2)

嗯,你的布尔逻辑是模棱两可的,可能没有做你想要的。这可能会更好:

    if ((($_FILES["image$i"]["type"] == "image/gif")
    || ($_FILES["image$i"]["type"] == "image/jpeg")
    || ($_FILES["image$i"]["type"] == "image/png" ))
    && ($_FILES["image$i"]["size"] < 500000))

虽然如果我有我的druthers,整个事情看起来像:

    $file = $_FILES['image' . $i];
    $type = $file['type'];
    if(($type == 'image/gif' || $type == 'image/jpeg' || $type == 'image/png') && $file['size'] < 500000)

答案 4 :(得分:2)

我认为你真的不需要通过Javascript更新的变量。您可以使用PHP计算checking the error code上传的文件数量。您也可以通过检查文件扩展名来处理文件上传,因为不同的浏览器通常可以发送不同的MIME类型。以下是我所说的一个例子:

$accepted_files = array(
    'jpg',
    'png',
    'gif',
    'jpeg'
);

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    foreach($_FILES as $key => $upload) {
        if ($upload['error'] == 0) {
            $file_parts = explode ('.',$upload['name']);
            if (in_array($file_parts[sizeof($file_parts)-1], $accepted_files)) {
                // This type of file is a-ok
            }
            else {
                // Not an accepted file type
            }
        }
    }
}   

答案 5 :(得分:0)

我认为你的if条件错了。你需要在OR的第一组布尔值周围使用括号,如下所示:

   if ( (($_FILES["image$i"]["type"] == "image/gif")
    || ($_FILES["image$i"]["type"] == "image/jpeg")
    || ($_FILES["image$i"]["type"] == "image/png" ))
    && ($_FILES["image$i"]["size"] < 500000))

这恰当意味着“如果文件是(gif或jpeg或png)的图像并且小于该尺寸”。

之前的方式可能不是你想要的逻辑。

答案 6 :(得分:0)

您可以组合所有['type'] == x || ['type'] == y只需拨打一次in_array($_FILES[...]['type'], $allowed)>

即可

$ _ FILES [..] ['type']包含客户端发送的数据,既不会被PHP检查也不会被清理。如果文件的类型具有任何相关性,则不依赖于$ _FILES [..] ['type']或$ _FILES [..] ['name']的后缀。 只有实际的内容很重要。如果需要,您可以使用the fileinfo extensionmime_content_type()对其进行测试(标记为已弃用,以支持fileinfo)