Заметки об «индийском» коде

Материал из Бронетанковой Энциклопедии — armor.kiev.ua/wiki
Перейти к: навигация, поиск


Автор(ы): Чобиток Василий

Пример № 1 (PHP 5)

14.08.2010

Задача: известно, что путь к картинке хранится в переменной $image_path. Картинка может быть в одном из форматов, который поддерживается браузерами (JPEG, GIF и т. п.). Необходимо картинку передавать в браузер не прямой ссылкой, а при обращении к скрипту.

Естественно, что при получении картинки скриптом в начале PHP-скрипт должен сообщить в заголовке тип передаваемых данных, например: «Content-type: image/jpeg».

Программист решает эту задачу следующим образом:

$extension = strtolower(strrchr(basename($image_path), '.'));

switch($extension) {
  case '.jpg': header('Content-type: image/jpeg'); break;
  case '.jpeg': header('Content-type: image/jpeg'); break;
  case '.png': header('Content-type: image/png'); break;
  case '.gif': header('Content-type: image/gif'); break;
}

В этом коде проблемы следующие:

  1. Привязка к расширению. Не всегда расширение соответствует реальному формату данных. Дай файлу в формате JPEG расширение «.gif» и этот код перестанет работать. Впрочем, это некритичная проблема, т.к. любой сайтовладелец, должен следить за адекватностью контента и данная проблема может никогда и не проявится.
  2. При появлении новых форматов изображений (SVG набирает силу) придётся менять код внутри структурного оператора switch и добавлять новые операторы.

Решение проблемы: в PHP есть функции, которые возвращают тип изображения по сигнатуре первых байтов его файла (exif_imagetype), а также Mime-тип изображения по его типу. Рефакторинг предыдущего решения даёт следующий результат:

$imgType = exif_imagetype($image_path);
header('Content-type: ' . image_type_to_mime_type($imgType));

Здесь картинки работают независимо от расширения, нет привязки к ограниченному списку форматов, размер кода сократился в три раза.