Hello all,
I've wasted an entire work day on this problem, so if you can help me, I will send 9,000,000 karma points in your direction (and throw in wishes of snax and girls...if that's your thing).
I set up the following gallery upload page, which is essentially a copy of another working upload page that I'm currently using for a client. But, somehow, this second one creates an error. The only difference is that this new one should accept larger files (3.75M instead of 1M):
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 18432 bytes) in /path/to/Upload_Gal.php on line 110
Problem - I've defined MAX_FILE_SIZE to accept up to 3.75M (3932160 bytes). Even if there were three maxed out uploads, that would only add up to 10.5M total. The code seems to work fine for files that are 1M or smaller, but immediately fails with only a single "large" upload (one file at 3.5M).
PLEASE READ THIS
My php.ini file (which I've quadruple checked...paths and settings), allows 32M for uploads, files, posts, etc...so the problem isn't there, I don't think.
I've read, generally, that this could be due to bad coding - which I wouldn't doubt, since I'm no aficionado. But, I can't find where the problem is. The error says line 110, but that's general (marked below)
//STEP 2 UPLOAD
//max size 3.75 mb
define('MAX_FILE_SIZE',3932160);
if(array_key_exists('upload',$_POST) && isset($_SESSION['gal'])) {
//define file sizes for orig and thumbs
define('MAX_FILE_WIDTH',360);
define('MAX_FILE_HEIGHT',360);
define('MAX_THUMB_WIDTH',108);
define('MAX_THUMB_HEIGHT',108);
//define upload dir
define('UPLOAD_DIR','..path/');
//define thumbs_dir
define('THUMBS_DIR',UPLOAD_DIR.'Th/');
$gal = $_SESSION['gal'];
//permitted MIME types
$permitted = array('image/jpeg','image/pjpeg');
//convert the max size (bytes) to MB
$max = number_format(MAX_FILE_SIZE/1048576,1).'MB';
foreach($_FILES['image']['name'] as $number => $file) {
//replace spaces & assign var to $file
$file = str_replace(' ','_',$file);
//assume file is unacceptable
$name_lengthOK = false;
$sizeOK = false;
$typeOK =false;
$unique = false;
//check name length
$file_length = strlen($file);
if($file_length <= 25) {
$name_lengthOK = true;
}
//check filesize
if($_FILES['image']['size'][$number] > 0 && $_FILES['image']['size'][$number] <= MAX_FILE_SIZE) {
$sizeOK = true;
}
//check MIME type
foreach($permitted as $type) {
if($type == $_FILES['image']['type'][$number]) {
$typeOK = true;
break;
}
}//endforeach
//make sure image is not a duplicate
if(!file_exists(UPLOAD_DIR.$file)) {
$unique = true;
}
if($name_lengthOK && $sizeOK && $typeOK && $unique) {
$original = $_FILES['image']['tmp_name'][$number];
switch($_FILES['image']['error'][$number]) {
case 0:
//move the file to the upload folder and rename it
//get new sizes from orig
list($width, $height, $type) = getimagesize($original);
//calculate ratios
if ($width <= MAX_FILE_WIDTH && $height <= MAX_FILE_HEIGHT) {
$file_ratio = 1;
if($width > $height) {
$thumb_ratio = MAX_THUMB_WIDTH/$width;
}
else {
$thumb_ratio = MAX_THUMB_HEIGHT/$height;
}
}
elseif ($width > $height) {
$file_ratio = MAX_FILE_WIDTH/$width;
$thumb_ratio = MAX_THUMB_WIDTH/$width;
}
else {
$file_ratio = MAX_FILE_HEIGHT/$height;
$thumb_ratio = MAX_THUMB_HEIGHT/$height;
}
//strip the extension off the image filename
$imagetypes = array('/\.jpg$/','/\.jpeg$/');
$name = preg_replace($imagetypes,'',basename($file));
$source = imagecreatefromjpeg($original); //------THIS IS LINE 110 -------------------
//calculate new dimensions
$new_width = round($width * $file_ratio);
$new_height = round($height * $file_ratio);
$thumb_width = round($width * $thumb_ratio);
$thumb_height = round($height * $thumb_ratio);
//create image resources
$new_file = imagecreatetruecolor($new_width, $new_height);
$thumbnail = imagecreatetruecolor($thumb_width, $thumb_height);
//create resized copies
imagecopyresampled($new_file, $source, 0,0,0,0, $new_width, $new_height, $width, $height);
imagecopyresampled($thumbnail, $source, 0,0,0,0, $thumb_width, $thumb_height, $width, $height);
$sql_filename = mysql_real_escape_string($name.'.jpg');
$sql = "INSERT INTO images (image_name,gallery) VALUES ('$sql_filename','$gal')";
$sql_result = mysql_query($sql) or die(mysql_error());
//save resized copy
$success = imagejpeg($new_file, UPLOAD_DIR.$name.'.jpg',100);
$success .= imagejpeg($thumbnail, THUMBS_DIR.$name.'.jpg',100);
imagedestroy($source);
imagedestroy($new_file);
imagedestroy($thumbnail);
if($success) {
$upload_result[] = '<span id="blue_text">"'."<em>$file</em>".'" '."UPLOADED SUCCESSFULLY</span>";
}
else {
$upload_result[] = "Error uploading $file. Please try again.";
}
break;
case 3:
$upload_result[] = "An error occurred while uploading $file. PLEASE TRY AGAIN.";
default:
$upload_result[] = "SYSTEM ERROR uploading $file. Contact webmaster.";
}//end switch
}//endif($name_length...sizeOK)
elseif(!$unique && $_FILES['image']['error'][$number] !== 4) {
$upload_result[] = "ERROR: A file named $file already exists.";
}
elseif(!$name_lengthOK) {
$upload_result[] = 'ERROR: "'."<em>$file</em>".'" '."must be renamed to be 25 characters or less.";
}
elseif ($_FILES['image']['error'][$number] == 4) {
$upload_result[] = 'No file selected';
}
else {
$upload_result[] = '"'."<em>$file</em>".'" '."COULD NOT BE UPLOADED:<br/>
- <em>Max size: $max<br/>
- jpeg only</em>";
}
}//endforeach
}//end if $_POST
<p><strong>Step 2:</strong><br/>
Once you've chosen a gallery to view (above), you may upload up to 3 photos at a time. Images will be resized for web-friendliness. However, if your files are large, upload may take some time.
</p>
<label for="image1">1. Choose Image:</label>
<input type="hidden" name="MAX_FILE_SIZE" value = "<?php echo MAX_FILE_SIZE; ?>*" />
<input type="file" name="image[]" id="image1" />
<br/>
<label for="image2">2. Choose Image:</label>
<input type="file" name="image[]" id="image2" />
<br/>
<label for="image3">3. Choose Image:</label>
<input type="file" name="image[]" id="image3" />
</p>
<p>
<input type="submit" name="upload" id="upload" value="Upload Image(s)" />
</p>
</div>
</form>
I DO NOT WANT A WORKAROUND, so please do not suggest that I allocate more memory, because I shouldn't have to. I need to know where I'm tricking php into thinking that either my files are larger than they are, or that it doesn't have enough memory to assume these tasks. Thanks in advance.