PHPmailer – problém s memory limitem

Při odesílání e-mailu s větší přílohou pomocí phpmaileru můžete narazit na situaci, kdy vám PHP ohlásí překročení povoleného množství paměti a skript se ukončí. Chybová hláška pak vypadá následovně:

Fatal error: Allowed memory size of 16777216 bytes exhausted
(tried to allocate 6123456 bytes)
in {........}/class.phpmailer.php on line 1262

Paměťový limit je 16 MB, skript jej celý vyčerpá.

Zjevným řešením by bylo navýšit paměťový limit v PHP. Ne vždy je tu ta možnost. Proto přichází na řadu řešení spočívající v úpravě zdrojového kódu phpmaileru.

Když se podíváte na řádek, označený v předchozí chybové hlášce, uvidíte tam něco takového:

$encoded = chunk_split(base64_encode($str), 76, $this->LE);

Tento kód vezme data z proměnné $str (4 MB), provede base64_encode, která data nafoukne na 5.3 MB, a takto upravená data předá funkci chunk_split, která udělá další kopii, přičemž za každý 76. bajt vloží ukončení řádku. Proměnná $encoded tak bude obsahovat něco kolem 5.9 MB dat. Když to všechno spočítáme, dostaneme se na 15.2 MB, což je 16 MB hranici nebezpečně blízko.

Přitom by stačilo využít toho, že není třeba uschovávat původní data. Předmětný řádek by se dal přepsat na:

$b64 = base64_encode($str);
unset($str);
$encoded = chunk_split($b64, 76, $this->LE);
unset($b64);

Pomocí unset()ů na druhém a čtvrtém řádku uvolníme proměnné, které již nepotřebujeme. Po prvním řádku zabereme 4 MB + 5,3 MB paměti. Po druhém řádku už jenom 5,3 MB (4 MB část smažeme). Po třetím řádku pak máme 5,3 MB + 5,9 MB s tím, že na čtvrtém řádku 5,3 MB opět uvolníme.

Nevýhodou zmíněného postupu je fakt, že si smažeme obsah proměnných $str a $b64. Pokud s těmito proměnnými chceme později pracovat, máme smůlu.

Tanto příspěvek byl zařazen do kategorie PHP a označen štítkem , . Do oblíbených si můžete uložit trvalý odkaz.

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

*

Můžete používat následující HTML značky a atributy: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>