|
|
|
|
|
圖片上傳時(shí)出現(xiàn)內(nèi)存不足的錯(cuò)誤
有沒有一種可以防止php GD image library運(yùn)行時(shí)出現(xiàn)內(nèi)存不足的方法?當(dāng)上傳一張大圖片時(shí),GD就有可能用盡內(nèi)存,終止腳本的運(yùn)行。我比較喜歡其能拋出一段錯(cuò)誤描述,但并沒有這樣。
現(xiàn)在我在腳本里首先設(shè)置ini_set('memory_limit', '128M'),如果湊效我就這么設(shè)置了。但根據(jù)服務(wù)器設(shè)置這是不可能的,所以我又不得不回到計(jì)算法則去估算內(nèi)存的大概使用量,然后與memory_get_usage()做比較(如果這個(gè)函數(shù)存在的話),否則只能是粗略估算了。
這樣處理是可以達(dá)到目的了,但是處理方式不夠簡(jiǎn)潔,并且有時(shí)候它也不能成功。我相信會(huì)有更好的辦法,例如GD可以返回更好的異常,而不是遇到什么事情只有停止。
◆討論一:
有網(wǎng)友認(rèn)為操作內(nèi)存不太可能,因?yàn)槿魏蝿?dòng)作都會(huì)消耗內(nèi)存。其建議最好的辦法是根據(jù)當(dāng)前內(nèi)存設(shè)置來(lái)限制上傳圖片的大小。
但我更喜歡讓GD來(lái)判斷內(nèi)存的使用量,不能單單顯示上傳文件大小這樣來(lái)處理。因?yàn)橐粡埥?jīng)過(guò)高壓縮、高分辨率的JPG小圖片,使用內(nèi)存比一張經(jīng)過(guò)低壓縮、低分辨率的PNG大圖片還要多。這就是為什么我要重新回到內(nèi)存估算的處理方法上來(lái)的原因。
◆討論二:
某網(wǎng)友說(shuō)可以不去計(jì)算內(nèi)存消耗,而是設(shè)定一個(gè)最大內(nèi)存使用值,例如你有4G可以內(nèi)存,那么圖片處理可以設(shè)置用2G-4G,一旦超出這個(gè)數(shù)值,就停止執(zhí)行腳本,這么避免隱藏的嚴(yán)重錯(cuò)誤。
對(duì)于此網(wǎng)友的方法,我認(rèn)為也是可行的,可是對(duì)于共享主機(jī)來(lái)說(shuō),這是無(wú)法實(shí)現(xiàn)的。我現(xiàn)在只是估算以防止事件掛起。
◆討論三:
捕抓PHP嚴(yán)重錯(cuò)誤,如“Out of memory”或“PHP Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate … bytes) in”。
我認(rèn)為這個(gè)方法不可行。一旦一個(gè)PHP腳本出現(xiàn)“Out of memory”,它就不能調(diào)用關(guān)閉函數(shù)因?yàn)槟切枰峙涓嗟膬?nèi)存。
◆總結(jié):?jiǎn)栴}如何解決?到目前為止我還沒有一個(gè)更好的解決方案。我希望能有辦法做到在出現(xiàn)“Out of memory”問(wèn)題時(shí)GD拋出異常,但這好像是一個(gè)不可能實(shí)現(xiàn)的事件。
小知識(shí):GD 是一個(gè)開源的圖像處理庫(kù),支持 PNG/JPEG/GIF以及其他格式的圖像。GD一般被用來(lái)創(chuàng)建圖表、圖形、縮略圖以及其他圖像相關(guān)的處理操作。
參考:PHP生成縮略圖出現(xiàn)內(nèi)存不足的解決方法
用php生成縮略圖,操作300kb+的jpg圖片都沒問(wèn)題,但是操作220kb左右的png圖片就顯示內(nèi)存用盡,
Allowed memory size of 8388608 bytes exhausted (tried to allocate 3715200 bytes;。。。
出現(xiàn)這個(gè)問(wèn)題的解決方法是把分配給php的內(nèi)存設(shè)置大一些,在圖片處理的頁(yè)面添加ini_set("memory_limit","12M");
添加之后的內(nèi)存限制僅對(duì)本頁(yè)面有效,不用擔(dān)心對(duì)其他程序產(chǎn)生影響。
實(shí)例:PHP ini_set 用法
ini_set具有更改php.ini設(shè)置的功能。此函數(shù)接收兩個(gè)參數(shù):需要調(diào)整的配置變量名,以及變量的新值。
例如,在某腳本出現(xiàn)時(shí)增加最大執(zhí)行時(shí)間(maximum execution time):
<?php
ini_set('max_execution_time', 600)
// more code
?>
這樣的設(shè)置將僅僅影響被設(shè)置的腳本。一旦腳本執(zhí)行完畢,該變量將自動(dòng)恢復(fù)到原始值。