Ошибка нехватки памяти при объединении большого количества PDF-файлов с использованием Zend_PDF - PullRequest
1 голос
/ 02 февраля 2012

Мы используем модуль Zend_PDF в SugarCRM для объединения PDF-счетов, которые генерирует наша система. Я смог успешно объединить несколько PDF-файлов (около 10-30 в моих тестах), но мы получаем ошибки памяти, когда пытаемся объединить большее количество PDF-файлов. Ошибка выглядит примерно так:

[30-Jan-2012 14:10:20] Неустранимая ошибка PHP: допустимый объем памяти 268435456 байтов исчерпан в /usr/local/src/php-5.3.8/Zend/zend_operators.c:1265 (попытался выделить 68134 байта) в /srv/www/htdocs/sugar6_mf/Zend/Pdf/Element/Object/Stream.php в строке 442

Вышеуказанная ошибка возникла, когда мы попытались объединить 457 PDF-файлов - это файлы, а не страницы. Нам понадобится объединить 5000 и более за один раз.

Может ли кто-нибудь предложить какую-либо помощь / совет, как решить эту проблему?

При необходимости спросите, и я опубликую код о том, как генерируется объединенный pdf.

Спасибо.

1 Ответ

2 голосов
/ 03 февраля 2012

Мне следует предвосхитить этот ответ, сказав, что я ничего не знаю о SugarCRM - мой ответ основан исключительно на моих знаниях Zend_Pdf.

Если мое понимание верно, у вас есть скрипт PHP (надеюсь,1004 * не работает внутри Apache, учитывая время, которое потребуется для обработки 5000 файлов), который принимает несколько файлов PDF в качестве входных данных с использованием метода Zend_Pdf::load(), а затем перебирает страницы каждого объекта PDF и добавляет их водин целевой экземпляр Zend_Pdf, который вы затем записываете в файл с использованием метода save().

Используя этот подход, даже если вы unset() каждый из исходных объектов PDF после добавлениястраниц до целевого объекта PDF, вам все равно потребуется достаточно памяти для хранения всего выходного файла.Если вы пропустили 250 МБ только с 457 файлами, то я предполагаю, что ваши входные PDF-файлы, вероятно, имеют размер около 500 КБ, поэтому ваш выходной файл будет абсолютно огромным, поэтому у вас все равно будет нехватка памяти.

Мой совет - полностью отказаться от этого метода и использовать вместо него pdftk, который можно вызвать с помощью функции exec().Я уверен, что есть ограничение на размер аргументов, которые вы можете предоставить exec(), так что, вероятно, это будет многоэтапный процесс с несколькими промежуточными файлами, но в конечном итоге я думаю, что это будет более быстрое и надежное решение.

И просто для повторения более ранней точки, я бы не запустил этот процесс в Apache.Я бы настроил cron задание, которое запускается с соответствующими интервалами и помещает выходной файл в безопасную область на вашем веб / файловом сервере.

...