Перейти к содержимому

Покрытие методов TCPDF в NextPDF compat-legacy

nextpdf/compat-legacy — это слой совместимости, а не форк TCPDF и не гарантированный клон поведения. Он предоставляет имена публичных методов TCPDF 6.x, порядок параметров и значения по умолчанию поверх основного движка NextPDF. Большинство вызовов напрямую отображается на операции NextPDF Document. Небольшая часть принимает устаревшие параметры, которые NextPDF не учитывает или которые не дают эффекта.

Эта страница сводит результаты аудита методов в удобный для чтения вид. Авторитетная и проверяемая тестами матрица покрытия находится в репозитории, в файле docs/TCPDF_COVERAGE.md. Если эта страница и матрица в репозитории расходятся, приоритет имеет матрица в репозитории, потому что её проверяет тестовый набор.

Используйте эту страницу, чтобы ответить на один вопрос перед миграцией: для каждого метода TCPDF, который вызывает моя кодовая база, что на самом деле делает адаптер?

В ходе аудита было обследовано около 120 публичных методов TCPDF 6.x. Каждый метод отнесён ровно к одной из четырёх категорий.

КатегорияКоличествоЧто это значит для вас
Зеркальные — полностью делегируются94Вызов напрямую отображается на метод NextPDF Document. Поведение совместимо для документированных параметров.
Тихо игнорируемые — частично15Метод выполняется и возвращает результат, но один или несколько параметров TCPDF не дают эффекта. Это документированное поведенческое различие.
Нереализованные — пустое тело4Метод существует ради совместимости исходного кода, но ничего не делает.
Неприменимо7Метод TCPDF не влияет на вывод PDF; намеренно исключён.
Дополнительные методы дрейфа современного API17Методы Document из NextPDF v5.1+, доступные в адаптере, чтобы код со смешанным API компилировался. У них нет эквивалента в TCPDF 6.x.

Эти цифры взяты из docs/TCPDF_COVERAGE.md §Summary. Тестовый набор проверяет матрицу через tests/Unit/Compat/Tcpdf/TcpdfApiDriftTest.php и tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php.

Замечание о формулировках. Этот пакет не претендует на роль “прямой замены” или “100% совместимого с TCPDF”. Он покрывает 94 из обследованных ~120 методов TCPDF прямым делегированием. Для остальных методов есть документированные поведенческие различия, описанные ниже. Точнее описывать его как совместимую с TCPDF альтернативу с известной, протестированной поверхностью совместимости.

Адаптер построен из 25 трейтов с единственной ответственностью (src/Compat/Tcpdf/Concerns/), которые в сумме предоставляют 273 публичных метода, плюс небольшое число методов жизненного цикла и аварийного завершения в самом классе TCPDF. Приведённые выше категории покрытия учитывают отдельные методы поверхности API TCPDF 6.x (~120), а не общее число публичных методов адаптера. Эти два числа измеряют разное: покрытие поверхности API и размер реализации. Если в README.md пакета указано меньшее число трейтов или методов, считайте авторитетными docs/TCPDF_COVERAGE.md и эту страницу. Сводка в README была написана до появления трейта AdaptsDriftV51.

1. Зеркальные методы — совместимое делегирование

Заголовок раздела «1. Зеркальные методы — совместимое делегирование»

Девяносто четыре метода напрямую отображаются на базовый экземпляр NextPDF\Core\Document. Имена TCPDF в PascalCase отображаются на имена NextPDF в camelCase там, где движок использует camelCase. Ради прямой и обратной совместимости адаптер принимает оба варианта написания.

Типичные группы (полная таблица: docs/TCPDF_COVERAGE.md §1):

Область TCPDFПримеры методовТрейт адаптера
Жизненный циклOutput(), Close(), getPDFData()AdaptsLifecycle
СтраницыAddPage(), getNumPages(), deletePage()AdaptsPageManagement
ТекстCell(), MultiCell(), Write(), Text(), Ln()AdaptsTextOutput
ШрифтыSetFont(), SetFontSize(), AddFont()AdaptsFonts
ЦветаSetTextColor(), SetDrawColor(), SetFillColor()AdaptsColors
РисованиеLine(), Rect(), Circle(), Polygon(), Arrow()AdaptsDrawing
ПреобразованияRotate(), Scale(), Translate(), Skew(), Mirror*()AdaptsTransforms
НавигацияAddLink(), Annotation(), addTOC()AdaptsNavigation

Для этих методов наблюдаемое поведение совместимо с TCPDF 6.x для параметров, документированных в NextPDF. Адаптер не гарантирует, что вывод PDF будет побайтово идентичным. Базовый движок — независимая реализация PDF 2.0, поэтому байты могут различаться даже тогда, когда видимый результат эквивалентен. Если ваши тесты проверяют точные байты PDF, а не отрисованное содержимое, рассчитывайте обновить эталоны для этих проверок. См. /integrations/tcpdf-compat/migration/ для рекомендуемой стратегии обновления эталонов.

2. Тихо игнорируемые методы — документированные поведенческие различия

Заголовок раздела «2. Тихо игнорируемые методы — документированные поведенческие различия»

Эти 15 методов выполняются и возвращают результат, но хотя бы один параметр TCPDF принимается ради совместимости исходного кода, а затем игнорируется. Прочитайте этот раздел перед миграцией. Эти вызовы не завершаются ошибкой; они тихо выполняют меньше действий, чем оригинальный TCPDF.

Метод TCPDFИгнорируемые параметрыСовместимая альтернатива
Image()параметры: type, link, align, resize, dpi, palign, ismask, imgmask, border, fitbox, hidden, fitonpage, alt, altimgsNextPDF image() принимает file, x, y, width, height. Для кликабельного изображения выведите изображение, затем добавьте Document::link() поверх того же прямоугольника. Маскирование изображений и альтернативные изображения не поддерживаются.
writeHTML()параметры: ln, fill, reseth, cell, alignNextPDF writeHtml() обрабатывает только содержимое. Чтобы управлять макетом, оберните HTML в позиционированный блок через современный API.
writeHTMLCell()border (в строковой форме), ln, fill, reseth, autopaddingШирина, высота, позиция и булева рамка учитываются; расширенный макет ячейки не имеет соответствия в движке.
ImageEps()параметры: link, useBoundingBox, align, palign, border, fitonpage, fixoutvalsУчитываются только позиция и размер.
ImageSVG()параметры: link, align, palign, border, fitonpageУчитываются только позиция и размер.
SetProtection()mode (ненулевой), pubkeys (непустой)NextPDF всегда использует AES-256 для стандартного обработчика. Для шифрования на основе сертификатов используйте современный setPublicKeyEncryption(), доступный в адаптере (см. /integrations/tcpdf-compat/security-and-operations/).
Bookmark()параметры: style, color, x, isNamedDestЗаголовок, уровень и позиция по y учитываются.
setDestination()параметры: page, xИмя и позиция по y учитываются.
Link()параметр: spacesВнутреннее для TCPDF отслеживание пробелов; эквивалента в движке нет.
Annotation()ключи option помимо Subtype, spacesТип, позиция и текст учитываются.
SetLineStyle()детали штрихового узора, кроме шириныОсновные свойства линии отображаются.
setAlpha()частичное отображение режимов наложенияУ некоторых имён режимов наложения нет эквивалента в движке.
Polycurve()полный список параметровВ режиме по умолчанию ничего не делает; эквивалента в движке нет.
PieSectorXY()полный список параметровЧастичное отображение (линии от центра к краю различаются).
RoundedRectXY()радиус для каждого углаТолько единый радиус для всех углов.

То, как адаптер сообщает об этих различиях, зависит от строгого режима (см. /integrations/tcpdf-compat/configuration/). При выключенном строгом режиме — значении по умолчанию, обеспечивающем обратную совместимость, — эти вызовы тихо деградируют. При включённом строгом режиме каждый вызов, который игнорирует параметр, выбрасывает TcpdfNotImplementedException с точным списком игнорируемых параметров и подсказкой по миграции. Строгий режим — инструмент аудита, а не настройка для продакшена.

Дизайн строгого режима следует принципу, согласно которому вызывающая сторона должна явно видеть, когда её намерение не учтено. OWASP ASVS 5.0 §16.5.3 требует, чтобы приложения завершались с ошибкой корректно и безопасно и предотвращали сценарии небезопасного отказа (fail-open). Тихая потеря параметра — это скорее ловушка для разработчика, чем уязвимость, но тот же принцип явного отказа применим и здесь. Закреплённый дайджест пункта находится в разделе citations начального блока страницы.

Четыре метода существуют, чтобы устаревший исходный код компилировался, но их тела ничего не делают. При включённом строгом режиме три из них выбрасывают TcpdfNotImplementedException. Четвёртый (Open()) — намеренная безопасная пустая операция, которая никогда не выбрасывает исключение, потому что этот вызов всегда можно безопасно удалить из устаревшего кода.

Метод TCPDFПоведениеЗамена
setSignature()Пустая операция (ничего действующего не сохраняет). Выбрасывает исключение в строгом режиме.Для цифровой подписи требуется коммерческая редакция NextPDF. Используйте современный API подписи с объектом-значением CertificateInfo; см. /integrations/tcpdf-compat/security-and-operations/.
addEmptySignatureAppearance()Пустая операция. Выбрасывает исключение в строгом режиме.То же ограничение коммерческой редакции, что и у setSignature().
endPage()Пустая операция. Выбрасывает исключение в строгом режиме.NextPDF управляет жизненным циклом страниц автоматически. Удалите вызов.
Open()Безопасная пустая операция. Никогда не выбрасывает исключение.NextPDF открывает документ автоматически. Вызов всегда можно безопасно удалить.

Подпись не доступна в основном движке через этот адаптер. Адаптер предоставляет современную точку входа для подписи, которая делегирует движку. Базовая поддержка подписи ограничена коммерческой редакцией. Эта документация не делает никаких утверждений о профилях подписи с долгосрочной валидацией или метками времени для какой-либо редакции. См. /integrations/tcpdf-compat/security-and-operations/ для точной, осторожной формулировки.

Семь методов TCPDF не влияют на вывод PDF и намеренно исключены. Их безопасно вызывать.

Метод TCPDFПочему исключён
setDocCreationTimestamp() / setDocModificationTimestamp()Состояние хранится в адаптере, но не связано с метаданными XMP документа. В выводе не видно.
setSRGBmode()Управление цветом в NextPDF не зависит от этого флага.
setPDFVersion()NextPDF выбирает версию PDF из своего профиля conformance/output; прямого сеттера нет. Адаптер выдаёт уведомление и продолжает работу.
setDocInfoUnicode()NextPDF всегда работает в Unicode; сам флаг ничего не делает.
setDefaultMonospacedFont()Эквивалента в движке нет; вместо него применяется стилизация HTML/CSS.
setFontSubsetting()NextPDF всегда создаёт подмножества встроенных шрифтов; флаг фактически всегда включён.

Версия PDF задаётся движком. Вывод записывается как PDF 2.0 (ISO 32000-2). ISO 32000-2 §7.5.2 определяет, что программа записи, соответствующая стандарту, указывает версию документа — в заголовке файла или в записи Version каталога — как 2.0. В нём также указано, что сохранение файла не понижает его версию. Это соответствует поведению адаптера: такие вызовы, как setPDFVersion('1.4'), не могут понизить целевую версию PDF до более старой через этот адаптер. Закреплённый дайджест пункта находится в разделе citations начального блока страницы.

Семнадцать методов из ядра NextPDF v5.1+ доступны в адаптере (трейт AdaptsDriftV51), чтобы код, смешивающий API TCPDF с современным API, по-прежнему компилировался. У них нет эквивалента в TCPDF 6.x. Примеры: getWarnings(), hasWarnings(), embedFileFromString(), enableBiDi(), beginTag() / endTag(), enableLinearization(), useAesGcm(), useDocumentMac(), setConformanceMode(). Рассматривайте их как современный API, а не как часть контракта совместимости с TCPDF.

Если ваш код вызывает…СтатусСделайте вместо этого
Error()Поведение изменено (усилено)Адаптер заменяет вызов die() из TCPDF на выбрасывание RuntimeException. Оборачивайте рискованные вызовы в try/catch; не полагайтесь на завершение процесса.
setPDFVersion()НеприменимоУдалите. Вывод всегда в формате PDF 2.0.
setUserRights()Устарело в PDF 2.0Удалите. Вызов выдаёт уведомление E_USER_DEPRECATED и игнорируется.
setSignature()Не реализовано в ядреПерейдите на современный API подписи в коммерческой редакции.
Image(...) с дополнительными параметрамиТихо игнорируетсяОставьте только file, x, y, w, h; добавьте Document::link() для кликабельных изображений.
endPage() / Open()Не реализовано / пустая операцияУдалите.
  1. Установите пакет и запустите имеющийся набор тестов на адаптере без изменений в коде. См. /integrations/tcpdf-compat/install/ и /integrations/tcpdf-compat/quickstart/.
  2. Включите строгий режим в отдельном прогоне аудита (не в продакшене): $pdf->setStrictMode(true);. Зафиксируйте каждое TcpdfNotImplementedException. Каждое из них называет точные игнорируемые параметры и подсказку по миграции.
  3. Для каждого места, где выбрасывается исключение, решите, убрать ли игнорируемый параметр или перенести этот вызов на современный API через $pdf->getDocument().
  4. Обновите эталоны для любого теста, который проверяет точные байты PDF; вместо этого проверяйте отрисованное содержимое или структурные свойства.
  5. Выключите строгий режим и разверните проверенный путь выполнения. Сохраните регулярную задачу CI со строгим режимом, чтобы ловить регрессии по мере рефакторинга.

Полная процедура с кодом: /integrations/tcpdf-compat/migration/.

  • docs/TCPDF_COVERAGE.md — авторитетная, проверенная тестами матрица покрытия (в репозитории)
  • /integrations/tcpdf-compat/migration/ — полная стратегия миграции с TCPDF на NextPDF
  • /integrations/tcpdf-compat/configuration/ — строгий режим и настройка адаптера
  • /integrations/tcpdf-compat/security-and-operations/ — подход к шифрованию и подписи
  • /integrations/tcpdf-compat/integration/ — подключение адаптера к приложению
  • /integrations/tcpdf-compat/boot-and-discovery/ — регистрация псевдонимов классов и предоставление фасада