[PHP] Fatal Error bei kleinerem Array

strolch00

redraft.de
ID: 155297
L
21 April 2006
1.684
72
Hi @all,

wieso bringt mir PHP diesen Fehler
Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 12288 bytes) in /srv/www/web0/html/sawmill/core/class_img.php on line 158

bei dieser Zeile:
PHP:
$source = imagecreatefromjpeg($imgfile);

Das kuriose ist das dies eine klasse zum auslesen von Image Ordnern ist. Testen kann man es hier. Und der Fehler ist ist nur bei einem Ordner und zwar bei "Balla Geb 19" in dem sind aber kurioser weise weit weniger Bilder drin als in einem anderen.

Hoffe einer von euch weiß Rat.

Thx

*edit
Hier der komplette Code:
PHP:
<?php

   /* index.php von
    * chronicleofsawmill.de
    */

   ini_set('display_error', 1);
   error_reporting(E_ALL);

   define('FILE_DIR', 'files');				// Dateien ordner

   class list_dir
   {
      var $_global_dir;
      var $_handle;
      var $_subdir;
      var $_file_array;
      var $_file;
      var $_blacklist_array;
      var $_image_path_array;


      function __construct()
      {
         $this->_global_dir = 'files' . DIRECTORY_SEPARATOR;
         $this->_global_thumb_dir = 'thumbs' . DIRECTORY_SEPARATOR;
         $this->_file_array = array();
         $this->_blacklist_array = array('.', '..', 'Thumbs.db', 'thumbs');
         $this->_image_path_array = array();
      }

      function open_dir()
      {
         /*
          * Open Dir and put the files info´s into an array
          *
          */
         // verzeichnis auslesen
         $this->_handle = scandir($this->_global_dir);
         // unnötige dinge entfernen
         for($x = 0; $x <= count($this->_handle) - 1; $x++)
         {
            if(in_array($this->_handle[$x], $this->_blacklist_array))
               unset($this->_handle[$x]);
         }
         // array sortieren
         natsort($this->_handle);

         if(!empty($this->_handle))
         {
            // array durchgehen und ebenso auslesen
            foreach($this->_handle AS $k => $this->_subdir)
            {
               if(is_dir($this->_global_dir . DIRECTORY_SEPARATOR . $this->_subdir) && !in_array($this->_subdir, $this->_blacklist_array))
               {
                  $this->_file_array[$this->_subdir] = scandir($this->_global_dir . DIRECTORY_SEPARATOR . $this->_subdir);

                  // entfernt '.' und '..' und 'Thumb.db'
                  $_element_count = count($this->_file_array[$this->_subdir])- 1;
                  for($x = 0; $x <= $_element_count; $x++)
                  {
                     if(in_array($this->_file_array[$this->_subdir][$x], $this->_blacklist_array))
                        unset($this->_file_array[$this->_subdir][$x]);
                  }
              }
               else
                  continue;
            }
         }
         else
            $_SESSION['error'][] = 'Dir open error!';
      }

      /*
       *Überblickfunktion der file ordner
       *
       */
      function overview($_limit = 0)
      {
         $this->open_dir();

         // abbruchfunktion inklusive Blätterfunktion bauen
         $x_tmp = 0;
         $data = array();
         foreach($this->_file_array AS $k => $v)
         {
            $x_tmp++;
            $data[] = array('folder_link' => urlencode($k), 'link_title' => ucwords(str_replace('_', ' ', $k)));
         }

         return $data;
      }

      /*
       * Bilderauflistfunktion
       *
       */
      function watch_img($_dir_name, $_img_number = 0)
      {
         if(empty($this->_file_array))
            $this->overview();

         if(array_key_exists($_dir_name, $this->_file_array))
         {
            $_elements = count($this->_file_array[$_dir_name]);
            foreach($this->_file_array[$_dir_name] AS $k => $v)
            {
               $_img_tmp_file = $this->_global_dir . $_dir_name . DIRECTORY_SEPARATOR . $v;
               $_img_info = getimagesize($_img_tmp_file);
               $_img_info['correct_width'] = ceil($_img_info[0] / 2);
               $_img_info['correct_height'] = ceil($_img_info[1] / 2);

               $this->_image_path_array[] = array('img' => array('path' => '/' . $_img_tmp_file, 'width' => $_img_info['correct_width'], 'height' => $_img_info['correct_height'])
                                          , 'thumb' => $this->do_thumb($v, $this->_global_dir . $_dir_name));

               // del tmp vars
               unset($_img_tmp_file, $_img_info);
            }
            //echo"<pre>";print_r($this->_image_path_array);echo"</pre>";
            return $this->_image_path_array[$_img_number];
         }
      }

      // ------start thumbnailer -----------------------------
      function do_thumb($file, $dir)
      {
         if(file_exists($dir . DIRECTORY_SEPARATOR . $this->_global_thumb_dir) == FALSE)
            mkdir($dir . DIRECTORY_SEPARATOR . $this->_global_thumb_dir, 0755);		// verzeichnis anlegen wenns nicht existiert

         if(file_exists($dir . DIRECTORY_SEPARATOR . $this->_global_thumb_dir . $file) == FALSE)
         {
            $thumbsize = 150;
            $imgfile = $dir . DIRECTORY_SEPARATOR . $file;
            list($width, $height) = getimagesize($imgfile);
            $imgratio = $width / $height;
            if($imgratio > 1)
            {
               $newwidth = $thumbsize;
               $newheight = $thumbsize / $imgratio;
            }
            else
            {
               $newheight = $thumbsize;
               $newwidth = $thumbsize * $imgratio;
            }

            $end = explode(".", $imgfile);					//Endung filtern
            $endung = strtolower($end[count($end)-1]);	//Endung filtern
            if($endung == 'jpg' || $endung == 'JPG' || $endung == 'JPEG' || $endung == 'jpeg')
            {
               $thumb = ImageCreateTrueColor($newwidth, $newheight);
               $source = imagecreatefromjpeg($imgfile);
               imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
               imagejpeg($thumb, $dir . DIRECTORY_SEPARATOR . $this->_global_thumb_dir . 'thumb_' . $file, 100); //"uploads/images/thumbs/thumb_$file"
               imagedestroy($thumb);
               chmod($dir . DIRECTORY_SEPARATOR . $this->_global_thumb_dir . 'thumb_' . $file, 0755);
            }
         }

         return array('path' => $dir . DIRECTORY_SEPARATOR . $this->_global_thumb_dir . 'thumb_' . $file
                    , 'width' => floor($newwidth)
                    , 'height' => floor($newheight));
      }
      // -----------------------------------------------------

      function generate_thumblink($_array)
      {
         $ret_array = array();
         if(is_array($_array) && count($_array) == 2)
         {
            if($_array['img_number'] > 0)
               $ret_array['thumb_backward'] = array('number' => $_array['img_number'] - 1
                                                  , 'thumb' => $this->_image_path_array[$_array['img_number'] - 1]['thumb']['path']);
            else
               $ret_array['thumb_backward'] = NULL;

            $ret_array['thumb_current'] = array('number' => $_array['img_number']
                                               , 'thumb' => $this->_image_path_array[$_array['img_number']]['thumb']['path']);
            if($_array['img_number'] < count($this->_image_path_array) - 1)
               $ret_array['thumb_forward'] = array('number' => $_array['img_number'] + 1
                                                  , 'thumb' => $this->_image_path_array[$_array['img_number'] + 1]['thumb']['path']);
            else
               $ret_array['thumb_forward'] = NULL;
         }
         //echo"<pre>";print_r($ret_array);echo"</pre>";
         return $ret_array;
      }
   }
?>
In Zeile 120 wird es aufgerufen.
 
Zuletzt bearbeitet:
Der ganze Code wäre wohl von Vorteil, weil da wohl vorher ein Speicherleck sein wird.
 
Das heißt du verbrauchst zuviel Speicher... warum? Weil du die Bilder nicht aus dem Speicher entfernst. Du entfernst zwar die Thumbs aber das Quellbild lässt du im Speicher. Und warum das bei Ordnern mit relativ weinig Bilder passiert liegt einfach dran dass die Quellbilder da größer sein werden.

Fehler ist hier bei Zeile 155...
 
Hi Zero,

also wenn ich das richtig verstanden habe fehlt mir noch ein imagedestroy($source); das hat mir aber nix gebracht. Ich habe es eingefügt aberder Fehler besteht trotzdem noch.
Habe ich Dich jetzt falsch verstanden und meintest Du was anderes oder liegt der Fehler doch wo anders.
 
Hi Zero,

also wenn ich das richtig verstanden habe fehlt mir noch ein imagedestroy($source); das hat mir aber nix gebracht. Ich habe es eingefügt aberder Fehler besteht trotzdem noch.
Habe ich Dich jetzt falsch verstanden und meintest Du was anderes oder liegt der Fehler doch wo anders.

Ja so hab ich das gemeint. Das war eigentlich der offensichtlichste fehler in die Richtung. Entweder hast du ein Bild in dem Ordner was schon alleine den kompletten Speicher aufbraucht oder es ist irgendwo noch ein anderer Fehler vorhanden. Ich seh aber jetzt nix wirklich kritisches, von daher würde ich mal auf erstens tippen.
 
Also in dem Ordner waren Bilder mit 3MB Größe, jetzt habe ich allerdins gestern schon alle verkleiner auf 500kb maximal und es sind 5 oder 6 Bilder. In den anderen Ordnern sind teilweise 30 Bilder mit ~ 150kb.
 
Ich weiß jetzt nicht wie die GDLib arbeitet und wie sich das ganze auf den Speicher auswirkt. Aber im Worstcase hast du mindestens Weite*Höhe*3 (mindestens, die GDLib untersützt auch nen Alpha-Kanal). Also sollten die Bilder kleiner als 2000x1500 Pixel sein... aber ich schätze mal bei 500KB großen Jpegs bist du da je nach Quallität trüber.
 
Jap da hast du Recht nach der größe habe ich nicht geschaut ich code grad die klasse neu und danach ändere ich das mal. Hoffe das war die Lösung. Ich meld mich wieder.