Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Переполнение памяти, скрипт почему то не хочет очищать память 
V
    Опции темы
AGENTxXx
Дата 21.5.2015, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 231
Регистрация: 8.6.2009

Репутация: нет
Всего: 1



Добрый день уважаемые форумчане! 

Может есть люди, которые смогут тут увидеть, почему память не очищается. Не может загрузить изображение размером 18 мегабайт. Пока что поставил условие ini_set("memory_limit", -1); но хотелось бы понять всё равно причину. Задача класса - все изображения со статусом 2 залить на локальный сервер и поменять статус на 1
Код

<?php
class UploadModel {
    public static function getExternalImgs()
    {
        global $DB;

        $SQL = "SELECT id, link, preview FROM event_photos WHERE state = 2";
        $result = $DB->mysqliQuery($SQL);
        if (mysqli_num_rows($result) == 0) {
            return;
        }

        while ($row = mysqli_fetch_assoc($result)) {
            $answer = self::downloadExternalImg($row['link'],$row['preview']);
            $ok = 0;
            if (!empty($answer['link'])) {
                $SQL = "UPDATE event_photos SET link = '" . $answer['link'] . "' WHERE id = " . $row['id'];
                $DB->mysqliQuery($SQL);
                $ok++;
            }
            if (!empty($answer['preview'])) {
                $SQL = "UPDATE event_photos SET preview = '" . $answer['preview'] . "' WHERE id = " . $row['id'];
                $DB->mysqliQuery($SQL);
                $ok++;
            }

            if ($ok == 2) {
                $SQL = "UPDATE event_photos SET state = 1 WHERE id = " . $row['id'];
                $DB->mysqliQuery($SQL);
            }
            
        }
    }

    public static function downloadExternalImg($link, $preview)
    {

        $allowed = array('png', 'jpg', 'gif','zip');

        if (!empty($link)) {
            $content = file_get_contents($link);
            //$header = self::parseHeaders($http_response_header);
            $img = imagecreatefromstring($content);
            //$width = $imgsize[0];
            //$height = $imgsize[1];
            //var_dump(imagesx($img), imagesy($img), $header); die;

            $extension = pathinfo($link, PATHINFO_EXTENSION);

            if(!in_array(strtolower($extension), $allowed)){
                return false;
            }

            $name = md5($link) . "." . $extension;
            file_put_contents("images/upload/long/" . $name,$content);

            if (imagesy($img) > 1500) {
                self::resize("images/upload/long/" . $name,"images/upload/long/" . $name,1000);
            }
            unset($content);
            unset($img);
         $new_link = "images/upload/long/" . $name;
        }
        else {
            $new_link = null;    
        }

        if (!empty($preview)) {
            if (empty($name)) {
                $name = md5($preview) . "." . $extension;
            }
            $content = file_get_contents($preview);
            $img = imagecreatefromstring($content);

            $extension = pathinfo($preview, PATHINFO_EXTENSION);

            if(!in_array(strtolower($extension), $allowed)){
                return false;
            }

         file_put_contents("images/upload/preview/" . $name,$content);

         if (imagesy($img) > 1500) {
                self::resize("images/upload/preview/" . $name,"images/upload/preview/" . $name,1000);
            }

            unset($content);
            unset($img);
         $new_preview = "images/upload/preview/" . $name;
        }
        else {
            $new_preview = null;    
        }

     return array("link" => $new_link, "preview" => $new_preview);
    }

    //Получаем заголовки ответа при запросе
    public static function parseHeaders( $headers )
    {
        $head = array();
        foreach( $headers as $k=>$v )
        {
            $t = explode( ':', $v, 2 );
            if( isset( $t[1] ) )
                $head[ trim($t[0]) ] = trim( $t[1] );
            else
            {
                $head[] = $v;
                if( preg_match( "#HTTP/[0-9\.]+\s+([0-9]+)#",$v, $out ) )
                    $head['reponse_code'] = intval($out[1]);
            }
        }
        return $head;
    }

    public static function resize($file_input, $file_output, $w_o, $h_o = 0, $percent = false) {
        list($w_i, $h_i, $type) = getimagesize($file_input);
        if (!$w_i || !$h_i) {
            echo 'Невозможно получить длину и ширину изображения';
            return;
            }
            $types = array('','gif','jpeg','png');
            $ext = $types[$type];
            if ($ext) {
                 $func = 'imagecreatefrom'.$ext;
                 $img = $func($file_input);
            } else {
                 echo 'Некорректный формат файла';
            return;
            }
        if ($percent) {
            $w_o *= $w_i / 100;
            $h_o *= $h_i / 100;
        }
        if (!$h_o) $h_o = $w_o/($w_i/$h_i);
        if (!$w_o) $w_o = $h_o/($h_i/$w_i);

        $img_o = imagecreatetruecolor($w_o, $h_o);
        imagecopyresampled($img_o, $img, 0, 0, 0, 0, $w_o, $h_o, $w_i, $h_i);
        if ($type == 2) {
            return imagejpeg($img_o,$file_output,60);
        } else {
            $func = 'image'.$ext;
            return $func($img_o,$file_output);
        }
    }
}
?>

Ах да, вот ошибка: "PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 18208578 bytes) in /home/admin/web/prokoder.ru/public_html/models/UploadModel.php on line 55"
Есть идеи, как освободить память?
PM MAIL   Вверх
baldina
Дата 21.5.2015, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



вижу вызов
Цитата(AGENTxXx @  21.5.2015,  16:05 Найти цитируемый пост)
$img = imagecreatefromstring($content);

без imagedestroy()

судя по тексту $img толком не используется, и imagecreate() вообще не нужна (если нужно, imagesy() можно заменить на getimagesize(), который кстати используется в resize())
в resize() опять же нужен imagedestroy()

если resize() не нужен, можно вообще не читать файл в память, а использовать copy или stream_copy_to_stream()

Это сообщение отредактировал(а) baldina - 21.5.2015, 17:30
PM MAIL   Вверх
baldina
Дата 21.5.2015, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



Код

public static function downloadExternalImg($link, $preview)
{
...
        if (!empty($link)) {
            ...
            $filename = "images/upload/long/" . $name;
            copy ($link, $filename);
            list($w, $h) = getimagesize($filename);

            if ($h > 1500) {
                self::resize($filename, $filename,1000);
            }
...
}

public static function resize($file_input, $file_output, $w_o, $h_o = 0, $percent = false) 
{
...
        imagecopyresampled($img_o, $img, 0, 0, 0, 0, $w_o, $h_o, $w_i, $h_i);
        imagejpeg($img_o,$file_output,60);
        imagedestroy($img_o);
        imagedestroy($img);
...        
}

PM MAIL   Вверх
AGENTxXx
Дата 22.5.2015, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 231
Регистрация: 8.6.2009

Репутация: нет
Всего: 1



Т.е. я правильно понимаю что unset() автоматом не выполнит освобождение и нужно в начале вызывать imagedestroy() а потом только unset()?

На счёт copy - спасибо! Вроде как должен подойти. Я просто думал, что copy только на локальном сервере работать может...
PM MAIL   Вверх
baldina
Дата 22.5.2015, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



unset удалит переменную, но не память с ней связанную: $img это ресурс, и должен освобождаться явно
PM MAIL   Вверх
AGENTxXx
Дата 22.5.2015, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 231
Регистрация: 8.6.2009

Репутация: нет
Всего: 1



Мда... я думал, что unset умный))) Окей) Спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0643 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.