用户
 找回密码
 入住 CI 中国社区
搜索
查看: 9910|回复: 6
收起左侧

[图片处理] uploadify swfupload 上传图片出现类型错误解决方案

[复制链接]
发表于 2012-9-24 11:44:25 | 显示全部楼层 |阅读模式

第一步:http://codeigniter.org.cn/forums/thread-14392-1-1.html

第二步:由于flash上传图片的mine是application/octet-stream,我想到的是修改config

修改./application/config/mimes.php
例如:
PHP复制代码
 
'jpeg'    =>    array('image/jpeg', 'image/pjpeg'),
                'jpg'    =>    array('image/jpeg', 'image/pjpeg'),
                'jpe'    =>    array('image/jpeg', 'image/pjpeg'),
                'png'    =>    array('image/png',  'image/x-png'),
 
复制代码



PHP复制代码
 
'jpeg'    =>    array('image/jpeg', 'image/pjpeg', 'application/octet-stream'),
                'jpg'    =>    array('image/jpeg', 'image/pjpeg', 'application/octet-stream'),
                'jpe'    =>    array('image/jpeg', 'image/pjpeg', 'application/octet-stream'),
                'png'    =>    array('image/png',  'image/x-png', 'application/octet-stream'),
 
复制代码


大家看下这样会有什么问题吗?

发表于 2012-9-24 14:48:40 | 显示全部楼层
这个 mimes.php 的配置就是做这个用的,如果有些类型无法上传,就配置下 mime 就可以了。
发表于 2013-3-14 10:36:32 | 显示全部楼层
本帖最后由 yuvista 于 2013-3-14 10:45 编辑

其实,不应该这样修改。这样会导致安全隐患,在条件允许的情况下应该开启fileinfo扩展 来获取正确的类型


  1. extension=php_fileinfo.dll
复制代码


linux下
SQL复制代码
extension=fileinfo.so
复制代码
发表于 2014-8-21 23:24:02 | 显示全部楼层
extension=php_fileinfo.dll   果然有用
发表于 2014-12-24 17:12:22 | 显示全部楼层
本帖最后由 ^淡如清风 于 2014-12-24 17:19 编辑
yuvista 发表于 2013-3-14 10:36
其实,不应该这样修改。这样会导致安全隐患,在条件允许的情况下应该开启fileinfo扩展 来获取正确的类型

补充 uploadify swfupload 上传图片类型时出现

英文语言包:
The filetype you are attempting to upload is not allowed.

中文语言包:
此文件的类型在禁止上传之列

原因,楼上几层都已经说了,正如:@yuvista 说的,在条件允许的情况下应该开启fileinfo扩展 来获取正确的类型。
为什么开启后就不会报错了呢?
原来:CI的上传类中有个方法如下,处理这个mine
PHP复制代码
/**
 * File MIME type
 *
 * Detects the (actual) MIME type of the uploaded file, if possible.
 * The input array is expected to be $_FILES[$field]
 *
 * @param    array
 * @return    void
 */

protected function _file_mime_type($file)
{
    // We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii)
    $regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/';
 
    /* Fileinfo extension - most reliable method
     *
     * Unfortunately, prior to PHP 5.3 - it's only available as a PECL extension and the
     * more convenient FILEINFO_MIME_TYPE flag doesn't exist.
     */

    if (function_exists('finfo_file'))
    {
        $finfo = finfo_open(FILEINFO_MIME);
        if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
        {
            $mime = @finfo_file($finfo, $file['tmp_name']);
            finfo_close($finfo);
 
            /* According to the comments section of the PHP manual page,
             * it is possible that this function returns an empty string
             * for some files (e.g. if they don't exist in the magic MIME database)
             */

            if (is_string($mime) && preg_match($regexp, $mime, $matches))
            {
                $this->file_type = $matches[1];
                return;
            }
        }
    }
 
    /* This is an ugly hack, but UNIX-type systems provide a "native" way to detect the file type,
     * which is still more secure than depending on the value of $_FILES[$field]['type'], and as it
     * was reported in issue #750 (https://github.com/EllisLab/CodeIgniter/issues/750) - it's better
     * than mime_content_type() as well, hence the attempts to try calling the command line with
     * three different functions.
     *
     * Notes:
     *    - the DIRECTORY_SEPARATOR comparison ensures that we're not on a Windows system
     *    - many system admins would disable the exec(), shell_exec(), popen() and similar functions
     *      due to security concerns, hence the function_exists() checks
     */

    if (DIRECTORY_SEPARATOR !== '\\')
    {
        $cmd = 'file --brief --mime ' . escapeshellarg($file['tmp_name']) . ' 2>&1';
 
        if (function_exists('exec'))
        {
            /* This might look confusing, as $mime is being populated with all of the output when set in the second parameter.
             * However, we only neeed the last line, which is the actual return value of exec(), and as such - it overwrites
             * anything that could already be set for $mime previously. This effectively makes the second parameter a dummy
             * value, which is only put to allow us to get the return status code.
             */

            $mime = @exec($cmd, $mime, $return_status);
            if ($return_status === 0 && is_string($mime) && preg_match($regexp, $mime, $matches))
            {
                $this->file_type = $matches[1];
                return;
            }
        }
 
        if ( (bool) @ini_get('safe_mode') === FALSE && function_exists('shell_exec'))
        {
            $mime = @shell_exec($cmd);
            if (strlen($mime) > 0)
            {
                $mime = explode("\n", trim($mime));
                if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
                {
                    $this->file_type = $matches[1];
                    return;
                }
            }
        }
 
        if (function_exists('popen'))
        {
            $proc = @popen($cmd, 'r');
            if (is_resource($proc))
            {
                $mime = @fread($proc, 512);
                @pclose($proc);
                if ($mime !== FALSE)
                {
                    $mime = explode("\n", trim($mime));
                    if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
                    {
                        $this->file_type = $matches[1];
                        return;
                    }
                }
            }
        }
    }
 
    // Fall back to the deprecated mime_content_type(), if available (still better than $_FILES[$field]['type'])
    if (function_exists('mime_content_type'))
    {
        $this->file_type = @mime_content_type($file['tmp_name']);
        if (strlen($this->file_type) > 0) // It's possible that mime_content_type() returns FALSE or an empty string
        {
            return;
        }
    }
 
    $this->file_type = $file['type'];
}
复制代码


--------------------------------------- 扩展内容 ----------------------------------------------
以下内容来源:http://www.php100.com/html/webkaifa/PHP/PHP/2010/1023/6664.html

php5.3以下使用fileinfo获得文件的mime类型

php5.3.0以下要获得文件的mime类型,一般的方法是使用mime_content_type()方法,不过这个方法已经过时,所以最好使用fileinfo来代替。

本人使用的是windows环境,下面介绍的是基于windows环境的。

首先要下载php_fileinfo.dll文件,可以在http://pecl.php.net/package/Fileinfo 这里下载,不过这里下载到的是源文件,需要自己编译。也可以在这里下载http://dllcentral.com/php_fileinfo.dll/5.2.5.5/ ,不过下到的是5.2.55版本的。如果你使用的php环境是xampp的话,则不用自己下载,xampp里面已经集成了这个东西。

之后到sourceforge.net下载file程序(file程序是GNUWin32 Project的程序之一),地址是:http://sourceforge.net/projects/gnuwin32/files/file/ ,不过最好选择4.20版本或者之前的的,因为以后的版本中没有magic.mime文件。下载二进制版本,类似于file-x.xx-bin.zip。将下载的file-x.xx-bin.zip解压缩,从share目录中将存放文件类型信息的magic和magic.mime两个文件复制到到一个目录下,假设这个目录为D:\xampp\php\extras。其中magic可以用apache的conf目录下的magic代替HP的extras文件夹也有一个 magic.mime文件,但是用它的话fileinfo扩展无法正确工作(如果使用php自带的magic.mime的话,则使用fileinfo获取文件的mime类型的话,每次都返回),不能用来代替GNUWin32的这个magic.mime。

修改php.ini,加入这样一行:
PHP复制代码
extension=php_fileinfo.dll
复制代码


之后重新启动web服务器。查看phpinfo()是否已经正确启用了Fileinfo。

测试代码如下:
PHP复制代码
<?php
//可以手动自动magic文件的路径,也可以通过配置来获得,以下是通过php.ini的配置
//来获得magic文件的绝对路径
$magicFile = get_cfg_var('magic_mime.magic')';
$testFile = '
d:\test.doc';
$finfo = new finfo(FILEINFO_MIME, $magicFile);
echo $finfo->file($testFile);
?>
复制代码
输出:application/msword

注意:必须保证magic.mime与magic两个文件放在同一个文件夹 。
发表于 2015-1-8 13:03:29 | 显示全部楼层
^淡如清风 发表于 2014-12-24 17:12
补充 uploadify swfupload 上传图片类型时出现

英文语言包:

根本原因是因为,flash上传的时候 会覆盖掉文件mime type  通过fileinfo 才能正确正确获取这个文件的mime type
发表于 2015-4-22 11:31:31 | 显示全部楼层
试过了,开启php_fileinfo.dll就ok了

本版积分规则