Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Ошибка при imagejpeg
 
 автор: Киналь   (23.05.2008 в 19:03)   письмо автору
 
 

Функция imagejpeg() в случае неудачи возвращает FALSE. Можно ли как-то узнать, почему именно произошла ошибка? Необходимость в этом возникла потому, что срабатывает эта функция "через раз", то есть не в скрипте дело.

   
 
 автор: sim5   (23.05.2008 в 19:33)   письмо автору
 
   для: Киналь   (23.05.2008 в 19:03)
 

Если бы возвращался номер ошибки, тогда... Узнавать причину косвенно, при каких условиях не работает, исходя из этого искать причину.

   
 
 автор: Киналь   (23.05.2008 в 20:08)   письмо автору
 
   для: sim5   (23.05.2008 в 19:33)
 

Вот в том-то и дело, что номера нет) Надеялся, вдруг есть что-то вроде mysql_error, хотя, конечно, откуда бы?=)
Эта функция у меня используется в самописной (и довольно длинной) функции загрузки картинок с их и уменьшение; при записи умеьшенной копии ошибка и происходит. Некоторые файлы нормально загружаются, а некоторые нет; так вот. не скажете, по каким критериям сравнивать эти файлы? В смысле. вот выясню я, что файл А загружается, а файл Б - нет; как мне выявить, что вызывает сбой?

   
 
 автор: sim5   (23.05.2008 в 20:32)   письмо автору
 
   для: Киналь   (23.05.2008 в 20:08)
 

Зато при загрузке файла можно просмотреть ошибку: $_FILES['fieldname']['error']. Вполне возможно, что не закачивается по тем или иным причинам файл, ну и соответсвенно отсюда далее ошибки.

   
 
 автор: Киналь   (23.05.2008 в 23:24)   письмо автору
 
   для: sim5   (23.05.2008 в 20:32)
 

Да это-то проверяется. Ладно, буду колдовать) Спасибо за помощь.

   
 
 автор: Trianon   (23.05.2008 в 22:33)   письмо автору
 
   для: Киналь   (23.05.2008 в 20:08)
 

а памяти процессу хватает?

   
 
 автор: Киналь   (23.05.2008 в 23:25)   письмо автору
 
   для: Trianon   (23.05.2008 в 22:33)
 

Да вроде хватает. Говорю ж, только на некоторых файлах спотыкается.

   
 
 автор: Trianon   (23.05.2008 в 23:29)   письмо автору
 
   для: Киналь   (23.05.2008 в 23:25)
 

так только некоторые картинки могут быть достаточно большими по размеру.
А меж тем открытая картинка занимает места в памяти h * w * 4

   
 
 автор: Киналь   (24.05.2008 в 00:45)   письмо автору
 
   для: Trianon   (23.05.2008 в 23:29)
 

Ну, проверю, конечно, но при 2 Гб оперативки на локальной машине такое вряд ли возможно)

   
 
 автор: Trianon   (24.05.2008 в 00:50)   письмо автору
 
   для: Киналь   (24.05.2008 в 00:45)
 

а для самого php MEMORY LIMIT не стоит ?

   
 
 автор: Anonymous   (24.05.2008 в 00:58)
 
   для: Trianon   (23.05.2008 в 23:29)
 

> А меж тем открытая картинка занимает места в памяти h * w * 4

А почему именно столько занимает каждый пиксель (4 байта)? 0xFFFFFFFF цветов что ли?

   
 
 автор: Trianon   (24.05.2008 в 01:02)   письмо автору
 
   для: Anonymous   (24.05.2008 в 00:58)
 

Я не убежден на 100%, но ничего удивительного мне в этом не кажется.
Три цвета плюс альфа-канал - четыре сэмпла по восемь бит (выражаясь в терминах TIFF :)
А даже если три? Мало чтоли? :))

   
 
 автор: Anonymous   (24.05.2008 в 01:06)
 
   для: Trianon   (24.05.2008 в 01:02)
 

Я мало имел дела с расширением GD в PHP, но вроде без применения imagesavealpha() информации об альфа-канале быть не должно.

   
 
 автор: Trianon   (24.05.2008 в 01:54)   письмо автору
 
   для: Anonymous   (24.05.2008 в 01:06)
 

Я сейчас специально поставил несколько опытов с imagecreatefromjpeg и memory_get_usage
Затраты памяти оказываются примерно равными С + 5 * h * w
Так что пять байт на пиксель.

   
 
 автор: sim5   (24.05.2008 в 08:05)   письмо автору
 
   для: Trianon   (24.05.2008 в 01:54)
 

Специально попробовал файлы размером более 2 МБ - от 4 до 8, на локальном под Денвером GD даже не чихает, спокойно получаются малые копии, заметно возрастает время обработки, только лишь всего.
Может я выскажу крамольную мысль, но мне кажется, что причина где-то в скрипте автора, в логике его работы.

   
 
 автор: AVS   (24.05.2008 в 08:13)   письмо автору
 
   для: Trianon   (24.05.2008 в 01:54)
 

> С + 5 * h * w

А что такое C?

   
 
 автор: Киналь   (30.05.2008 в 22:01)   письмо автору
 
   для: Киналь   (23.05.2008 в 19:03)
 

Проверил настройки сервера - практически совпадают с настройками на localhost'е, только размер POST-данных 4 Мб вместо 8-ми. Видимо, ошибка где-то в логике. Причем сам я видел сбой пару раз, и теперь не могу никак повторить; заказчик же, по его утверждению, вообще работать не может из-за этого.

Вобщем, большая просьба ткнуть носом в возможные слабые места вот этого кода (извините за размер, на всякий случай ничего вырезать не стал):

<?php
function image_upload($f_name$f_type$f_tmp_name$f_error$f_size$filename,
$copyright=""$path="../img/"$width=100)
{

$file_arr = array('name' => $f_name'type' => $f_type'tmp_name' => $f_tmp_name,
'error' => $f_error'size' => $f_size);

$type=trim($file_arr['type']);
/*
echo "<pre>";
print_r($file_arr);
echo "</pre>";
//die();
*/

$valid_types=array('image/jpeg''image/pjpeg''image/png''image/x-png''image/gif''image/vnd.wap.wbmp');
if (!
in_array($type$valid_types))
     
error("К сожалению, формат файла не поддерживается.
          Допустимы форматы JPEG, PNG, GIF, WBMP.
          Закачиваемый файл имеет MIME-тип 
$type"$_SERVER['HTTP_REFERER']);


//          $real = realpath($path.$filename);
          
$real_path realpath($path);
//            $real_path = $path;
          
$real $real_path."/".$filename;
          
//die($path." Realpath: ".$real);

if (!move_uploaded_file($file_arr['tmp_name'], $real))
     
error("Произошла ошибка при загрузке файла.
          Код ошибки - 
$file_arr[error]"$_SERVER['HTTP_REFERER']);

//Основной файл закачан, тип проверен. можно работать дальше.

$imagesize=getimagesize($real);
$img_x=$imagesize[0];
$img_y=$imagesize[1];

$division=$img_x/$img_y;
$small_x=$width;
$small_y=$small_x/$division;

//Создаем пустое изображение
$small_res=imagecreatetruecolor($small_x$small_y);

//Создаем изображение из основного файла
switch ($type)
{
        case(
'image/jpeg'):
              {
               
$main_res=imagecreatefromjpeg($real);
               break;
              }
        case(
'image/pjpeg'):
              {
               
$main_res=imagecreatefromjpeg($real);
               break;
              }
               case(
'image/gif'):
              {
               
$main_res=imagecreatefromgif($real);
               break;
              }
        case(
'image/png'):
              {
               
$main_res=imagecreatefrompng($real);
               break;
              }
        case(
'image/x-png'):
              {
               
$main_res=imagecreatefrompng($real);
               break;
              }
        case(
'image/wbmp'):
              {
               
$main_res=imagecreatefromwbmp($real);
               break;
              }
// end of switch

if (
    !
imagecopyresampled($small_res$main_res0000$small_x$small_y$img_x$img_y)
    )
    
error("Ошибка при создании уменьшенной копии.");

//записываем на диск копию

if (
    !
imagejpeg($small_res$real_path.'/small/small_'.$filename)
   )
   die(
"Ошибка при записи уменьшенной копии.");

// Вписываем копирайт
// Пишем черным цветом
$black=imagecolorallocate($main_res000);
imagestring($main_res599$copyright$black);
// Пишем белым цветом; результат - белый с черным контуром
$color=imagecolorallocate($main_res255255255);
imagestring($main_res41010$copyright$color);

switch (
$type)
{
        case(
'image/jpeg'):
              {
               
$m_rec=imagejpeg($main_res$real);
               break;
              }
        case(
'image/pjpeg'):
              {
               
$m_rec=imagejpeg($main_res$real);
               break;
              }
        case(
'image/gif'):
              {
               
$m_rec=imagegif($main_res$real);
               break;
              }
        case(
'image/png'):
              {
               
$m_rec=imagepng($main_res$real);
               break;
              }
        case(
'image/x-png'):
              {
               
$m_rec=imagepng($main_res$real);
               break;
              }
        case(
'image/wbmp'):
              {
               
$m_rec=imagewbmp($main_res$real);
               break;
              }
// end of switch

if (!$m_rec)
     {
      
error("Ошибка сохранения изображения.");
     }


//Все кончилось хорошо; уничтожаем все изображения
imagedestroy($main_res);
imagedestroy($small_res);

}
?>

   
 
 автор: sim5   (30.05.2008 в 22:47)   письмо автору
 
   для: Киналь   (30.05.2008 в 22:01)
 

Вот если бегло, то сперва нужно удостовериться, что файл закачан, а потом делать малую копию его (если уменьшается при загрузке файла), либо проверять непосредственно его наличие в указанном месте (уже после загрузки). А так получается ориентируемся, как я понимаю, на временный файл в tmp папке, а его после копирования там уже может и не быть, а источник то берем закачанный. В остальном то все нормально. if (move_uploaded_file()) делать до вызова функции, и все должно работать. Кстати, это - "К сожалению, формат файла не поддерживается", тоже лучше проверять до копирования файла в каталог.

   
 
 автор: Киналь   (30.05.2008 в 23:02)   письмо автору
 
   для: sim5   (30.05.2008 в 22:47)
 

> А так получается ориентируемся, как я понимаю, на временный файл в tmp папке, а его после копирования там уже может и не быть, а источник то берем закачанный. В остальном то все нормально. if (move_uploaded_file()) делать до вызова функции, и все должно работать.

Массив $file_arr - это, фактически, копия элемента $_FILES, то есть получается то же самое, как если бы проверка загрузки стояла до вызова. Хотя проверку существования в указанном месте сделаю на всякий случай, надо ж хоть что-то поменять) Спасибо за совет.

>Кстати, это - "К сожалению, формат файла не поддерживается", тоже лучше проверять до копирования файла в каталог.

Так и есть - сначала проверка, потом move_uploaded_file()

   
 
 автор: sim5   (30.05.2008 в 23:14)   письмо автору
 
   для: Киналь   (30.05.2008 в 23:02)
 

Ну уж нет, тут как раз у вас и проблемы скорее всего. Нужно проходить массив FILES, проверяя is_uploaded_file($_FILES['upld']['tmp_name']) (проверяем загрузку в tmp каталог), и если загружен, то проверив допустимое расширение, вызываем функцию, а в ней копируем файл в каталог и делаем его малую копию.

PS. Кстати, как это понять:


<?
if (!move_uploaded_file($file_arr['tmp_name'], $real)) 
     
error("Произошла ошибка при загрузке файла. 
          Код ошибки - 
$file_arr[error]"$_SERVER['HTTP_REFERER']);


если после этого никаких действий, т.е. выполнение кода не прерывается?

   
 
 автор: Киналь   (30.05.2008 в 23:23)   письмо автору
 
   для: sim5   (30.05.2008 в 23:14)
 

Хм, честно говоря, разницы не вижу. Перед вызовом у меня сейчас проверяется размер файла ($_FILES['name']['size']); то есть функция вызывается только если файл на сервер вообще пришел, и дальше в функции уже загружается.
Хотя чем спорить, просто наставлю проверок существования файлов, и посмотрим, что получится.

   
 
 автор: BinLaden   (31.05.2008 в 02:06)   письмо автору
 
   для: sim5   (30.05.2008 в 23:14)
 

> если после этого никаких действий, т.е. выполнение кода не прерывается?

Откуда нам знать, что в error()?

   
 
 автор: Киналь   (31.05.2008 в 10:43)   письмо автору
 
   для: sim5   (30.05.2008 в 23:14)
 

error() - это вывод сообщения "Произошла ошибка" и die().

   
 
 автор: sim5   (31.05.2008 в 10:51)   письмо автору
 
   для: Киналь   (31.05.2008 в 10:43)
 

Вопрос - а вы случаем не проверяли, какое количество файлов у вас обрабатывается и загружается (в реальную папку, не tmp) стабильно? Дело в том, что я сейчас проверяю подобное у себя. Заметил таку вещь, я пробую загружать и обрабатывать файлы размером по 2.9 МБ, стабильно обрабатываются только 5 штук, хотя загрузка на сервер происходит больше 5 файлов. Уже при загрузке 6 файлов, наблюдается сбой - это можно даже увидеть косвенно, по поведению прогресс бара в IE.
Вчера было уже позно, сейчас продолжу исследования этого явления. ))

   
 
 автор: Киналь   (31.05.2008 в 12:26)   письмо автору
 
   для: sim5   (31.05.2008 в 10:51)
 

Пытался. Но, говорю ж, баг какой-то хаотичный - я его пару раз только видел, повторить не получается, так что никаких экспериментов. Файлов загружается не больше 4-х сразу, причем, по словам заказчика, затык присходит даже при загрузке 4-х файлов по 150 Кб. Я загружал по 400 Кб каждый - ничего. Хотя уже из интереса попробую, найду только картинку потяжелее)

   
 
 автор: sim5   (31.05.2008 в 12:30)   письмо автору
 
   для: Киналь   (31.05.2008 в 12:26)
 

Вы погодите нервничать, у меня стабильна загрузка для 5 больших, экспириенс (как говорит Trianon) никогда не помешает :), в чем-то кроется ведь проблема. Мне нужен был ваш ответ - сейчас продолжим изыскания.)

   
 
 автор: sim5   (04.06.2008 в 10:21)   письмо автору
 
   для: Киналь   (23.05.2008 в 19:03)
 

Ну и как дела?) Сколько я не пробовал, не полуается у меня глюков зависящих от размера и прочего, кроме от числа закачиваемых файлов. Вот на это я так и не нашел ответа, облазил весь php.ini и http.conf, что там может влиять на такой баг - что под Денвер, что на реальном сервере закачиватся только 5 файлов, вернее закачиватся в папку tmp сервера все, которые определены в форме, а вот копируются в реальную папку, только первые 5 из массива FILES формы. То есть, если в форме заполнить первые три поля, а затем, например, еще два, но через поля 2-3, то будет сохранено только три файла. Если указать все подряд, например, 10 полей, то сохранятся только первые 5 (FILES[0]-FILES[4]). Кто знает чем это определяется?

Кстати, определять закачку по, типа: if ($_FILES['name']['size'])... как вы писали, это не правильно. Здесь есть проблема с закачкой файлов нулевой длины. Суть ее не в том что файлы не закачиваются, а в том что невозможно определить закачался ли файл на самом деле. В случае когда файл не закачался и в случае пустого файла, переменная будет равна 0. Если в поле напечатать имя несуществующего файла, то это будет передано как файл с нулевой длиной.

   
 
 автор: Киналь   (04.06.2008 в 10:51)   письмо автору
 
   для: sim5   (04.06.2008 в 10:21)
 

А никак) При больших файлах идет просто превышение upload_max_filesize; так что понаставил проверок и отправил заказчику. Вроде больше проблем не возникало) Возиться с экспериментами, честно говоря, особо времени нет - сессия в разгаре.


>Кстати, определять закачку по, типа: if ($_FILES['name']['size'])... как вы писали, это не правильно. Здесь есть проблема с закачкой файлов нулевой длины. Суть ее не в том что файлы не закачиваются, а в том что невозможно определить закачался ли файл на самом деле. В случае когда файл не закачался и в случае пустого файла, переменная будет равна 0. Если в поле напечатать имя несуществующего файла, то это будет передано как файл с нулевой длиной.

Какая разница-то? Главное, что файла с фотографией нет, работать не с чем.

   
 
 автор: sim5   (04.06.2008 в 11:23)   письмо автору
 
   для: Киналь   (04.06.2008 в 10:51)
 

Ну большие файлы это известная проблема, а как по числу закачиваемых одновременно файлов у вас? Дело в том, что ограничение в 5 файлов, у меня не завист от их размера, или их суммарного размера. Сколько файлов у вас закачивается одновременно?

   
 
 автор: mihdan   (04.06.2008 в 12:38)   письмо автору
 
   для: sim5   (04.06.2008 в 11:23)
 

Не поверите тестил upload у себя на сервере и столкнулся с этой же проблемой - и тоже только 5 файлов ;( Странно. В инете не нарыл ничего особого, в php.ini, httpd.conf тоже. У кого появится предположение - милости просим поделиться

Киналь , у вас случаем не русский Апач?

   
 
 автор: Киналь   (04.06.2008 в 13:25)   письмо автору
 
   для: mihdan   (04.06.2008 в 12:38)
 

У меня Денвер (второй версии). Только что благополучно закачалось и обработалось семь файлов общим весом 1.3 Мб. Попробовал "вразбивку", с пропусками полей в форме - тоже нормально. На сервере не проверял от греха подальше)

   
 
 автор: sim5   (04.06.2008 в 13:52)   письмо автору
 
   для: Киналь   (04.06.2008 в 13:25)
 

У меня Денвер 3, фиг с ним, пусть даже, если у меня эксклюзив его ), то такая же лажа у меня получается и с реальным сервером. Видимо глюк никак не связан непосредственно с сервером (и Денвером).

   
 
 автор: sim5   (04.06.2008 в 14:11)   письмо автору
 
   для: mihdan   (04.06.2008 в 12:38)
 

Во! Только заметил, mihdan, точно ограничение на 5 файлов!? Ладно, предположим, что дело все таки в настройках сервера, осталось сравнить их с Денвером 2, ну что-то не припомню, чтобы там отличалось чем-то кардинальным...

PS. По поводу русского:

Файлы могут быть испорченными если под Апачем запущены некоторые модули, например mod_charset (известный как Russian Apache). Его можно выключить для определенных файлов:

<Files upload.php>
CharsetDisable On
</Files>

Вы это имеете ввиду?

   
 
 автор: mihdan   (04.06.2008 в 15:36)   письмо автору
 
   для: sim5   (04.06.2008 в 14:11)
 

to sim5
1. Да именно 5 файлов и неважно какого размера
2. Да про это самое

   
 
 автор: sim5   (04.06.2008 в 16:11)   письмо автору
 
   для: mihdan   (04.06.2008 в 15:36)
 

Ну значит фича связана с другим - в Денвер 3, этот модуль не подключается.

   
 
 автор: mihdan   (04.06.2008 в 16:22)   письмо автору
 
   для: sim5   (04.06.2008 в 16:11)
 

Это точно! Прогнал еще на 2х серверах - один оказался также бажный, на локалке под Денвером работает нормально. Интересный баг

   
 
 автор: sim5   (04.06.2008 в 16:42)   письмо автору
 
   для: mihdan   (04.06.2008 в 16:22)
 

Прикрипите конфигурационные файлы свого Денвера, сличить. Что-то тут не то.

   
 
 автор: mihdan   (04.06.2008 в 17:10)   письмо автору
26.2 Кб
 
   для: sim5   (04.06.2008 в 16:42)
 

php.ini, httpd.conf в аттаче

   
 
 автор: sim5   (04.06.2008 в 17:28)   письмо автору
 
   для: mihdan   (04.06.2008 в 17:10)
 

Вы под Денвером романы пишите?))

max_execution_time = 3000
max_input_time = 6000

Нет, все это не влияет на эту фичу, ничем экстраординарным ваши конфиги не отличаются. Если у вас под Денвером действительно нет ограничений, то скиньте архив всех конфигурационных файлов Апач, а так же архив скриптов Денвера (перловку), может быть в них причина.

   
 
 автор: mihdan   (04.06.2008 в 17:40)   письмо автору
33.2 Кб
 
   для: sim5   (04.06.2008 в 17:28)
 

Да ща на Денвере сижу - порадовал меня Котеров. Сейчас прикреплю

   
 
 автор: sim5   (04.06.2008 в 17:59)   письмо автору
 
   для: mihdan   (04.06.2008 в 17:40)
 

Сделайте архив скриптов Денвера (папки denwer\scripts\init.d и denwer\scripts\lib), перловка его, может причина в них, конфигурацию я уже всю испробовал, не в ней дело.

   
 
 автор: mihdan   (04.06.2008 в 17:55)   письмо автору
54.5 Кб
 
   для: sim5   (04.06.2008 в 17:28)
 

А вот скрипты перловские

   
 
 автор: sim5   (04.06.2008 в 18:01)   письмо автору
 
   для: mihdan   (04.06.2008 в 17:55)
 

Все, принято, будем посмотреть.

   
 
 автор: mihdan   (04.06.2008 в 18:08)   письмо автору
 
   для: sim5   (04.06.2008 в 18:01)
 

Я тож копаю, но пока безрезультатно, если у вас что-то получится, сообщите обязательно.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования