Генерация PDF PHP + Битрикс + Подводные камни

В действительности всё совершенно иначе, чем на самом деле - Антуан де Сент Экзюпери

Задача стояла сгенерировать pdf-файл в CRM 1С-битрикс. Задача с первого взгляда тривиальна, НО есть подводные камни. Итак по порядку, как бы сделал любой разработчик:

1. Найти либу для генерации html -> pdf

В моем случае я использовал mpdf версии 6.0 (я знаю что есть другие, намного производительные, но у меня хост запрещает ставить программки типа wkhtmltopdf. К тому же mpdf лучше справляется с картинками, да какие-то свойства CSS она заглатывает и не отображает, но кому нужны спецэффекты в pdf? Еще недостаток есть с большими таблицами, но это уже другая статья)

2. Залить в либу на хост

По старой привычке прописать chmod и chown. Это нужно если то через что вы заливали не переносит права на папки вместе с файлами, ну и навсякий пожарный чтобы работало)))

Sudo chmod –R 777 /var/www/html/test/
Sudo chown –R www-data:www-data /var/www/html/test/

3. Затестить и посмотреть результат, удивиться что все работает или не работает.

Итак, создаю файл /var/www/html/test/print.php. Предварительно загрузив mpdf в /var/www/html/components/mpdf/.

Код файла print.php:

require_once $_SERVER['DOCUMENT_ROOT']. "/components/mpdf/mpdf.php";
$TEXT = "<h1 style='color:#000;'>Hello World</h1>"; 
$mpdf=new mPDF(); 
$mpdf->WriteHTML($TEXT); 
$mpdf->Output();

Этого кода хватает чтобы создался документ в браузере. Но если вы вызовете это все дело на серваке битрикса, то в лучшем случае Вы получите пустой документ.

А случаев два:

  1. Если вы пробуете создать pdf-файл mpdf’ом в каком-нибудь бизнес-процессе, используя PHP-код, где находится код наподобии того что выше, то у вас ничего хорошего не получится. Конкретнее – Chrome попробует вам его показать и не сможет, при этом выплюнет Вам ошибку «Не удалось загрузить» (Failed to load PDF document). А в Firefox’e будет все ок, загрузится документ, даже там что-то будет выводиться. Весь косяк в том, что битрикс подсовывает свои заголовки и при попытке записать файл у Вас наверняка не очищается поток вывода/.

    Проблема решается подставив ob_get_clean(); перед подключением либы.

    Вывод у Вас очищен и по идее все должно работать. Но это же битрикс ))) Куда же без второго случая.

  2. Если у Вас все хорошо создается и подгружается без ошибок, И Вы видите пустой документ в Chrome, а в Firefox’e все ок, то проблема совсем не в коде.

    Как оказалось дело в настройках сервака битрикс. У него есть такая штука как mbstring.func_overload, ее значение по-умолчанию 2 или 7 в зависимости какая сборка у вас стоит.

    Вся фишка в том, что mpdf требует значение mbstring.func_overload равным 0, а битрикс2 (или 7). Как быть спрашивается?

    Тут еще нюанс это значение можно изменять в .htaccess в PHP версии меньше 5.3. Если версия PHP больше 5.3, то в .htaccess прописав соответствующее значение оно просто не применится, хотя это зависит от хоста, как настроил. Есть случай на TimeWeb, где это работает. Но это не мой случай.

    Так вот чтобы pdf-файл создался, нужно чтобы для папки, где лежит этот скрипт создания pdf-файла, значение mbstring.func_overload было в 0. Тут внимание! Не для папки с либой /var/www/html/components/mpdf/, а для той где идет вызов /var/www/html/test/. Вопрос, где прописывать? Можно зайти сюда /etc/httpd/conf/httpd.conf и в самый конец прописать:

    <Directory /var/www/html/test/>
        Php_admin_value mbstring.func_overload 0
    </Directory>
    

    После этого ребутим:

    /etc/init.d/httpd restart
    /etc/init.d/nginx restart
    

    Проверяем генерацию. Все должно работать.

P.S. Если вы в битриксе не хотите заморачиваться, то можете прописать значение mbstring.func_overload для корня, вот как:

<Directory /home/bitrix/www/>
    Php_admin_value mbstring.func_overload 0
    Order allow,deny
    Allow from all
</Directory>

P.S.S. Просьба, если наши ошибки или хотите дополнить выше сказанное, пишите в комментарии. В будущем кто-то может с этим столкнуться. Я с Битриксом знакомлюсь шестой день, всех мелочей не знаю.

Комментарии (1)
  • Ахат Баязи 16 июля 2017, 06:07 # 0
    Тоже столкнулся с проблемой запуска mPDF в оболочке Битрикс. Но не стал заморачиваться с настройкой mbstring.func_overload
    использовал tsPDF. вот моя статейка по теме: Битрикс: Как конвертировать документ в PDF?
    1. Написать комментарий