Как определить при загрузке файла на сервер, что это изображение?! Ответ: PHP: <?php # Функция для определения параметров изображения # Возвращает массив параметров если файл изображение и FALSE при ошибке function get_image_info($file = NULL) { if(!is_file($file)) return false; if(!$data = getimagesize($file) or !$filesize = filesize($file)) return false; $extensions = array(1 => 'gif', 2 => 'jpg', 3 => 'png', 4 => 'swf', 5 => 'psd', 6 => 'bmp', 7 => 'tiff', 8 => 'tiff', 9 => 'jpc', 10 => 'jp2', 11 => 'jpx', 12 => 'jb2', 13 => 'swc', 14 => 'iff', 15 => 'wbmp', 16 => 'xbmp'); $result = array('width' => $data[0], 'height' => $data[1], 'extension' => $extensions[$data[2]], 'size' => $filesize, 'mime' => $data['mime']); return $result; } # Пример (отрывок) проверки файла при загрузке $valid_extensions = array('gif', 'jpg', 'png'); if(!$image_info = get_image_info($_FILES['upload_image']['tmp_name']) or !in_array($image_info['extension'], $valid_extensions)) { die('Ошибка'); } else { $upload_file_name = uniqid(NULL, true).'.'.$image_info['extension']; if(!@move_uploaded_file($_FILES['upload_image']['tmp_name'], 'upload_folder/'.$upload_file_name)) die('Ошибка'); } Комментарии?
Проверку по сигнатуре зафигачить: PHP: <?php function get_image_type($file) { if (!$f = fopen($file, 'rb')) { return false; } $data = fread($f, 8); fclose($f); if ( @array_pop(unpack('H12', $data)) == '474946383961' || @array_pop(unpack('H12', $data)) == '474946383761' ) { return 'GIF'; } else if ( @array_pop(unpack('H4', $data)) == 'ffd8' ) { return 'JPEG'; } else if ( @array_pop(unpack('H16', $data)) == '89504e470d0a1a0a' ) { return 'PNG'; } else if ( @array_pop(unpack('H4', $data)) == '424d' ) { return 'BMP'; } return false; } ?>
Не спорю. Предлагаю совместить Сначала проверка расширения, потом сигнатуры, а уже потом попытка узнать размер.
Hight, твоя проверка пропустит некартинки (любая проверка по расширению/мим типу их пропустит), а версия Sergey89 - нет. По идеи.
RTFM. Ничего она не пропустит. Внимательнее код функции "get_image_info" изучай и почитай мануал по функции getimagesize. http://ru2.php.net/manual/ru/function.getimagesize.php
test.gif: Код (Text): GIF89ad <? echo 'PHP'; ?> Вся твоя проверка - псевдо-полезная херня. Набор лишних букв. Кстати, почитай про getimagesize() и массив $_FILES глазами, а не тем, чем читал до этого.
lexa Давай разбираться То-есть, если мы подсунем этой функции не изображение, то получим false, а если изображение, то набор его параметров. Так ведь?! Так. Моя функция 'get_image_info' - это расширение 'getimagesize'. Возвращает массив параметров: 'width', 'height', 'extension', 'size' ,'mime' на основе данных полученных от 'getimagesize' и false в случае если файл не изображение. При этом отличие моей 'get_image_info' от 'getimagesize' состоит в том, что моя функция возвращает расширение файла в виде строки, а не числового значения и возвращает размер файла изображения. При этом хочу заметить, что расширение файла изображения определяется на основании данных полученных от 'getimagesize', а не всякими там строковыми функциями и регулярными выражениями. По-этому всё отлично работает и функция отлично справляется со своей задачей.
Hight, я только показал, как может пройти некартинка при всей твоей лишней проверке. Массив $_FILES содержит и мим-тип, и размер, а простым движением можно вынуть расширение из имени файла и будет так же хорошо работать. getimagesize() нужна только для получения ширины и высоты (ну и как формальная проверка на "картинкость"). Все остальные манипуляции - излишни. Как например функция filesize(). В идеале, у тега form есть атрибут access (кажется) в котором через запятую указываются доступные для загрузки типы файлов: image/*, text/plain и т.д. Вообще не понятно с чего ты так неадекватно среагировал.
Гарантировать, что в файле нет ничего кроме картинки можно только после удачного ресайза (например 1 в 1), и только для результатов этого ресайза.
Тогда вот ресайзилка: PHP: <?php function image_resize($img_file, $target_file, $width, $height) { if(!file_exists($img_file)) return false; if(!$source_im_info = @getimagesize($img_file)) return false; $valid_im_types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); if(!array_key_exists($source_im_info[2], $valid_im_types)) return false; $img_open_func = 'imagecreatefrom'.$valid_im_types[$source_im_info[2]]; $source_im = $img_open_func($img_file); $result_im = imagecreatetruecolor($width, $height); if(!@imagecopyresampled($result_im, $source_im, 0, 0, 0, 0, $width, $height, $source_im_info[0], $source_im_info[1])) return false; $img_close_func = 'image'.$valid_im_types[$source_im_info[2]]; if(!$img_close_func($result_im, $target_file)) return false; imagedestroy($source_im); imagedestroy($result_im); return true; }
Вопрос, зачем проверять? Если для того, чтобы не грузили на сервер запускаемые сценарии, то здесь хватит правильного расширения и вменяемых настроек сервера. Кстати, можно создать корректное изображение, которое в то же время будет исполняемым сценарием. В bmp это вообще без проблем.
В bmp после заголовка (и, возможно, палитры) тупо идут коды точек. Для изображения 100x100x256 цветов - 10 000 байт, которые соответствуют точкам, никаких ограничений на последовательность нет. В эту часть вполне можно вставить теги <? ?> и написать внутри всё что угодно. В других форматах посложнее, но думаю тоже лазейки найдутся.
vasa_c и смысл? я могу отстенографировать в любой файл что угодно. а 31 байт заголовка не помешает выдать интепритатору ексепшн? он не выполнит ведь его