Delay a while loop in PHP to prevent memory exhaustion?
<p>I have a pretty simple image resize script that loops through 1000 folders, with different amounts of images in each folder. On my testing server, there aren't a lot of images, so it runs fine...but live with about 100K images...it will run into the memory problem. The php memory is already set to 384M, but i'd rather have the script maybe only process 10 folders at a time, stop for a bit, then start again. How can I do that within the while loop? use the sleep function maybe?</p>

<p>Here it is...</p>

<pre><code>class DevTestHelper {


//This will Go through all full size images and resize images into requested folder
function resizeGalleryImages($destFolder, $width, $height, $isCrop = false) {

    $count = 1000;

    $source = JPATH_SITE."/images/gallery/full";
    $dest = JPATH_SITE."/images/gallery/".$destFolder;

    echo 'Processing Images&lt;br&gt;';

    //Loop through all 1000 folders 0 to 999 in the /full dir
    for($i=0; $i &lt; $count;$i++) {
        $iPath = $source.'/'.$i;
        if(is_dir($iPath)) {

                $h = opendir($iPath);
                //Loop through all the files in numbered folder
                while ($entry = readdir($h)) {

             //only read files
                    if ($entry != "." &amp;&amp; $entry != ".." &amp;&amp;        !is_dir($entry)) {
              $img = new GImage($source.'/'.$i.'/'.$entry);

                        $tmp = $img-&gt;resize($width, $height, true, 3);

                        if($isCrop) {
                            $tmpWidth = $tmp-&gt;getWidth();
                            $tmpHeight = $tmp-&gt;getHeight();

                            $xOffset = ($tmpWidth - $width) / 2;
                            $yOffset = ($tmpHeight - $height) / 2;

                            $tmp-&gt;crop($width, $height, $xOffset, $yOffset, false, 3);
                        }

                        $destination = $dest.'/'.$i.'/'.$entry;

                        if(!$tmp-&gt;toFile($destination)) {
                            echo 'error in creating resized image at: '.$destination.'&lt;br&gt;';
                      }

                      flush();
          ob_flush();
          sleep(10);
                      echo $entry ;
                      //echo $entry.'&lt;br&gt;';
            }

                }

            echo 'Processed: '.$i.' Folder&lt;br&gt;';

        }
    }
</code></pre>

<p>Thanks for any suggestions.</p>

<pre><code>/**
* Class to manipulate an image.
*
* @package      Gallery.Libraries
* @subpackage   Media
* @version      1.0
*/
class GImage extends JObject
{
/**
 * The image handle
 *
 * @access  private
 * @var     resource
 */
var $_handle = null;

/**
 * The source image path
 *
 * @access  private
 * @var     string
 */
var $_path = null;

var $_support = array();

/**
 * Constructor
 *
 * @access  public
 * @return  void
 * @since   1.0
 */
function __construct($source=null)
{
    // First we test if dependencies are met.
    if (!GImageHelper::test()) {
        $this-&gt;setError('Unmet Dependencies');
        return false;
    }

    // Determine which image types are supported by GD.


    $info = gd_info();
    if ($info['JPG Support']) {
        $this-&gt;_support['JPG'] = true;
    }
    if ($info['GIF Create Support']) {
        $this-&gt;_support['GIF'] = true;
    }
    if ($info['PNG Support']) {
        $this-&gt;_support['PNG'] = true;
    }

    // If the source input is a resource, set it as the image handle.
    if ((is_resource($source) &amp;&amp; get_resource_type($source) == 'gd')) {
        $this-&gt;_handle = &amp;$source;
    } elseif (!empty($source) &amp;&amp; is_string($source)) {
        // If the source input is not empty, assume it is a path and populate the image handle.

        //Andy - Big freaking cockroach: if file is wrong type or doesn't even exist the error is not handled.
        $this-&gt;loadFromFile($source);
    }
}

function crop($width, $height, $left, $top, $createNew = true, $scaleMethod = JXIMAGE_SCALE_INSIDE)
{
    // Make sure the file handle is valid.
    if ((!is_resource($this-&gt;_handle) || get_resource_type($this-&gt;_handle) != 'gd')) {
        $this-&gt;setError('Invalid File Handle');
        return false;
    }

    // Sanitize width.
    $width = ($width === null) ? $height : $width;
    if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $width)) {
        $width = intval(round($this-&gt;getWidth() * floatval(str_replace('%', '', $width)) / 100));
    } else {
        $width = intval(round(floatval($width)));
    }

    // Sanitize height.
    $height = ($height === null) ? $width : $height;
    if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $height)) {
        $height = intval(round($this-&gt;getHeight() * floatval(str_replace('%', '', $height)) / 100));
    } else {
        $height = intval(round(floatval($height)));
    }

    // Sanitize left.
    $left = intval(round(floatval($left)));

    // Sanitize top.
    $top = intval(round(floatval($top)));

    // Create the new truecolor image handle.
    $handle = imagecreatetruecolor($width, $height);

    // Allow transparency for the new image handle.
    imagealphablending($handle, false);
    imagesavealpha($handle, true);

    if ($this-&gt;isTransparent()) {
        // Get the transparent color values for the current image.
        $rgba = imageColorsForIndex($this-&gt;_handle, imagecolortransparent($this-&gt;_handle));
        $color = imageColorAllocate($this-&gt;_handle, $rgba['red'], $rgba['green'], $rgba['blue']);

        // Set the transparent color values for the new image.
        imagecolortransparent($handle, $color);
        imagefill($handle, 0, 0, $color);

        imagecopyresized(
            $handle,
            $this-&gt;_handle,
            0, 0,
            $left,
            $top,
            $width,
            $height,
            $width,
            $height
        );
    } else {

        imagecopyresampled(
            $handle,
            $this-&gt;_handle,
            0, 0,
            $left,
            $top,
            $width,
            $height,
            $width,
            $height
        );
    }

    // If we are cropping to a new image, create a new GImage object.
    if ($createNew)
    {
        // Create the new GImage object for the new truecolor image handle.
        $new = new GImage($handle);
        return $new;
    } else
    {
        // Swap out the current handle for the new image handle.
        $this-&gt;_handle = &amp;$handle;
        return true;
    }
}

  function filter($type)
{
    // Initialize variables.
    $name = preg_replace('#[^A-Z0-9_]#i', '', $type);

    $className = 'GImageFilter_'.ucfirst($name);
    if (!class_exists($className))
    {
        jimport('joomla.filesystem.path');
        if ($path = JPath::find(GImageFilter::addIncludePath(), strtolower($name).'.php'))
        {
            require_once $path;

            if (!class_exists($className)) {
                $this-&gt;setError($className.' not found in file.');
                return false;
            }
        }
        else {
            $this-&gt;setError($className.' not supported. File not found.');
            return false;
        }
    }

    $instance = new $className;
    if (is_callable(array($instance, 'execute')))
    {
        // Setup the arguments to call the filter execute method.
        $args = func_get_args();
        array_shift($args);
        array_unshift($args, $this-&gt;_handle);

        // Call the filter execute method.
        $return = call_user_func_array(array($instance, 'execute'), $args);

        // If the filter failed, proxy the error and return false.
        if (!$return) {
            $this-&gt;setError($instance-&gt;getError());
            return false;
        }

        return true;
    }
    else {
        $this-&gt;setError($className.' not valid.');
        return false;
    }
}

function getHeight()
{
    return imagesy($this-&gt;_handle);
}

function getWidth()
{
    return imagesx($this-&gt;_handle);
}

function isTransparent()
{
    // Make sure the file handle is valid.
    if ((!is_resource($this-&gt;_handle) || get_resource_type($this-&gt;_handle) != 'gd')) {
        $this-&gt;setError('Invalid File Handle');
        return false;
    }

    return (imagecolortransparent($this-&gt;_handle) &gt;= 0);
}

function loadFromFile($path)
{
    // Make sure the file exists.
    if (!JFile::exists($path)) {
        $this-&gt;setError('File Does Not Exist');
        return false;
    }

    // Get the image properties.
    $properties = GImageHelper::getProperties($path);
    if (!$properties) {
        return false;
    }

    // Attempt to load the image based on the MIME-Type
    switch ($properties-&gt;get('mime'))
    {
        case 'image/gif':
            // Make sure the image type is supported.
            if (empty($this-&gt;_support['GIF'])) {
                $this-&gt;setError('File Type Not Supported');
                return false;
            }

            // Attempt to create the image handle.
            $handle = @imagecreatefromgif($path);
            if (!is_resource($handle)) {
                $this-&gt;setError('Unable To Process Image');
                return false;
            }
            $this-&gt;_handle = &amp;$handle;
            break;
        case 'image/jpeg':
            // Make sure the image type is supported.
            if (empty($this-&gt;_support['JPG'])) {
                $this-&gt;setError('File Type Not Supported');
                return false;
            }

            // Attempt to create the image handle.
            $handle = @imagecreatefromjpeg($path);
            if (!is_resource($handle)) {
                $this-&gt;setError('Unable To Process Image');
                return false;
            }
            $this-&gt;_handle = &amp;$handle;
            break;
        case 'image/png':
            // Make sure the image type is supported.
            if (empty($this-&gt;_support['PNG'])) {
                $this-&gt;setError('File Type Not Supported');
                return false;
            }

            // Attempt to create the image handle.
            $handle = @imagecreatefrompng($path);
            if (!is_resource($handle)) {
                $this-&gt;setError('Unable To Process Image');
                return false;
            }
            $this-&gt;_handle = &amp;$handle;
            break;
        default:
            $this-&gt;setError('File Type Not Supported');
            return false;
            break;
    }

    // Set the filesystem path to the source image.
    $this-&gt;_path = $path;

    return true;
}

function resize($width, $height, $createNew = true, $scaleMethod = JXIMAGE_SCALE_INSIDE)
{

    // Make sure the file handle is valid.
    if ((!is_resource($this-&gt;_handle) || get_resource_type($this-&gt;_handle) != 'gd')) {
        $this-&gt;setError('Invalid File Handle');
        return false;
    }

    // Prepare the dimensions for the resize operation.
    $dimensions = $this-&gt;_prepareDimensions($width, $height, $scaleMethod);
    if (empty($dimensions)) {
        return false;
    }

    //var_dump($dimensions);

    // Create the new truecolor image handle.
    $handle = imagecreatetruecolor($dimensions['width'], $dimensions['height']);

    // Allow transparency for the new image handle.
    imagealphablending($handle, false);
    imagesavealpha($handle, true);

    if ($this-&gt;isTransparent()) {
        // Get the transparent color values for the current image.
        $rgba = imageColorsForIndex($this-&gt;_handle, imagecolortransparent($this-&gt;_handle));
        $color = imageColorAllocate($this-&gt;_handle, $rgba['red'], $rgba['green'], $rgba['blue']);

        // Set the transparent color values for the new image.
        imagecolortransparent($handle, $color);
        imagefill($handle, 0, 0, $color);

        imagecopyresized(
            $handle,
            $this-&gt;_handle,
            0, 0, 0, 0,
            $dimensions['width'],
            $dimensions['height'],
            $this-&gt;getWidth(),
            $this-&gt;getHeight()
        );
    } else {

        imagecopyresampled(
            $handle,
            $this-&gt;_handle,
            0, 0, 0, 0,
            $dimensions['width'],
            $dimensions['height'],
            $this-&gt;getWidth(),
            $this-&gt;getHeight()
        );
    }

    // If we are resizing to a new image, create a new GImage object.
    if ($createNew)
    {
        // Create the new GImage object for the new truecolor image handle.
        $new = new GImage($handle);
        return $new;
    } else
    {
        // Swap out the current handle for the new image handle.
        $this-&gt;_handle = &amp;$handle;
        return true;
    }
}

function toFile($path, $type = IMAGETYPE_JPEG, $options=array())
{
    switch ($type)
    {
        case IMAGETYPE_GIF:
            $ret = imagegif($this-&gt;_handle, $path);
            break;

        case IMAGETYPE_PNG:
            $ret = imagepng($this-&gt;_handle, $path, (array_key_exists('quality', $options)) ? $options['quality'] : 0);
            break;

        case IMAGETYPE_JPEG:
        default:
            $ret = imagejpeg($this-&gt;_handle, $path, (array_key_exists('quality', $options)) ? $options['quality'] : 100);
            break;
    }

    return $ret;
}

function display() {
    //header('Content-type: image/jpeg');
    imagejpeg($this-&gt;_handle,'',100);
}

function _prepareDimensions($width, $height, $scaleMethod)
{
    // Sanitize width.
    $width = ($width === null) ? $height : $width;
    if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $width)) {
        $width = intval(round($this-&gt;getWidth() * floatval(str_replace('%', '', $width)) / 100));
    } else {
        $width = intval(round(floatval($width)));
    }

    // Sanitize height.
    $height = ($height === null) ? $width : $height;
    if (preg_match('/^[0-9]+(\.[0-9]+)?\%$/', $height)) {
        $height = intval(round($this-&gt;getHeight() * floatval(str_replace('%', '', $height)) / 100));
    } else {
        $height = intval(round(floatval($height)));
    }

    $dimensions = array();
    if ($scaleMethod == JXIMAGE_SCALE_FILL)
    {
        $dimensions['width'] = $width;
        $dimensions['height'] = $height;
    }
    elseif ($scaleMethod == JXIMAGE_SCALE_INSIDE || $scaleMethod == JXIMAGE_SCALE_OUTSIDE)
    {
        $rx = $this-&gt;getWidth() / $width;
        $ry = $this-&gt;getHeight() / $height;

        if ($scaleMethod == JXIMAGE_SCALE_INSIDE)
            $ratio = ($rx &gt; $ry) ? $rx : $ry;
        else
            $ratio = ($rx &lt; $ry) ? $rx : $ry;

        $dimensions['width']    = round($this-&gt;getWidth() / $ratio);
        $dimensions['height']   = round($this-&gt;getHeight() / $ratio);
    }
    else {
        $this-&gt;setError('Invalid Fit Option');
        return false;
    }

    return $dimensions;
}
}

 class GImageFilter extends JObject
{
/**
 * Add a directory where GImage should search for filters. You may
 * either pass a string or an array of directories.
 *
 * @access  public
 * @param   string  A path to search.
 * @return  array   An array with directory elements
 * @since   1.5
 */
function addIncludePath($path='')
{
    static $paths;

    if (!isset($paths)) {
        $paths = array(dirname(__FILE__).'/image');
    }

    // force path to array
    settype($path, 'array');

    // loop through the path directories
    foreach ($path as $dir)
    {
        if (!empty($dir) &amp;&amp; !in_array($dir, $paths)) {
            array_unshift($paths, JPath::clean( $dir ));
        }
    }

    return $paths;
}

function execute()
{
    $this-&gt;setError('Method Not Implemented');
    return false;
}
}

class GImageHelper
{
function getProperties($path)
{
    // Initialize the path variable.
    $path = (empty($path)) ? $this-&gt;_path : $path;

    // Make sure the file exists.
    if (!JFile::exists($path)) {
        $e = new JException('File Does Not Exist');
        return false;
    }

    // Get the image file information.
    $info = @getimagesize($path);
    if (!$info) {
        $e = new JException('Unable To Get Image Size');
        return false;
    }

    // Build the response object.
    $result = new JObject;
    $result-&gt;set('width',       $info[0]);
    $result-&gt;set('height',      $info[1]);
    $result-&gt;set('type',        $info[2]);
    $result-&gt;set('attributes',  $info[3]);
    $result-&gt;set('bits',        @$info['bits']);
    $result-&gt;set('channels',    @$info['channels']);
    $result-&gt;set('mime',        $info['mime']);

    return $result;
}

function test()
{
    return (function_exists('gd_info') &amp;&amp;            function_exists('imagecreatetruecolor'));
}
</code></pre>

<p>}</p>
