【问题标题】:Severe fileinfo issues严重的文件信息问题
【发布时间】:2012-05-09 17:29:23
【问题描述】:

我在共享主机上,并且一直在与他们争夺文件信息的工作,我们终于让它工作了,但我又遇到了另一个障碍,我基本上得到了这个,因为我正在创建一个新的文件上传工具,我们需要知道正在上传哪些 mimetype,但 fileinfo 不想玩球。

因此,.sql 文件将返回 text/plain,正确。

但是,所有其他文件都会简单地返回 application/octet-stream,我想知道为什么会这样,我不想用大量问题惹恼主持人,所以我想进行一些研究在我进一步麻烦他们之前就这个问题。

代码:

function get_mime($filename)
{
    $result = new finfo(FILEINFO_MIME_TYPE, "/usr/share/file/magic.mime"); 
    return $result->file($filename, FILEINFO_MIME_TYPE);
}

echo $user->get_mime($_FILES['file']['tmp_name'][$i]);

任何帮助将不胜感激,非常感谢

更新

所以我已经开始更新 MIMETYPE 检查的代码,并且我已经更新了代码以反映以下内容(对于函数):

function get_mime($filename)
{
    $result = new finfo(FILEINFO_MIME_TYPE, "/usr/share/file/magic.mime"); // return mime type ala mimetype extension

    if (is_resource($result) === true)
    {
        return $result->file($filename, FILEINFO_MIME_TYPE);
    } else {
        return "failed";
    }

    return false;
}

显然,如您所见,当它失败时,我已将其输出 failed。这种情况 100% 发生,并且删除该 if 语句会导致它返回 application/octet-stream,这是不正确的。

上传过程将是:用户上传 -> 文件被移动到公共以上的临时文件夹,(upload_check)将由fileinfo检查文件,如果文件不是我们接受的文件,将被丢弃,否则将被复制到公共文件,然后从临时文件夹中丢弃。

我已经创建了该进程,但 fileinfo 仍然不想合作并为所有内容返回 application/octet-stream,即使它们位于刚刚保存在 public_html 文件夹上方的服务器上。

有什么建议吗?

杰克

【问题讨论】:

    标签: php mime fileinfo


    【解决方案1】:

    建议

    我真的认为你在这里搞错了......

    A.上传文件时,它还会在$_FILES 中自动返回mime type

    echo $_FILES['file']['type'][$i] ;
    

    B 如果您想为未上传的文件获取 mime,或者尝试更好地确定客户端标头提供的内容,请使用 mime_content_type http://php.net/manual/en/function.mime-content-type.php

    echo mime_content_type($fileName);
    

    C.折旧

    mime_content_typeFileinfo 均未得到妥善维护,已折旧。

    更新:它曾经在手册中被错误地标记为已弃用,但已在 2016 年 1 月 14 日修复https://bugs.php.net/bug.php?id=71367。可以看到支持 7.0,因此根本没有停止。

    或者可以建议你看看下面的链接进行替换

    Getting mime type of zipped files

    http://www.php.net/manual/en/function.mime-content-type.php#87856

    D.你也可以使用getID3http://sourceforge.net/projects/getid3/files/getID3%28%29%201.x/1.9.3/,它可以检查一些常见文件的真实mime类型......

    E.使用 Linux 命令行可能更节省

    $mime = shell_exec("file -bi " . escapeshellarg($file));   
    

    或者在 Mac 上

    $mime = shell_exec("file -b --mime ".escapeshellarg($file));
    

    最后

    为什么要直接在$_FILES['file']['tmp_name'][$i] 上工作??众所周知,这会带来很多问题

    试试

    $tempDir = ""; // Temp
    foreach ( $_FILES ["file"] ["error"] as $key => $error ) {
        if ($error == UPLOAD_ERR_OK) {
            $tmp_name = $_FILES ["file"] ["tmp_name"] [$key];
            $name = $_FILES ["file"] ["name"] [$key];
            $tempFile = "$tempDir/$name";
            move_uploaded_file ( $tmp_name, $tempFile );
            echo $user->get_mime ( $tempFile );
            unlink ( $tempFile );
    
        }
    }
    

    【讨论】:

    • 您好,感谢您的评论。我完全了解您来自哪里,现在我也知道我哪里出错了,我目前正在编写一个上传器,允许我定义允许的扩展名和文件类型,我知道 $_FILES 将返回 MIMETYPE,但它很容易被愚弄(即将打印“Hello World”保存到带有 php 标签的 jpeg 中,它将返回“image/jpeg”。我正在编写一个安全上传器,我想选择上传哪些文件,但是我猜测它将创建一个允许所有文件类型的平台,因为这似乎几乎是不可能的
    • 获取 $_FILES 数组中任何给定文件的正确和真实 MIMETYPE。感谢您的评论
    • 嘿@Baba,感谢您的深入回复。您基本上已经准确概述了我打算做什么,我将临时文件移动到一个文件夹,然后我将在其中调用 finfo 函数以获取真实的,或者更好地了解 MIMETYPE,然后确定文件是否已上传到公共服务器或从服务器丢弃。我已经开始将文件移动到临时文件夹,但是导致问题的是文件信息,它仍然存在“失败”,我已经更新了我的帖子以反映这一点。
    • 如果您只打算使用图像,请使用 getimagesize ...它会告诉您它是否是有效的图像、高度、宽度并返回 mime 类型
    • @Baba,你说“mime_content_type 和 Fileinfo 都没有得到适当的维护,它们已经被贬值了”。您能否提供引用,因为我认为这是不正确的。也许您的意思是曾经是依赖项的“魔术文件”垃圾?
    【解决方案2】:

    您应该检查您尝试使用的魔术文件是否存在并且可以被php读取。

    试试:

    $finfo = finfo_open(FILEINFO_MIME, "/usr/share/file/magic.mime");
    
    if (!$finfo) {
        echo "Opening fileinfo database failed";
        exit();
    }
    
    finfo_close($finfo);
    

    【讨论】:

    • 嘿,是的,它可以被读取并且文件路径已被主机确认。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2020-01-13
    相关资源
    最近更新 更多