IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Веб-программирование (http://www.imho.ws/forumdisplay.php?f=29)
-   -   Логика if - else PHP нужна помощь (http://www.imho.ws/showthread.php?t=141601)

killhunter 16.10.2009 00:53

Логика if - else PHP нужна помощь
 
День добрый.
Помогите, пожалуйста, разобраться с логикой многоуровнего if - else.
Есть код загрузки картинок на сервер + пути в базу.
Многочисленные проверки работают и всю грузиться куда надо, если проходит проверки. Но вот текст ошибки по проверке размера фаила в Кб не выдаётся, а выдается ошибка по пикселям. Хотя фаил большого чем надо размера не пропускает. В общем хочу понять почему не выдаёт ошибку по размеру. :idontnow:
Заранее спасибо.

PHP код:

//коннектимся к базе
$max_image_width = 150;
$max_image_height = 301;
$max_image_width2 = 801;
$max_image_height2 = 1001;
$max_image_size = 20 * 1024;
$max_image_size2 = 200 * 1024;
$valid_types = array("gif","jpg", "png", "jpeg", "JPG", "JPEG", "GIF", "PNG");

if($post=="Y")
  {
   

   // Каталог, в который мы будем принимать файл:
   $uploaddir1 = 'files/';
   $filename = $_FILES['image_path1']['name'];
   $filename_1 = $_FILES['image_path2']['name'];
     if (eregi("[а-яА-Я]", $filename) || eregi("[а-яА-Я]", $filename_1))
       {
         $error_1="<b>Ошибка:</b> <font color=#FF0000>В имени фаила не должно быть русских букв.</font>";
       }
     else
       {
         //генерируем новые имена
         $add=rand(1,10).rand(5,20).rand(3,40).rand(1,100);
         $name=substr($filename, 0, strrpos($filename, "."));
         $name_hex=bin2hex($name);
         $add2=rand(1,10).rand(5,20).rand(3,40).rand(1,100);
         $name2=substr($filename_1, 0, strrpos($filename_1, "."));
         $name_hex2=bin2hex($name2);
         $ext = substr($filename, 1 + strrpos($filename, "."));
         $ext2 = substr($filename_1, 1 + strrpos($filename_1, "."));
         $filename2 = $_FILES['image_path1']['tmp_name'];
         $filename2_2 = $_FILES['image_path2']['tmp_name'];
         if (strrpos($filename, ".") > 8 && strrpos($filename_1, ".") > 8)
           {
            $error_2="<b>Ошибка:</b> <font color=#FF0000>Слишком длинное имя фаила. Допустимо 8 символов до точки.</font>";
           } 
         else
           {
         $image_path1 = $uploaddir1.basename($add.'_'.$name_hex.'.'.$ext);
         $image_path2 = $uploaddir1.basename($add2.'_'.$name_hex2.'.'.$ext2);
          //вот что-то здесь не так
           [B]if (filesize($filename2) > $max_image_size || filesize($filename2_2) > $max_image_size2) 
             {
               $error_3="<b>Ошибка:</b> <font color=#FF0000Размер фаила слишком большой. Допустимо не более 20Kб для фото-миниатюры и 200Кб для полной фотографии.</font>";[/B]             } 
           elseif (!in_array($ext, $valid_types) || !in_array($ext2, $valid_types)) 
             {
               $error_4="<b>Ошибка:</b> <font color=#FF0000>Неправильный тип фаила. Допустимо (jpg, jpeg) или фаил не указан.</font>";
             } 
           else 
             {
               $size = GetImageSize($filename2);
               $size2 = GetImageSize($filename2_2);
               if (($size) && ($size[0] == $max_image_width) && ($size[1] < $max_image_height) && ($size2) && ($size2[0] < $max_image_width2) && ($size2[1] < $max_image_height2)) 
                   {
                      // Копируем файл из каталога для временного хранения файлов:
                         if (copy($filename2, $image_path1) && copy($filename2_2, $image_path2))
                           {
                             //грузим в базу данные и путь
                                        
                            }
                         else $error_5="<b>Ошибка:</b> <font color=#FF0000>Не удалось загрузить файл на сервер!</font>"; 
                   } 
                 else $error_6="<b>Ошибка:</b> <font color=#FF0000>Размеры картинки слишком большие. Для фото-миниатюры ширина = 150px, высота максимально - 300px, для полной фотографии ширина максимально 800px, высота максимально - 1000px.</font>";
             }
          }
       }   
  }
echo $error_1;
echo $error_2;
echo $error_3;
echo $error_4;
echo $error_5;
echo $error_6;
?>
<form action="<? $PHP_SELF?>" method="post" enctype=multipart/form-data>
<input type="hidden" name="post" value="Y">
<input type="hidden" name="MAX_FILE_SIZE" value="200000">
....
<input type="file" name="image_path1" value="<? echo $image_path1?>" size=26>
<input type="file" name="image_path2" value="<? echo $image_path2?>" size=26
...
<input type="submit" value="Добавить">
</form>
//закрываем коннект к базе


Plague 16.10.2009 01:38

хммм
Цитата:

Сообщение от killhunter (Сообщение 1679162)
<font color=#FF0000Размер фаила слишком большой. Допустимо не более 20Kб....

тег-то допиши уж, зачем экономить... :rolleyes: :biggrin:

<font color=#FF0000>Размер...

killhunter 16.10.2009 03:21

Спасибо.

Однако вопрос до конца не решён.
Проверил еще раз.
Дано два тестовых фаила:
первый - маленький 150*112 (по геометр. размерам подходит). Сохранён специально без сжатия - 44 Кб
(по Кб не подходит) - загружаем только его - PHP честно пишет - не подходит - ура!

второй - большой 600*450 (по геометр. размерам подходит). Сохранён специально без сжатия - 323 Кб (по Кб не подходит) - загружаем только его - PHP пишет - "Размеры картинки слишком большие. Для фото-миниатюры ширина = 150px, высота максимально - 300px, для полной фотографии ширина максимально 800px, высота максимально - 1000px." - не то - косяк!

Грузим оба - PHP честно пишет - не подходит - ура!
(ссылаясь скорее всего на первый фаил)

Жмем фаилы по размеру - ошибок нет - грузим на сервер и в базу.

Всё бы ничего, если бы делал интерфейс для себя. А так пользователь будет биться головой о стенку (хоть весь лист испиши help'ом) почему размеры большой картинки по пикселям верны, а картинка не грузится и выдаёт что неправильные размеры по пикселям.

P.S. Сделал то же самое для одного фаила
При выполнение условий всё грузиться.
Если взять картинку меньшую по пикселям, но большую по Кб, пишет большая по Кб.
Если взять нужную по пикселям, но большую по Кб, пишет неправильные размеры по пикселям.:idontnow:
PHP код:

<?
$max_image_width 
150;
$max_image_height 301;
$max_image_size 20 1024;
$valid_types = array("jpg""jpeg""JPG""JPEG");

 
if(
$post=="Y")
  {
               
    
// Каталог, в который мы будем принимать файл:
    
$uploaddir 'upload/';
    
$filename1_1 $_FILES['image_path']['name'];

         if (
eregi("[а-яА-Я]"$filename1_1))
      {
        
$error_1="<b>Ошибка:</b> <font color=#FF0000>В имени фаила не должно быть русских букв.</font>";
      }
     else
      {
       
$add=rand(1,10).rand(5,20).rand(3,40).rand(1,100);
       
$name=substr($filename1_10strrpos($filename1_1"."));
       
$name_hex=bin2hex($name);
       
$filename2_1 $_FILES['image_path']['tmp_name'];
         if (
strrpos($filename1_1".") > 9)
           {
            
$error_2="<b>Ошибка:</b> <font color=#FF0000>Слишком длинное имя фаила. Допустимо 8 символов до точки.</font>";
           } 
         else
           {
         
$ext substr($filename1_1strrpos($filename1_1"."));
         
$image_path $uploaddir.basename($add.'_'.$name_hex.'.'.$ext);
 
        if (
filesize($filename2_1) > $max_image_size
           {
            
$error_3="<b>Ошибка:</b> <font color=#FF0000>Размер фаила слишком большой. Допустимо не более 20Кб.</font>";
           } 
         elseif (!
in_array($ext$valid_types)) 
           {
            
$error_4="<b>Ошибка:</b> <font color=#FF0000>Неправильный тип фаила. Допустимо (jpg, jpeg) или фаил не указан.</font>";
           } 
         else 
           {
            
$size getimagesize($filename2_1);
             if ((
$size) && ($size[0] == $max_image_width) && ($size[1] < $max_image_height)) 
              {

                
// Копируем файл из каталога для временного хранения файлов:
                  
if (copy($filename2_1$image_path))
                    {
                       
//грузим в базу и на сервер                                  
                     
} else   $error_5="<b>Ошибка:</b> <font color=#FF0000>Не удалось загрузить файл на сервер!</font";  
              } else   
$error_6="<b>Ошибка:</b> <font color=#FF0000>Неправильные размеры изображения. Измените, пожалуйста, размеры изображения до: ширина = 150px, высота максимально - 300px.</font>";
           }
         }
       }   
    }
echo 
$error_1;
echo 
$error_2;
echo 
$error_3;
echo 
$error_4
echo 
$error_5
echo 
$error_6;
?>
<form action="<? $PHP_SELF?>" method="post" enctype=multipart/form-data>
<input type="hidden" name="post" value="Y">
<input type="hidden" name="MAX_FILE_SIZE" value="20000">
....
<input type="file" name="image_path" value="<? echo $image_path?>" size=25>
.....
<input type="submit" value="Сохранить" >
</form>


Plague 16.10.2009 03:36

бррр. многа букф. особенно для третьего часа ночи. я честно пытался трижды прочесть и собрать в кучу. ниасилил.

файл a - проходит по dimension и не проходит по size
файл b - проходит по dimension и не проходит по size

дальше что?

killhunter 16.10.2009 03:45

Сделал дополнение на один фаил.

По вопросам, да именно так.

Оба фаила правильно проверяются на условия, но первый выдаёт правильные else (dimension, size). Второй выдает только dimension, на проверку как dimension, так и size.

EvroStandart 16.10.2009 12:27

Делай рядом с каждой проверкой выписку в хтмл. Чтобы видеть что там скрипт реально насчитал.

killhunter 16.10.2009 13:10

Сделал.
Проверял скрипт одного фаила.
Взял фаил 150*105, т.е. размеры подходят, но 30 Кб (не подходит).
Дальше началось странное:
три загрузки этого фаила - выводит неправильные размеры по ширине и высоте и не выводит echo размера по Кб и по ширине.
Четвертая и далее загрузки пишет большой размер по Кб и выводит echo filesize($filename2_1); 30150 как и должен.

Т.е. получается первые три загрузки getimagesize вообще не сработал.
Я правильно понимаю?
Если это так, то как можно с этим бороться - это же код, а не гадание на кофейной гуще :biggrin:

boor 16.10.2009 13:45

Версия php какая?
формат картинок разный или один?

killhunter 16.10.2009 13:53

Проверяю на локальном компе
Apache/2.0.59 PHP/4.3.4
Картинка одна (если рассматривать скрипт загрузки одного фаила), формат .jpg (обработка в Photoshop)

Hubbitus 19.10.2009 01:45

Хм, скажу честно, код жуткий (начиная с прямых проверок, странных получений имени файла и расширения и copy вместо move_uploaded_file ну и других конечно), но суть Вашей проблемы полагаю что Вы просто не проверяете ошибку аплоада ($_FILES['image_path']['error']) в Вашем случае получается, когда размер больше указанного в MAX_FILE_SIZE, php выставляет ошибку 2 ( UPLOAD_ERR_FORM_SIZE ), и соответственно $filename2_1 = $_FILES['image_path']['tmp_name']; пустые.

Правда getimagesize потом честно говорит об этом:
Код:

Warning: getimagesize() [function.getimagesize]: Filename cannot be empty in /home/hubbitus/_SITES/ru.bir.ru/_temp/imho.ws/Upload/1.php on line 35
странно как Вы этого не заметили. Полагаю забыли включить уровень вывода всех ошибок.

killhunter 19.10.2009 14:43

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

И ещё вопрос в контексте :)
Все мы в общем-то учимся постоянно. Вот сейчас я изучаю php, мне интересно почему код жуткий :biggrin:

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

Однако, буду признателен любой ссылки на мануал или пример максимально безопасной загрузки картинок на сервер :beer:

Hubbitus 19.10.2009 15:04

Цитата:

Сообщение от killhunter (Сообщение 1679790)
Т.е. надо ввести проверку на размер временного фаила, чтобы не ноль.

То есть надо проверить корректность загрузки, я же написал! $_FILES['image_path']['error'], is_uploaded_file...


Про жуткий код, ну я частично в скобках уже указал, ну например, что за велосипед:
Код:

$name=substr($filename1_1, 0, strrpos($filename1_1, "."));
Если в $filename1_1 будет имя файла "a.b.c.d.jpg"? Почему не воспользоваться стандартными http://php.net/pathinfo, http://ru2.php.net/basename? Там же и расширение файла. Про небезопасное использование copy я говорил. Ну и также далее, про длину файла в 8 символов (вообще не понятно откуда, ну да Бог с ней, может Вы в DOSе работаете, или того требует бизнес-логика) проверка по первой точке также не корректна...

killhunter 21.10.2009 10:08

Вот вариант с учётом, анализа ошибок загрузки и проверки временного фаила на ноль. Всё работает.
Кстати фаил a.b.c.d.jpg тоже правильно грузится :)
Поясню про 8 символов - сделано по двум причинам:
1. ограничить имя конечного фаила после bin2hex()
2. можно было и 5,7; 8 символов просто небольшая хитрость и пыль в глаза :)

PHP код:

$max_image_width = 150;
$max_image_height = 301;
$valid_types = array("jpg", "jpeg", "JPG", "JPEG");

 
if($post=="Y")
  {
        
    // Каталог, в который мы будем принимать файл:
    $uploaddir = 'upload/';
    $filename1_1 = $_FILES['image_path']['name'];

         if (eregi("[а-яА-Я]", $filename1_1))
      {
        $error_1="<b>Ошибка:</b> <font color=#FF0000>В имени фаила не должно быть русских букв.</font>";
      }
     else
      {
       $add=rand(1,10).rand(5,20).rand(3,40).rand(1,100);
       $name=substr($filename1_1, 0, strrpos($filename1_1, "."));
       $name_hex=bin2hex($name);
       $filename2_1 = $_FILES['image_path']['tmp_name'];
         if (strrpos($filename1_1, ".") > 9)
           {
            $error_2="<b>Ошибка:</b> <font color=#FF0000>Слишком длинное имя фаила. Допустимо 8 символов до точки.</font>";
           } 
         else
           {
         $ext = substr($filename1_1, 1 + strrpos($filename1_1, "."));
         $image_path = $uploaddir.basename($add.'_'.$name_hex.'.'.$ext);
 
        if (!in_array($ext, $valid_types)) 
           {
            $error_4="<b>Ошибка:</b> <font color=#FF0000>Неправильный тип фаила. Допустимо (jpg, jpeg) или фаил не указан.</font>";
           } 
         else 
           {

            if($_FILES['image_path']['error'] === 0)
             {
               if(isset($_FILES['image_path']) && is_uploaded_file($_FILES['image_path']['tmp_name']) && $_FILES['image_path']['size'])
               {
                $size = getimagesize($filename2_1);
                 if (($size) && ($size[0] == $max_image_width) && ($size[1] < $max_image_height)) 
                  {
                  // Копируем файл из каталога для временного хранения файлов:
                  if (copy($filename2_1, $image_path))
                    {
                         //грузим на сервер и в базу                                
                             
                     } else  $error_5="<b>Ошибка:</b> <font color=#FF0000>Не удалось загрузить файл на сервер!</font"; 

                  } else  $error_6="<b>Ошибка:</b> <font color=#FF0000>Неправильные размеры изображения. Измените, пожалуйста, размеры изображения до: ширина = 150px, высота максимально - 300px.</font>"; 
              } else $error_3="<b>Ошибка:</b> <font color=#FF0000>Такого фаила не существует</font>";
            } 
          else 
            {
               if($_FILES['image_path']['error'] === 1)
               { $msg="<b>Ошибка:</b> <font color=#FF0000>Размер файла ".BASENAME( $_FILES['image_path']['name'])." больше максимально допустимого размера, разрешённого директивой upload_max_filesize конфигурационного файла php.ini.</font>"; }
               if($_FILES['image_path']['error'] === 2)
               { $msg="<b>Ошибка:</b> <font color=#FF0000>Размер фаила ".BASENAME( $_FILES['image_path']['name'])." слишком большой. Допустимо не более 50Kб.</font>"; }
               if($_FILES['image_path']['error'] === 3)
               { $msg="<b>Ошибка:</b> <font color=#FF0000>Файл ".BASENAME( $_FILES['image_path']['name'])." был получен только частично.</font>"; }
               if($_FILES['image_path']['error'] === 4)
               { $msg="<b>Ошибка:</b> <font color=#FF0000>Файл не был загружен. Вероятнее всего Вы не выбрали файл.</font>"; }
            }
          }
        }
      }   
    }
.....
<? echo $error_1?>
<? 
echo $error_2?>
<? 
echo $error_3?>
<? 
echo $error_4?>
<? 
echo $error_5?>
<? 
echo $error_6?>
<? 
echo $msg?>
.....
<form action="<? $PHP_SELF?>" method="post" enctype=multipart/form-data>
<input type="hidden" name="post" value="Y">
<input type="hidden" name="MAX_FILE_SIZE" value="50000">
....
<input type="file" name="image_path" value="<? echo $image_path?>" size=25>
....
<input type="submit" value="Добавить"> 
</form>

Всем спасибо за помощь и ссылки на мануал.
Пойду выяснять про отличие copy и move_uploaded_file в аспекте безопасности.


Часовой пояс GMT +4, время: 08:38.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.