ошибка imagecreatefromjpeg memory size [PHP]
если я правильно понимаю текст ошибки то передаваемый лимит 16 777 216 байт, а я передаю 6 400 байт что в разы меньше
не пойму в чем причина? ошибка возникает уже не первый раз
при чем, что самое смешное, файл размером 500 Кб функция обработала без вопросов
само изображение во вложении. настройки сервера:
memory_limit 16Mb
post_max_size 16Mb
upload_max_filesize 16Mb
если я правильно понимаю текст ошибки то передаваемый лимит 16 777 216 байт, а я передаю 6 400 байт:
Передавать то ты можешь и передаешься, только JPEG в расжатом видем занимает место в ОЗУ вразу большее, чем сам файл. Зависит от многих факторов, но вот для примера в одном из моих проектов при загрузке фоток на хостинг размером 2,5МБ, в ОЗУ при обработке эта же фота занимала 45МБ. Но это был крайний случае, обычно соотношение там было 1:10.
Поэтому выдаваемая ошибка правильно. Сказано, что лимит памяти превышен, значит так оно и есть.
P.S. А вот теперь догадайся, почему для фото хостингов берут выделенный сервер ;)
мне как раз нужна активная работа с фото
мне как раз нужна активная работа с фото
Ну выход тогда очевиден: смена хостера или тарифного плана.
imagecreatefromjpeg() возвращает ошибку уровня E_ERROR (фотальная ошибка)
естественно мне это ненужно
необходимо как-то предупредить возникновение ошибки
в js есть схема try..catch, насколько я понимаю в php такой нет
вызов функции
if (function_exists($type) && ($this->image=@$type($this->root.$file))){
@chmod($this->root.$file, 0777);
return $this->image;
} else {
return FALSE;
}
}
код должен предотвращать все ошибки,
но в некоторых случаях, когда возникает ошибка,
он все таки выдает Fatal error (если нет @) и прерывает работу кода
все что приходит в голову это юзать set_error_handler()
вот и у меня по воспоминаниям эта конструкция была, а в поиске по ману ее нет :(
видать опять что-то накрутил
вот мой код, тоже что и в мане
// проверяю установлена ли функция
if (!function_exists($type)) return FALSE;
try {
if ($this->image=@$type($this->root.$file)){ // здесь возникает ошибка которую не удается перехватить
// если все отработало нормально открываю права на файл
@chmod($this->root.$file, 0777);
} else {
// в случае ошибки возвращаю ее
throw new Exception('Fatat error: excess memory size');
}
} catch (Exception $e){
// в случае ошибки возвращаю FALSE
return FALSE;
}
// если все успешно, возвращаю ссылку на объект картинки
return $this->image;
}
откуда возникает эта ошибка мы разобрались
что с ней делать тоже
но я так и непонял как мне перехватить ошибку уровня E_ERROR
через try...catch не получается
вот такой вариант работает
throw new Exception('error');
} catch (Exception $e){
echo $e->getMessage();
}
и даже такое работает
try {
if ($a){
echo $a*10;
} else {
throw new Exception('error');
}
} catch (Exception $e){
echo $e->getMessage();
}
а так нет
if ($image=imagecreatefromjpeg($root.$file)){
return $image;
} else {
throw new Exception();
}
} catch (Exception $e){
return FALSE;
}
ошибка возникает в условии обрубая работу кода накорню
и через set_error_handler не сделаешь,
так как handler обрабатывает ошибки только семейства E_USER
собственно говоря я через iframe загружаю рисунок на сервер и делаю ресайз через GD, а далее возвращаю результат в JS скрипт и отображаю результат на экране вполне естественно что меня не устраивает возникновение фатальной ошибки, которая не может ничего вернуть на страницу
но даже без этого. в обычной ситуации фатальная ошибка в GD при ресайзе изображения после загрузки означает что изображение не было полностью обработано и требует выбора другого файла для загрузки, а что же с тем файлом который мы уже загрузили но не смогли обработать. он теперь валяется как мусор на сервере и занимает место
пока работает, хотя количество процентов на расходы пришлось увеличить до 25%
тестировал пока только на одной фотографии (2995х4500px 3157Kb)
сейчас буду активно тестировать на других
кстати, во время проверки выяснилось, что переопределение переменных занимает больше места в памяти
чем просто удаление и повторное определение той же переменной
для многих это естественно, но для меня это оказалось неожиданностью
вопрос об экономии системных ресурсов стал вполне актуальным
это точно :D
видать опять что-то накрутил
вот мой код, тоже что и в мане
// проверяю установлена ли функция
if (!function_exists($type)) return FALSE;
try {
if ($this->image=@$type($this->root.$file)){ // здесь возникает ошибка которую не удается перехватить
// если все отработало нормально открываю права на файл
@chmod($this->root.$file, 0777);
} else {
// в случае ошибки возвращаю ее
throw new Exception('Fatat error: excess memory size');
}
} catch (Exception $e){
// в случае ошибки возвращаю FALSE
return FALSE;
}
// если все успешно, возвращаю ссылку на объект картинки
return $this->image;
}
Вопрос, зачем строить подобный метод? Как я понимаю все это награмождено ради проверки существования функции, что-то громозко... и еще не совсем понимаю как это относится к imagecreatefromjpeg.
вообще проверку на существование функции выполняет только одна строка из всего кода
эта проверка проводится для того что бы убедится в том что модуль GD включен и переданная функция существует
остальная же часть кода предназначена для проверки на успешность выполнения функции, к сожалению она не отрабатывает так как надо
здесь стоит пояснить
это внутренняя функция класса предназначенного для работы с GD
в GD есть ряд схожих по работе функций таких как imagecreatefromjpeg, imagecreatefromgif, imagecreatefrompng, imagecreatefromwbmp
вместо того чтобы реализовывать проверку при инициализации каждой из функций я создал дополнительный метод который выполняет инициализацию и к которому обращаются вызывающие методы как к внутреннему методу
...
function create_jpeg($file){
return $this->_create($file, "imagecreatefromjpeg");
}
function create_gif($file){
return $this->_create($file, "imagecreatefromgif");
}
function _create($file, $type){
if (!function_exists($type)) return FALSE;
try {
if ($this->image = $type($this->root.$file)){
return $this->image;
} else {
throw new Exception();
}
} catch (Exception $e){
return FALSE;
}
}
...
}
такой API не очень удобен, но выглядит яснее и короче ИМХО