如何为扩展名分配多个文件MIME类型?

时间:2018-12-23 作者:T.Todua

为了允许上传额外的文件类型,我们使用:

add_filter(\'mime_types\', \'my_mimes\');
function my_mimes($all)
{
    $all[\'zip\'] = \'application/zip\';
    return $all;
}
但是如何将多个文件类型分配给一个扩展名呢?例如zip 扩展可能有application/zip mime和application/x-zip (比如,来自7zip). 这种方式行不通:

$all[\'zip\'] = [\'application/zip\', \'application/x-zip\'] ;

3 个回复
最合适的回答,由SO网友:birgire 整理而成

请注意,自WP 5.0.1以来,mime类型检查更加严格,其中文件内容和文件扩展名必须匹配。参见例如最近的questionvtt 文件类型。

给定文件扩展名的次要mime类型这里有一个建议,如何支持给定文件扩展名的次要mime类型。让我们采取行动.vtt 例如。core假定mime类型为text/vtt 对于该文件扩展名,但真正的mime类型来自finfo_file() 有时可能是text/plain. 这个finfo_file() 似乎有点buggy. 我们可以将其作为辅助mime类型添加支持,包括:

/**
 * Support for \'text/plain\' as the secondary mime type of .vtt files,
 * in addition to the default \'text/vtt\' support.
 */
add_filter( \'wp_check_filetype_and_ext\', \'wpse323750_secondary_mime\', 99, 4 );    

function wpse323750_secondary_mime( $check, $file, $filename, $mimes ) {
    if ( empty( $check[\'ext\'] ) && empty( $check[\'type\'] ) ) {
        // Adjust to your needs!
        $secondary_mime = [ \'vtt\' => \'text/plain\' ];

        // Run another check, but only for our secondary mime and not on core mime types.
        remove_filter( \'wp_check_filetype_and_ext\', \'wpse323750_secondary_mime\', 99, 4 );
        $check = wp_check_filetype_and_ext( $file, $filename, $secondary_mime );
        add_filter( \'wp_check_filetype_and_ext\', \'wpse323750_secondary_mime\', 99, 4 );
    }
    return $check;
}
这里我们使用wp_check_filetype_and_ext 筛选以查看检查是否失败。那样的话我们就跑wp_check_filetype_and_ext() 同样,但现在只在我们的二级mime类型上,同时禁用我们的过滤器回调以避免无限循环。

如果我们需要为.vtt 文件,然后我们可以使用以下内容展开上述代码段:

/**
 * Demo: Support for \'text/foo\' and \'text/bar\' mime types of .vtt files,
 * in addition to the default \'text/vtt\' support.
 */
add_filter( \'wp_check_filetype_and_ext\', \'wpse323750_multi_mimes\', 99, 4 );

function wpse323750_multi_mimes( $check, $file, $filename, $mimes ) {
    if ( empty( $check[\'ext\'] ) && empty( $check[\'type\'] ) ) {
        // Adjust to your needs!
        $multi_mimes = [ [ \'vtt\' => \'text/foo\' ], [ \'vtt\' => \'text/bar\' ] ];

        // Run new checks for our custom mime types and not on core mime types.
        foreach( $multi_mimes as $mime ) {
            remove_filter( \'wp_check_filetype_and_ext\', \'wpse323750_multi_mimes\', 99, 4 );
            $check = wp_check_filetype_and_ext( $file, $filename, $mime );
            add_filter( \'wp_check_filetype_and_ext\', \'wpse323750_multi_mimes\', 99, 4 );
            if ( ! empty( $check[\'ext\'] ) ||  ! empty( $check[\'type\'] ) ) {
                return $check;
            }
        }
    }
    return $check;
}
我希望您可以进一步测试它,并根据您的需要进行调整。

SO网友:Sergey Zaharchenko

birgire的回答稍有改进。必须为添加多个mime类型svg, 但是因为svg 默认情况下是禁止的,必须将动态筛选器添加到upload_mimes:

class Multiple_Mimes {

    public static function init() {
        add_filter( \'wp_check_filetype_and_ext\', [self::class, \'add_multiple_mime_types\'], 99, 3 );
    }


    public static function add_multiple_mime_types( $check, $file, $filename ) {
        if ( empty( $check[\'ext\'] ) && empty( $check[\'type\'] ) ) {
            foreach ( self::get_allowed_mime_types() as $mime ) {
                remove_filter( \'wp_check_filetype_and_ext\', [ self::class, \'add_multiple_mime_types\' ], 99 );
                $mime_filter = function($mimes) use ($mime) {
                    return array_merge($mimes, $mime);
                };

                add_filter(\'upload_mimes\', $mime_filter, 99);
                $check = wp_check_filetype_and_ext( $file, $filename, $mime );
                remove_filter(\'upload_mimes\', $mime_filter, 99);
                add_filter( \'wp_check_filetype_and_ext\', [ self::class, \'add_multiple_mime_types\' ], 99, 3 );
                if ( ! empty( $check[\'ext\'] ) || ! empty( $check[\'type\'] ) ) {
                    return $check;
                }
            }
        }

        return $check;
    }


    public static function get_allowed_mime_types(){
        return [
            [ \'svg\' => \'image/svg\' ],
            [ \'svg\' => \'image/svg+xml\' ],
        ];
    }

}

SO网友:bobbingwide

我有一个类似的问题要解决在哪里。zip文件被视为application/zip 通过PHP,但检测为application/x-zip-compressed.

我的解决方法是用一个发明的密钥添加这个新值

\'xzip\' => \'`application/x-zip-compressed\';
请参见https://github.com/WordPress/gutenberg/issues/23510

另请参见两个WordPress跟踪:

相关推荐

将文件上载到Uploads文件夹时向自定义用户角色发送电子邮件通知

我已经编写了一个自定义php,允许我的模板页面中的用户从前端上传新创建的子文件夹中的文件user_login 作为其名称uploads 文件夹因此,将上载根文件夹,并在用户的子文件夹中存储所有文件。这是我的密码。<form enctype="multipart/form-data" action="" method="POST" class="centered"> <p><