Как получить MIME-тип файла в PHP 5.5?

Я использую mime_content_type() в PHP 5.5 для получения типа MIME, но он бросает fatal: error function not found.

Как я могу добиться этого на PHP 5.5?

Ответ 1

Используйте функции finfo().

Простая иллюстрация:

<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, "path/to/image_dir/image.gif");
finfo_close($finfo);

OUTPUT :

image/gif

Примечание. Для включения этого расширения пользователи Windows должны включать связанный DLL файл php_fileinfo.dll в php.ini.

Ответ 2

Я потратил слишком много времени, пытаясь правильно работать с функциями finfo. Я, наконец, только что создал свою собственную функцию, чтобы соответствовать расширению файла любому массиву типов mime. Это не полный доказательство того, что файлы действительно являются расширением, обозначающим их, но эта проблема может быть смягчена тем, как вы обрабатываете ввод/вывод указанных файлов на своих серверах.

function mime_type($file) {

    // there a bug that doesn't properly detect
    // the mime type of css files
    // https://bugs.php.net/bug.php?id=53035
    // so the following is used, instead
    // src: http://www.freeformatter.com/mime-types-list.html#mime-types-list

    $mime_type = array(
        "3dml" => "text/vnd.in3d.3dml",
        "3g2" => "video/3gpp2",
        "3gp" => "video/3gpp",
        "7z" => "application/x-7z-compressed",
        "aab" => "application/x-authorware-bin",
        "aac" => "audio/x-aac",
        "aam" => "application/x-authorware-map",
        "aas" => "application/x-authorware-seg",
        "abw" => "application/x-abiword",
        "ac" => "application/pkix-attr-cert",
        "acc" => "application/vnd.americandynamics.acc",
        "ace" => "application/x-ace-compressed",
        "acu" => "application/vnd.acucobol",
        "adp" => "audio/adpcm",
        "aep" => "application/vnd.audiograph",
        "afp" => "application/vnd.ibm.modcap",
        "ahead" => "application/vnd.ahead.space",
        "ai" => "application/postscript",
        "aif" => "audio/x-aiff",
        "air" => "application/vnd.adobe.air-application-installer-package+zip",
        "ait" => "application/vnd.dvb.ait",
        "ami" => "application/vnd.amiga.ami",
        "apk" => "application/vnd.android.package-archive",
        "application" => "application/x-ms-application",
        // etc...
        // truncated due to Qaru character limit in posts
    );

    $extension = \strtolower(\pathinfo($file, \PATHINFO_EXTENSION));

    if (isset($mime_type[$extension])) {
        return $mime_type[$extension];
    } else {
        throw new \Exception("Unknown file type");
    }

}

Edit:

Я хотел бы обратиться к комментарию Давуза (так как он продолжает подниматься и проголосовать) и напомнить всем, что я положил псевдооговорку наверху, что это не "полноправное доказательство". Поэтому, пожалуйста, помните об этом, рассматривая подход, который я предложил в своем ответе.

Ответ 4

$finfo = finfo_open(FILEINFO_MIME_TYPE); должен это сделать.

Взято из документов php.net. Ваша функция устарела и, вероятно, уже удалена.

http://www.php.net/manual/en/function.finfo-file.php

Ответ 5

Вы должны понимать, что file_get_contents загрузит весь файл в память, это не очень хороший способ получить только тип mime. В этом случае вам не нужно использовать метод buffer и функцию file_get_contents.

Чтобы избежать ошибок и предупреждений, лучше сделайте это.

$filename = 'path to your file';

if (class_exists('finfo')) {
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    if (is_object($finfo)) {
        echo $finfo->file($filename);
    }
} else {
    echo 'fileinfo did not installed';
}

Также вы должны знать, что $finfo- > файл выдает PHP Warning, если он не работает.

Если файлinfo установлен неправильно, и у вас есть новая версия PHP, вы можете получить тип mime из заголовков.

Вы можете использовать cURL для получения типа mime из заголовков.

    $ch = curl_init();
    curl_setopt_array($ch, array(
            CURLOPT_HEADER => true,
            CURLOPT_NOBODY => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 1,
            CURLOPT_URL => $link)
    );

    $headers = curl_exec($ch);
    curl_close($ch);

    if (preg_match('/Content-Type:\s(.*)/i', $headers, $matches)) {
        echo trim($matches[1], "\t\n\r");
    }else {
        echo 'There is no content type in the headers!';
    }

Также вы можете использовать функцию get_headers, но она медленнее, чем запрос cURL.

$url = 'http://www.example.com';

$headers = get_headers($url, 1);

echo $headers['Content-Type'];

Ответ 6

Получить размер изображения, используя:

$infFil=getimagesize($the_file_name);

и

echo $infFil["mime"]

getimagesize возвращает ассоциативный массив с ключом MIME и, очевидно, размер изображения

Я использовал его, и он работает

Ответ 7

Я использую MimeTypeTool из Bat (https://github.com/lingtalfi/Bat)

Он использует fileinfo, если он доступен, и по умолчанию возвращается к отображению "расширение = > mime type".

Ответ 8

Это лучшее решение, которое я нашел, объединив два очень хороших сообщения

//Благодаря http://php.net/manual/en/function.mime-content-type.php#87856

function getMimeContentType($filename, $ext)
{
    if(!function_exists('mime_content_type'))
    {
        if($mime_types = getMimeTypes())
        {
            if (array_key_exists($ext, $mime_types))
            {
                return $mime_types[$ext];
            }
            elseif (function_exists('finfo_open'))
            {
                $finfo  = finfo_open(FILEINFO_MIME);
                $mimetype = finfo_file($finfo, $filename);
                finfo_close($finfo);
                return $mimetype;
            }
        }
        return 'application/octet-stream';
    }
    return mime_content_type($filename);
}

//Благодаря http://php.net/manual/en/function.mime-content-type.php#107798

function getMimeTypes()
{
    $url = 'http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types';

    $mimes = array();
    foreach(@explode("\n",@file_get_contents($url)) as $x)
    {
        if(isset($x[0]) && $x[0]!=='#' && preg_match_all('#([^\s]+)#', $x, $out) && isset($out[1]) && ($c = count($out[1])) > 1)
        {
                for($i=1; $i < $c; $i++)
            {
                    $mimes[$out[1][$i]] = $out[1][0];
            }
        }
    }
    return (@sort($mimes)) ? $mimes : false;
}

Используйте ссылку:

$filename = '/path/to/the/file.pdf';
$ext = strtolower(array_pop(explode('.',$filename)));
$content_type = getMimeContentType($filename, $ext);

Будет продолжать работать, даже если функция mime_content_type больше не поддерживается в php.