views:

76

answers:

4

Hey all.

Would anyone be able to give me a quick primer on how memory resources are used? I know I can up the PHP memory limit in PHP.ini as well as through lines of code such as:

    ini_set("memory_limit","24M");

I have an image upload script that I'm writing that is making use of a pretty cool PHP script called simpleImage which can be found here: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php

I have a basic form that accepts JPGs and PNGs. I've set my PHP memory limit to 24m, thinking this would be high enough, but when I tried to upload a 3mb image I still received the beautiful memory allocation exhausted error. Bumping the value up to a meatier 240M and the script runs fine (locally).

My script does this:
1) Accepts the TMP Image being uploaded
2) Runs getimagesize() on the image to check that it's a valid image.
3) Moves the temporary image to the final destination directory.
4) Loads the image using simple image.
5) Resizes the image using simple image.
6) Saves the resized image using simple image script.

So I guess that all the loading/checking/resizing requires a bit more than the 24M. But I'm worried about what an acceptable memory limit allocation would be. I would like for users to comfortable be able to upload ~6MB images. Is this going to be extremely stressful on your average dedicated servers?

Here's the gist of my script.. personally I don't think it's excessively wasteful on resources??

    if (!empty($_FILES)) {
    // get image
    ini_set("memory_limit","24M");
    require_once('simpleImage.php');
    require_once('db.php');
    $tempFile             =     $_FILES['file']['tmp_name'];
    $originalFile        =    $_FILES['file']['name'];
    $extension             =     strtolower(end(explode(".", $originalFile)));
    $targetFile         =    "path/to/directory/";

    // validate image
    $validExtensions    =    array('jpg', 'jpeg', 'png');
    if(in_array($extension, $validExtensions)) {
        $validExtension        =    true;    
    } else {
        $validExtension        =    false;    
    }

    if(getimagesize($tempFile) == false) {
        $validImage        =    false;    
    } else {
        $validImage        =    true;    
    }


    if($validExtension == true && $validImage == true) {
        if(move_uploaded_file($tempFile,$targetFile)) {

            $image = new SimpleImage();
            $image->load($targetFile);
            $image->resizeToWidth(500);
            $image->save($targetFile);
        }
    } 
}
+1  A: 

Formats such as JPG and PNG are highly compressed and hence a 3MB file which is say 6 megapixels could easily expand to 24MB in memory. Adding in the output image and PHP's own requirements could easily make the memory usage cross 30MB.

The actual memory requirement depends more on the image dimensions rather than the file size. A rough estimate would be megapixels * 3 MB for RGB images (JPEGs and opaque PNGs) or megapixels * 4 MB for RGBA images (transparent PNGs). Don't forget that the GD library itself may maintain temporary internal buffers for various purposes, so double this estimate should be a reasonable memory limit to use.

casablanca
A: 

Chances are your memory limit is probably too lower.

Keep in mind that when editing image files they generally need to be stored uncompressed in memory. So while a 3000x3000 jpeg may easily be under 3MB, uncompressed it will be 3000x3000x3 (3 is for one byte each for RGB) bytes or 27MB, and if you have an alpha channel, 36MB. Also, when finished with an image resource, be sure to destroy it so that the resources can be released.

Also, if you're using some sort of shared hosting, chances are the ini_set function has been disabled. It's always better to make such configuration settings in the php.ini if you can. I'm saying this so you can avoid the headaches of wondering why having ini_set("memory_limit","240M") and still not having enough memory might occur.

jay.lee
+1  A: 

Your average server can certainly handle a few uploads of 6meg files. Most users will undoubtedly be on DSL or cable broadband, which have fairly low upload bandwidths. 40-60kbyte/sec. Most servers will have at least a fast ethernet link (100mbit), which could theoretically handle around 200 simultaneous 60k/s uploads.

The big load will be resizing the images, as you need to hold the uncompressed bitmap in memory while resizing. The other answers have covered the memory requirements for that, but I'd like to point out that with PHP your memory limit has to be high enough to cover the actual size of the uploaded file.

A good rule of thumb is to have at least 1 meg more than the largest file you'd allow to be uploaded. Unless your code is hideously bloated, that should handle most any script you want to use to do upload processing, and from within that you can then boost the limit to handle the image resizing overhead. But the actual upload memory space has to be set in the server's config (Apache's php_value directives) or PHP's php.ini file - by the time your script would get executed and do the ini_set('memory_limit', ...), the upload's already completed (or aborted due to insufficient memory).

Marc B
A: 

SimpleImage probably isn't very efficient. The de facto standard for image manipulation inside programs is ImageMagick. It's written in C and thus very efficient. It's also widely used and well tested. See this page on php.net for instructions on how to install and use it in PHP.

imgx64