2009-11-14 57 views
1

我使用單個圖像上傳/裁剪/調整大小腳本文件高達10MB。PHP內存限制25MB用盡 - 文件上傳/裁剪/調整大小

測試時,我將php_ini內存限制設置爲25M,上傳文件時僅用了1.4MB左右。

"Allowed memory size of 26214400 bytes exhausted (tried to allocate 10368 bytes)" 

這對我來說很奇怪,是不是10368 < 26214400? (修辭問題)

或者這是否意味着我超過25MB 10368字節?我的腳本應該使用這麼多的內存嗎?

代碼:

function make_thumbnails($updir, $img) 
{ 
    $thumbnail_width = 200; 
    $thumbnail_height = 150; 
    $thumb_preword = "thumb_"; 

    $arr_image_details = GetImageSize($updir.$img); 
    $original_width = $arr_image_details[0]; 
    $original_height = $arr_image_details[1]; 

    if($original_width > $original_height){ 
     $new_width = $thumbnail_width; 
     $new_height = intval($original_height*$new_width/$original_width); 
    } else { 
     $new_height = $thumbnail_height; 
     $new_width = intval($original_width*$new_height/$original_height); 
    } 

    $dest_x = intval(($thumbnail_width - $new_width)/2); 
    $dest_y = intval(($thumbnail_height - $new_height)/2); 

    if($arr_image_details[2]==1) { $imgt = "ImageGIF"; $imgcreatefrom = "ImageCreateFromGIF"; } 
    if($arr_image_details[2]==2) { $imgt = "ImageJPEG"; $imgcreatefrom = "ImageCreateFromJPEG"; } 
    if($arr_image_details[2]==3) { $imgt = "ImagePNG"; $imgcreatefrom = "ImageCreateFromPNG"; } 

    if($imgt) 
    { 
     $old_image = $imgcreatefrom($updir.$img); 
     $new_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height); 
     imageCopyResized($new_image,$old_image,$dest_x, 
     $dest_y,0,0,$new_width,$new_height,$original_width,$original_height); 
     $imgt($new_image,$updir.$thumb_preword.$img); 

     // Added by your suggestions: 
     imagedestroy($old_image); 
     imagedestroy($new_image); 
    } 
} 
+1

您剛剛嘗試分配另一個10368字節時達到了內存限制。請向我們展示一些代碼,以便我們可以幫助您。 – Gumbo 2009-11-14 18:12:38

+0

感謝您的參與,代碼已發佈 – 2009-11-14 18:20:08

+0

真的很難確定最佳答案,總體而言,您都回答了我正在尋找的內容。謝謝!! – 2009-11-14 18:36:55

回答

4

該錯誤消息說,它試圖分配另一個字節10368,但它是不可用。換句話說,你的25MB池已經耗盡,腳本無法分配它需要的10368字節。

您可以增加此限制在php.ini文件中,通過添加或更新類似於下面的一行:

memory_limit = 64M 

至於「如果25MB的是不夠的,」這對我們來說是一個很難回答的問題答案......肯定有一些腳本需要64MB甚至更多。如果你發現你必須不斷增加你的記憶池的大小,我會開始考慮需要這麼多空間的東西。

Here is a related question這對你的內存池的大小有一些很好的討論。

編輯看到您的代碼發佈後,當您使用圖像時肯定會消耗大量內存。完成圖像資源後,您可以通過撥打imagedestroy來幫助您的腳本。

1

這意味着,當你超出限制時,你的腳本試圖分配10368字節,但它沒有成功。這並不意味着如果你將限制增加到26MB,你就不會再有這個問題了。該錯誤可能稍後發生。您可以嘗試以較小的步驟增加它(例如32MB,48MB等),直到您不再遇到此錯誤。

2

或者這是否意味着我超過了25MB的10368字節?

號你的腳本試圖分配10368個字節,10368 + alreadyallocated> 25MB

如果我的腳本是用這麼多內存?

如果您使用GD進行調整大小,是的。我會嘗試使用其他庫或控制檯工具進行圖像處理,它們可以提供更多的性能。而且,您可以決定使用隊列進行圖像處理,而不是將圖像尺寸調整剛剛在時間,如果它是公共網站

+0

我會研究一下,謝謝 – 2009-11-14 18:33:16

2

使用imagedestroy使用後釋放內存:

if($imgt) 
{ 
    $old_image = $imgcreatefrom($updir.$img); 
    $new_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height); 
    imageCopyResized($new_image,$old_image,$dest_x, 
    $dest_y,0,0,$new_width,$new_height,$original_width,$original_height); 
    imagedestroy($old_image); 
    $imgt($new_image,$updir.$thumb_preword.$img); 
    imagedestroy($new_image); 
} 
+0

甜蜜,這讓我的記憶力下降了一些。我應該注意這個問題的其他人,正確的語法是imagedestroy($ new_image); 謝謝! – 2009-11-14 18:30:53

+0

@Paul Silvis:謝謝。幸運的是,當我實際輸入'image_destroy'時,PHP.net顯示了正確的功能。 – Gumbo 2009-11-14 18:35:21

14

除了什麼已經說過:

永遠不要忘記,處理壓縮文件格式(如JPEG)需要比實際文件大小更多的內存。一個3000 x 3000像素的JPG文件可以僅重500kb,但需要(大致)3000 x 3000 x 3(紅,綠和藍各一個字節,根據模式,甚至還有一個用於Alpha)=至少27 MB 。

+0

謝謝,這確實將估算「可接受」的效率帶入了重點。 – 2009-11-14 18:29:28

+0

+1我打賭通過調試器運行他的代碼,他會在'$ imgcreatefrom($ updir。$ img);'(如果該行尚未顯示部分錯誤消息指示他沒有粘貼)。 – timdev 2009-11-15 04:18:34