Pemecahan masalah paket NextPDF Laravel
Sekilas
Bagian berjudul “Sekilas”Gunakan halaman ini untuk memetakan setiap kegagalan paket yang terlihat ke akar penyebab di tingkat sumber yang telah diverifikasi. Setiap entri mencantumkan gejala, penyebab, dan perbaikannya.
Pemasangan
Bagian berjudul “Pemasangan”composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configTinjauan konseptual
Bagian berjudul “Tinjauan konseptual”Sebagian besar masalah yang dilaporkan masuk ke lima kelompok: penemuan, resolusi kontainer, penandatanganan, job antrean, dan nama berkas Hypertext Transfer Protocol (HTTP). Paket ini sengaja dirancang agar gagal secara jelas. Fitur opsional yang tidak dikonfigurasi mengembalikan null, dan input yang tidak aman melempar eksepsi bertipe. Gejala biasanya langsung menunjuk ke penyebabnya.
Permukaan API — gejala ke penyebab
Bagian berjudul “Permukaan API — gejala ke penyebab”Penemuan dan boot
Bagian berjudul “Penemuan dan boot”| Gejala | Penyebab terverifikasi | Perbaikan |
|---|---|---|
| Provider tidak terdaftar setelah pemasangan | Aplikasi menonaktifkan penemuan dengan extra.laravel.dont-discover | Hapus paket dari dont-discover, atau daftarkan NextPdfServiceProvider secara manual di bootstrap/providers.php |
config('nextpdf') kosong | Konfigurasi tidak digabungkan karena belum ada binding yang diiklankan yang diresolusi (provider yang ditangguhkan) | Resolusikan salah satu entri provides(), atau konfirmasi penemuan dengan php artisan package:discover --ansi |
config/nextpdf.php tidak dibuat oleh publish | Tag publish tidak cocok | Gunakan tag yang tepat: php artisan vendor:publish --tag=nextpdf-config |
| RuntimeException: “NextPDF requires the ext-mbstring/ext-zlib PHP extension” | Ekstensi Hypertext Preprocessor (PHP) yang diperlukan tidak tersedia saat runtime | Pasang atau aktifkan mbstring dan zlib di php.ini |
Resolusi kontainer
Bagian berjudul “Resolusi kontainer”| Gejala | Penyebab terverifikasi | Perbaikan |
|---|---|---|
app(SignerInterface::class) mengembalikan null | Penandatanganan dinonaktifkan, atau sertifikat di nextpdf.signature kosong | Setel signature.enabled = true dan isi signature.certificate yang valid; pasang nextpdf/premium untuk menyediakan implementasi konkret penanda tangan |
app(TsaClient::class) mengembalikan null | nextpdf.tsa.url kosong | Konfigurasikan tsa.url (dan credentials/pins sesuai kebutuhan) |
| Class-not-found untuk tipe versi PDF/A | nextpdf.pdfa bukan null tetapi nextpdf/premium tidak terpasang | Pasang nextpdf/premium, atau setel kembali pdfa ke null |
| Class-not-found saat meresolusi kontrak e-invoice | Binding terdaftar, tetapi implementasi konkret Premium tidak ada | Pasang nextpdf/premium; kontrak e-invoice diresolusi secara lazy dan baru gagal saat resolusi pertama tanpa Premium |
| Dokumen yang sama dimutasi di dua operasi logis | Binding dokumen adalah factory; Anda menggunakan kembali satu instance yang telah diresolusi | Resolusikan PdfDocumentInterface yang baru untuk setiap dokumen |
Kontainer tanpa entri memunculkan eksepsi not-found pada get() (PHP Standard Recommendation 11 (PSR-11) §1.1.2). Kontrak e-invoice terikat, jadi has() pada kontainer mengembalikan true. Implementasi konkret Premium yang hilang memunculkan galat saat konstruksi, bukan dari kontainernya sendiri.
Job antrean
Bagian berjudul “Job antrean”| Gejala | Penyebab terverifikasi | Perbaikan |
|---|---|---|
InvalidArgumentException: Path traversal sequences are not allowed | Path output berisi segmen .. | Gunakan path absolut tanpa traversal di bawah direktori penyimpanan Anda |
InvalidArgumentException: Stream wrappers are not allowed | Path menggunakan skema seperti php:// | Gunakan path sistem berkas biasa |
InvalidArgumentException: Output path contains null bytes | Path berisi bita \0 | Bersihkan path sebelum dispatch |
InvalidArgumentException: Output path must end with .pdf extension | Path tidak diakhiri dengan .pdf (tidak peka huruf besar/kecil) | Gunakan akhiran .pdf (atau .PDF) |
| Job berjalan tetapi berkas kosong atau salah | Closure builder tidak mengembalikan dokumen yang sudah dikonfigurasi | Kembalikan dokumen dari builder; job menyimpan nilai yang dikembalikan |
| Job menggunakan antrean atau timeout yang salah | nextpdf.queue.* tidak disetel seperti yang diharapkan | Setel queue.queue, queue.connection, dan queue.timeout; tries dan backoff memerlukan subkelas |
Pemeriksaan path dijalankan di dalam handle() pada worker, jadi path yang buruk gagal selama eksekusi, bukan saat dispatch. Ini disengaja: worker memvalidasi payload antrean terserialisasi tepat di titik payload itu dikonsumsi.
Respons HTTP dan nama berkas
Bagian berjudul “Respons HTTP dan nama berkas”| Gejala | Penyebab terverifikasi | Perbaikan |
|---|---|---|
Nama berkas unduhan secara tak terduga menjadi document.pdf | Anda meneruskan nama berkas kosong; factory menggunakan nilai standar | Teruskan nama berkas yang tidak kosong |
| Nama berkas kehilangan path atau karakter khusus | Proses pembersihan nama berkas menghapus pemisah path, karakter kontrol, dan bita null | Teruskan hanya nama berkas dasar; pengerasan ini memang diharapkan |
| Nama berkas non-ASCII menampilkan mojibake di sebagian klien | Respons memancarkan RFC 5987 Request for Comments 5987 filename*= untuk nama non-ASCII; klien lama membaca cadangan ASCII | Sesuai harapan; sediakan nama yang aman untuk ASCII jika klien lama harus cocok persis |
Respons stream tidak memiliki Content-Length | Respons stream sengaja menghilangkan Content-Length (output dikirim per potongan) | Sesuai harapan; gunakan inline()/download() non-stream jika header panjang diperlukan |
Contoh kode — diagnostik
Bagian berjudul “Contoh kode — diagnostik”# Confirm the provider is discoveredphp artisan package:discover --ansi
# Inspect merged configurationphp artisan tinker --execute="dump(config('nextpdf.queue'));"<?php
declare(strict_types=1);
use NextPDF\Contracts\SignerInterface;
$signer = app(SignerInterface::class);
if ($signer === null) { // Signing not configured, or nextpdf/premium not installed. // Continue without a signature, or fail with a clear message.}Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”- Dengan provider yang ditangguhkan, pemasangan baru bisa tampak “rusak” hingga resolusi relevan pertama. Anggap pencantuman paket oleh
package:discoversebagai sinyal keberhasilan. - Ketika
image_cache_mb = null, paket beralih ke 50 MB; hanya0yang menonaktifkan cache. Laporan “cache tidak nonaktif” biasanya menggunakannull. - Ketika
signature.level = null, paket beralih diam-diam ke PDF Advanced Electronic Signatures (PAdES) B-B. Laporan “B-B tak terduga” biasanya membiarkan level tidak disetel.
Kinerja
Bagian berjudul “Kinerja”Jika beberapa permintaan pertama pada worker berumur panjang terasa lambat, registri fon sedang mengurai sesuai permintaan. Isi nextpdf.preload_fonts agar pemanasan berjalan satu kali saat boot worker. Lihat /integrations/laravel/configuration/ dan /integrations/laravel/boot-and-discovery/ untuk detailnya.
Catatan keamanan
Bagian berjudul “Catatan keamanan”Penolakan path dan nama berkas merupakan kontrol keamanan, bukan bug. Jangan menyiasatinya dengan melakukan pra-dekode atau melonggarkan pemeriksaan. Sebagai gantinya, arahkan output berkas melalui path penyimpanan yang terkendali. Lihat /integrations/laravel/security-and-operations/.
Konformansi
Bagian berjudul “Konformansi”| Klaim | Sumber | Klausa | reference_id |
|---|---|---|---|
| Entri kontainer yang hilang memunculkan not-found pada get() | PSR-11 Container | §1.1.2 |
Lihat juga
Bagian berjudul “Lihat juga”- /integrations/laravel/install/ — langkah penemuan dan publish
- /integrations/laravel/configuration/ — setiap kunci dan nilai standarnya
- /integrations/laravel/production-usage/ — pola dependency injection (DI) dan antrean
- /integrations/laravel/security-and-operations/ — alasan keberadaan pemeriksaan path