2009-07-13 6 views
5

C'è un modo per impedire a PHP GD image library di esaurire la memoria? Se viene caricata un'immagine troppo grande, GD tende a esaurire la memoria, terminando lo script. Mi piacerebbe lanciare un'eccezione o qualcosa di simile a tale estensione, ma purtroppo non è così.Un modo sicuro per impedire l'esaurimento della memoria della libreria di immagini GD? (PHP)

In questo momento sto usando uno script di tipo cobbled-together che per prima emette un ini_set('memory_limit', '128M'), se funziona, sono solitamente impostato. A seconda della configurazione del server potrebbe non essere possibile, quindi sto ricadendo su un algoritmo che cerca di stimare la quantità di memoria necessaria (prendendo in considerazione la risoluzione, la profondità del colore, i canali e un fattore fudge), quindi la confronta con memory_get_usage() se la funzione esiste, altrimenti fa una stima approssimativa.

Il tutto funziona così lontano, ma è tutt'altro che elegante e fallirà in alcuni casi limite, ne sono sicuro. C'è un modo migliore per farlo, cioè se GD fallisce con garbo se deve, invece di smettere tutto per fermarlo?

+1

immagini JPEG (non-PNG o altri tipi) possono essere ridimensionate mentre il carico, vedere questa risposta per ulteriori dettagli: http://stackoverflow.com/questions/12661/efficient-jpeg-image-resizing- in-php/4613341 # 4613341 –

risposta

3

Acquista più memoria! :-P

Seriamente, è impossibile gestire l'esaurimento della memoria perché qualsiasi azione eseguita richiederebbe più memoria.

La soluzione migliore è limitare la dimensione dell'immagine caricata in base alle impostazioni di memoria correnti.

+2

LOL, comprami un host con più memoria. ;-) Beh, mi piacerebbe almeno che GD stimasse il suo uso della memoria, invece di dover fare le congetture suscettibili agli errori e quindi trattenere il respiro. Non posso limitarmi a limitare l'immagine per dimensione del file. Un file di piccole dimensioni con un JPG ad alta risoluzione e molto compresso può occupare più memoria di un file di grandi dimensioni con un PNG a bassa risoluzione. Ecco perché devo ricorrere al mio calcolo sopra menzionato. – deceze

0

La soluzione migliore è smettere di cercare di capire quanta RAM sarà necessaria e limitarla al massimo - se disponi di 4 GB disponibili, specifica lo script dell'immagine da utilizzare tra 2 e 4 GB o giù di lì. e quando la sceneggiatura termina, tornare alla normalità, che coprirà tutte le situazioni potenzialmente fatali. Questo è l'unico modo "Fail-safe" che riesco comunque a pensare ...

+0

Questo è quello che sto cercando di fare, ma raramente è possibile su host condivisi. In questi casi sto facendo i calcoli migliori per determinare le difficoltà. – deceze

+0

Impostando il limite di memoria PHP uguale alla quantità totale di RAM che il sistema ha, o dovunque in remoto vicino, consentirà agli utenti di DOS tramite lo script di immagine. Capire quanta RAM è necessaria in precedenza è l'unico modo in cui posso pensare che impedirà questo tipo di DOS. –

1

C'è un altro modo per farlo, ma può richiedere molto tempo, poiché alcune parti del processo di modifica delle immagini sarebbero ripetute un numero di volte, ma è possibile impostare il limite di memoria sul valore stimato, quindi provare a elaborare l'immagine, se non riesce a rilevare l'eccezione, aumentare il limite di memoria, quindi elaborare di nuovo l'immagine - ripetere questo fino a raggiungere un determinato limite di memoria - a quel punto si lancia un messaggio di errore all'utente spiegando che la propria immagine è troppo grande per essere utilizzata.

Modifica: Per catturare l'errore out-of-memoria, è possibile utilizzare questa soluzione: http://au2.php.net/set_error_handler#35622

+0

Continua a leggere, AFAIK non c'è niente di catchable che viene lanciato. È un lavoro one-shot-o-it-doesn't operazione. A meno che tu non possa dirmi come rilevare un errore di memoria esaurita, che è quello che sto chiedendo. :) – deceze

+2

C'è un modo per catturare questi errori: http://au2.php.net/set_error_handler#35622 – jsnfwlr

+0

Dovrò vedere se questo effettivamente aiuta, come notato da Nick, dovrei usare più memoria per gestire l'errore dopo che si è verificato. – deceze

0

per catturare gli errori fatali di PHP, come "Out of memory" o "PHP Fatal error: ammessi dimensione della memoria di 8388608 byte esauriti (tentato di allocare ... byte) in ", vedere qui: http://php.net/manual/en/function.set-error-handler.php#88401

+0

Una volta che uno script PHP ha esaurito la memoria, non può chiamare la funzione di spegnimento perché ciò richiederebbe l'allocazione di più memoria. – scotts

3

Dopo aver creato un'immagine.

imagepng($image); 
imagedestroy($image); 

rimuoverà il problema di memoria

+0

Questo dovrebbe essere contrassegnato come la risposta, ha funzionato come un fascino per me. – Vic

+0

Questo dovrebbe ** non ** essere contrassegnato come risposta. La distruzione di un'immagine salva l'utilizzo della memoria, ma in nessun modo rende GD più elegante. – Glutexo

0

fare qualche test per verificare la quantità di memoria ogni gd funzione di necessità.

  • imagecreatetruecolor sembra aver bisogno width*height*5 bytes.

  • imagepng sembra aver bisogno di width*height*4 bytes.

+0

Perché 'imagecreatetruecolor' ha bisogno di 5 byte per pixel? Sembra un numero dispari. – Luke

+0

perché il supporto alfa è stato aggiunto molto tempo dopo imagecreate, e molte funzioni probabilmente avevano supposizioni che il 4 ° byte era sempre 0, quindi non poteva essere usato ... o pensavano/vedevano che era troppo complesso per usarlo e ne ha creato uno nuovo. – sebbu

+0

Hai esperienza anche durante il caricamento di immagini esistenti su di esso? per esempio. per jpg o png? Io uso x * y * ~ 5 per jpg, ~ 8 per png, sopra l'attuale utilizzo di mem. se questo supera il limite di mem ho impostato un'eccezione. Ma: impostare 64M come limite e avere un jpg caricato 2MB a volte può interrompere l'operazione. Jpg sembra usare a volte più memoria. Compressione? Qualche altro dato exif? dove posso migliorare il calcolo? – flobee

Problemi correlati