Лучший способ получить удаленный тип файла, чтобы заменить PHP getimagesize ()?

1

Я использую getimagesize() PHP getimagesize() для получения типа файла изображения на удаленном сервере.

Глядя на PHP-документы для getimagesize() здесь http://php.net/manual/en/function.getimagesize.php, в комментариях говорится, что эта функция сначала загружает весь файл сначала, а затем получает информацию о файле.

Комментарий также предоставил альтернативную функцию для замены getimagesize() которая утверждает, что загружает только первые байты, пока не получит getimagesize() ему информацию, которая быстрее, чем первая загрузка всего файла.

Проблема с этой новой функцией заключается в том, что она называется getJpegSize($img_loc) и утверждает, что работает в файлах JPEG. Поскольку мои пользователи, очевидно, не будут ограничиваться только файлами JPG, мне любопытно, есть ли лучший способ сделать это, что будет так же быстро, но работать и с другими типами изображений?

Код для новой функции приведен ниже. Также прямая ссылка на страницу документов PHP, где размещены комментарий и код: http://php.net/manual/en/function.getimagesize.php#88793

// Retrieve JPEG width and height without downloading/reading entire image.
// From http://php.net/manual/en/function.getimagesize.php
function getJpegSize($img_loc) {
    $handle = fopen($img_loc, "rb") or die("Invalid file stream.");
    $new_block = NULL;
    if(!feof($handle)) {
        $new_block = fread($handle, 32);
        $i = 0;
        if($new_block[$i]=="\xFF" && $new_block[$i+1]=="\xD8" && $new_block[$i+2]=="\xFF" && $new_block[$i+3]=="\xE0") {
            $i += 4;
            if($new_block[$i+2]=="\x4A" && $new_block[$i+3]=="\x46" && $new_block[$i+4]=="\x49" && $new_block[$i+5]=="\x46" && $new_block[$i+6]=="\x00") {
                // Read block size and skip ahead to begin cycling through blocks in search of SOF marker
                $block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
                $block_size = hexdec($block_size[1]);
                while(!feof($handle)) {
                    $i += $block_size;
                    $new_block .= fread($handle, $block_size);
                    if($new_block[$i]=="\xFF") {
                        // New block detected, check for SOF marker
                        $sof_marker = array("\xC0", "\xC1", "\xC2", "\xC3", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xCA", "\xCB", "\xCD", "\xCE", "\xCF");
                        if(in_array($new_block[$i+1], $sof_marker)) {
                            // SOF marker detected. Width and height information is contained in bytes 4-7 after this byte.
                            $size_data = $new_block[$i+2] . $new_block[$i+3] . $new_block[$i+4] . $new_block[$i+5] . $new_block[$i+6] . $new_block[$i+7] . $new_block[$i+8];
                            $unpacked = unpack("H*", $size_data);
                            $unpacked = $unpacked[1];
                            $height = hexdec($unpacked[6] . $unpacked[7] . $unpacked[8] . $unpacked[9]);
                            $width = hexdec($unpacked[10] . $unpacked[11] . $unpacked[12] . $unpacked[13]);
                            return array($width, $height);
                        } else {
                            // Skip block marker and read block size
                            $i += 2;
                            $block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
                            $block_size = hexdec($block_size[1]);
                        }
                    } else {
                        return FALSE;
                    }
                }
            }
        }
    }
    return FALSE;
}
  • 0
    Что вы собираетесь делать с той информацией, которую вы называете «Тип файла»? Так как вы говорите, что хотите избежать загрузки всего ресурса, означает ли это, что вы никогда его не загрузите? Тогда, возможно, на самом деле важна скорее информация типа mime, которую удаленный сервер отправляет вместе с данными; если это так, вместо этого сделайте запрос HEAD и оцените содержимое заголовка Content-Type .
Теги:

1 ответ

0

Каждый тип изображения имеет другой способ хранения своего размера. Поскольку у вас нет ограничений по типу, вы должны использовать getimagesize() и избегать добавления слишком большой сложности (если вам это действительно не нужно). Это упростит ваш код и поможет в обслуживании (если есть ошибка в функции, которую вы вставили, удачи в ней!)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню