NextPDF для CodeIgniter 4
nextpdf/codeigniter подключает движок NextPDF для Portable Document Format (PDF) к приложению CodeIgniter 4 через слой Services фреймворка. PDF-документы можно создавать в контроллерах, задачах или командах, а затем возвращать как нативные ответы CodeIgniter по протоколу Hypertext Transfer Protocol (HTTP).
Установка
Заголовок раздела «Установка»composer require nextpdf/codeigniterВ файле composer.json пакета указаны требования: php >=8.4 <9.0,
nextpdf/core ^3.0 || ^5.2 и codeigniter4/framework ^4.6. Также пакет
рекомендует nextpdf/artisan, nextpdf/premium и codeigniter4/queue. Полную таблицу требований, необязательные пакеты и шаги проверки см. в /integrations/codeigniter/install/.
Концептуальный обзор
Заголовок раздела «Концептуальный обзор»NextPDF — это движок PDF 2.0 на PHP 8.4. Базовый движок (nextpdf/core) не зависит от фреймворка: он ничего не знает о HTTP, маршрутизации и связывании зависимостей. nextpdf/codeigniter — адаптер, который подключает движок к приложению CodeIgniter 4. После установки адаптера не нужно вручную настраивать реестры, фабрики и обработку ответов.
Пакет добавляет в приложение CodeIgniter 4 четыре вещи:
- Класс Services (
NextPDF\CodeIgniter\Config\Services), который CodeIgniter обнаруживает автоматически. Он предоставляет именованные сервисы:fontRegistry,imageRegistry,documentFactory,pdfDocument,pdf,tsaClientиpdfSigner. - Библиотека
Pdf(NextPDF\CodeIgniter\Libraries\Pdf) — высокоуровневый интерфейс application programming interface (API) для контроллеров. Она оборачивает один одноразовый документ и за один вызов превращает его в ответ. - Помощник
PdfResponse(NextPDF\CodeIgniter\Http\PdfResponse), который создаётDownloadResponseCodeIgniter для встроенного просмотра или загрузки. Он добавляет фиксированный набор заголовков, которые усиливают защиту ответа. - Две глобальные вспомогательные функции —
pdf()иpdf_document(). Они регистрируются через запись автозагрузкиfilesв Composer и черезRegistrarпакета.
Пакет также обнаруживает необязательные расширения NextPDF при сборке документа. Если установлен nextpdf/artisan и настроен исполняемый файл Chrome, документ получает отрисовщик Chrome. Если установлен NextPDF Pro, вывод PDF/A и цифровая подпись доступны через тот же набор Services. Обнаружение выполняется условно и без вывода сообщений. Пакет никогда не требует отсутствующее расширение.
Почему класс Services, а не привязка в контейнере
Заголовок раздела «Почему класс Services, а не привязка в контейнере»CodeIgniter 4 не поставляется с контейнером внедрения зависимостей PSR-11. Вместо этого он использует локатор Services. Локатор Services — это класс со статическими фабричными методами, который фреймворк может обнаружить. Каждый метод возвращает либо общий экземпляр, либо новый. В PSR-11 §1.3 паттерн service locator — передача контейнера в объект, чтобы тот сам извлекал свои зависимости, — помечен модальным глаголом SHOULD NOT. Пакет следует соглашению о локаторах CodeIgniter. При этом поверхность локатора остаётся минимальной и явной: каждый сервис — это именованный фабричный метод с параметром bool $getShared, и вызывающий код получает конкретные объекты, а не дескриптор контейнера.
Благодаря этому интеграция CodeIgniter согласована с интеграциями Laravel и Symfony. Каждая интеграция предоставляет одни и те же логические сервисы через идиому своего фреймворка.
Поверхность API
Заголовок раздела «Поверхность API»| Точка входа | Тип | Возвращает | Время жизни |
|---|---|---|---|
Services::fontRegistry() | сервис | FontRegistryInterface | общий (прогрет, затем заблокирован) |
Services::imageRegistry() | сервис | ImageRegistry | общий (ограниченный кэш least recently used (LRU)) |
Services::documentFactory() | сервис | DocumentFactoryInterface | общий (без состояния) |
Services::pdfDocument(false) | сервис | NextPDF\Core\Document | новый при каждом вызове |
Services::pdf(false) | сервис | NextPDF\CodeIgniter\Libraries\Pdf | новый при каждом вызове |
Services::tsaClient() | сервис | ?TsaClient | общий; null, когда нет URL центра меток времени (TSA) |
Services::pdfSigner(false) | сервис | ?SignerInterface | новый; null, когда подпись отключена |
pdf() | помощник | Pdf | новый при каждом вызове |
pdf_document() | помощник | Document | новый при каждом вызове |
PdfResponse::inline() / download() | статический | DownloadResponse | на вызов |
GeneratePdfJob | задача очереди | — | одна на отправку |
Пример кода — быстрый старт
Заголовок раздела «Пример кода — быстрый старт»Контроллер возвращает PDF в три строки. Services::pdf() возвращает новый экземпляр библиотеки Pdf, которая оборачивает новый документ. Затем download() создаёт DownloadResponse CodeIgniter.
<?php
declare(strict_types=1);
namespace App\Controllers;
use CodeIgniter\HTTP\DownloadResponse;use NextPDF\CodeIgniter\Config\Services;
final class InvoiceController extends BaseController{ public function download(int $id): DownloadResponse { $pdf = Services::pdf(); $pdf->document()->addPage(); $pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf"); }}Полное пошаговое руководство, которое можно запустить, находится в /integrations/codeigniter/quickstart/. В нём разобраны маршрутизация, встроенный просмотр и варианты с помощниками pdf() и pdf_document().
Пример кода — продакшен
Заголовок раздела «Пример кода — продакшен»В продакшене запрашивайте отдельный экземпляр через Services::pdf(false). Перехватывайте единое базовое исключение, NextPDF\Exception\NextPdfException; все ошибки ядра и расширений наследуются от него. Логируйте сбой с контекстом, а не подавляйте ошибку.
try { $pdf = Services::pdf(false); $pdf->document()->addPage(); $pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf");} catch (NextPdfException $e) { $logger->error('pdf.invoice.failed', [ 'invoice_id' => $id, 'exception' => $e::class, 'message' => $e->getMessage(), ]);
return $this->response ->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR) ->setJSON(['error' => 'pdf_generation_failed', 'invoice_id' => $id]);}Полный продакшен-контроллер находится в /integrations/codeigniter/production-usage/. Он добавляет тайминг для наблюдаемости, безопасное время жизни для воркеров и асинхронную генерацию.
Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»- Реестры шрифтов и изображений — это синглтоны на время жизни процесса. Документ никогда не разделяется между вызовами.
pdfDocumentиpdfпри каждом вызове возвращают новый экземпляр, поэтому один запрос не может передать содержимое в другой.Services::pdf(false)иpdf()оба возвращают новый экземпляр библиотеки, которая оборачивает новый документ. - Пакет требует PHP-расширений
mbstringиzlib. Реестр шрифтов проверяет их один раз за процесс. Если какого-либо из расширений нет, реестр шрифтов выбрасывает ошибку времени выполнения с указанием отсутствующего расширения. - Поведение необязательных расширений зависит от того, что установлено в том же приложении. Когда присутствует только
nextpdf/core, пути подписи и PDF/A возвращаютnullили пропускаются. Они никогда не завершаются шумной ошибкой.
Производительность
Заголовок раздела «Производительность»Интеграция не добавляет измеримых накладных расходов сверх самого движка. Реестр шрифтов разбирается один раз, а затем блокируется. Реестр изображений — это кэш LRU, ограниченный настройкой imageCacheMb (50 MB по умолчанию). Затраты на сборку PDF определяют базовый движок и содержимое документа, а не адаптер. Бюджет на страницу для этого набора документации составляет 1500 ms по времени / 128 MB пиковой памяти. Отдельные рецепты задают собственный бюджет во фронтматтере.
Замечания по безопасности
Заголовок раздела «Замечания по безопасности»PdfResponse добавляет фиксированный набор заголовков ответа к каждому выдаваемому PDF: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag: noindex, nofollow и Referrer-Policy: no-referrer. Имена файлов очищаются, а имена вне ASCII передаются с расширенным параметром Request for Comments (RFC) 5987. Задача очереди ограничивает вызываемые билдеры пространством имён App\PdfBuilders и ограничивает пути вывода каталогом WRITEPATH/pdfs/. Полную модель угроз см. в /integrations/codeigniter/security-and-operations/.
Соответствие
Заголовок раздела «Соответствие»- Обнаружение модулей опирается на автозагрузку PSR-4 в Composer. Префикс пространства имён сопоставляется с базовым каталогом, а полностью квалифицированное имя класса — с путём к файлу (PSR-4 §x1.x3).
- Дизайн Services следует рекомендациям по локаторам, обсуждаемым в PSR-11 §1.3.
Коммерческий контекст
Заголовок раздела «Коммерческий контекст»Ядро NextPDF распространяется под лицензией Apache-2.0. Цифровые подписи, архивирование PDF/A и встраивание электронных счетов Factur-X предоставляются NextPDF Pro и NextPDF Enterprise. Пакет CodeIgniter предоставляет соответствующие сервисные методы. Эти методы возвращают null, пока в том же приложении не установлен соответствующий пакет Premium.
См. также
Заголовок раздела «См. также»- /integrations/codeigniter/install/ — установка и проверка пакета.
- /integrations/codeigniter/quickstart/ — первый PDF в контроллере.
- /integrations/codeigniter/configuration/ — каждый ключ конфигурации.
- /integrations/codeigniter/boot-and-discovery/ — как CodeIgniter находит класс Services.
- /integrations/codeigniter/integration/ — справочник по подключению и дымовой тест.