ข้ามไปยังเนื้อหา

การแก้ไขปัญหา NextPDF ใน CodeIgniter 4

อาการแต่ละข้อด้านล่างเชื่อมโยงกับสาเหตุที่ยืนยันได้จากซอร์สของแพ็กเกจหรือเฟรมเวิร์ก และมีวิธีแก้ไขที่ทำตามได้ชัดเจน

เมื่อ CodeIgniter resolve เซอร์วิส จะสแกนคลาส Config\Services ที่ค้นพบเพื่อหาเมธอดที่ตรงกัน การคืนค่า null หมายความว่า CodeIgniter ไม่ได้ค้นพบคลาส Services ของแพ็กเกจ

ตรวจสอบสาเหตุและแนวทางแก้ไขต่อไปนี้:

  • การค้นพบอัตโนมัติถูกปิดใช้งาน แอปพลิเคชันโฮสต์อาจตั้งค่า Config\Modules::$discoverInComposer = false หากเป็นเช่นนั้น ให้เพิ่ม nextpdf/codeigniter เข้าไปใน $composerPackages['only'] CodeIgniter จะสแกนแพ็กเกจ Composer ก็ต่อเมื่อแฟล็กนี้เป็น true เท่านั้น
  • ตัวโหลดอัตโนมัติล้าสมัย Composer จะแมปคำนำหน้าเนมสเปซ NextPDF\CodeIgniter\ ไปยังไดเรกทอรีฐาน หาก classmap ล้าสมัย คลาสนี้จะถูกซ่อนไว้ (PSR-4 §x1.x3) รัน composer dump-autoload
  • รายการ $aliases ถูกตัดออก การค้นพบจะทำงานเฉพาะกับรายการที่อยู่ใน Config\Modules::$aliases เท่านั้น แพ็กเกจต้องการ services รวมถึง registrars สำหรับเฮลเปอร์ ให้คืนค่ารายการทั้งสองรายการ

เฮลเปอร์จะถูกโหลดผ่านสองเส้นทาง: รายการ autoload files ของ Composer ในแพ็กเกจ และ Registrar ของแพ็กเกจ ข้อผิดพลาด undefined-function หมายความว่ารายการ files ยังไม่ได้ถูกโหลด

  • รัน composer dump-autoload เพื่อสร้างรายการ autoload files ขึ้นใหม่
  • ยืนยันว่า nextpdf/codeigniter ปรากฏอยู่ใน vendor/composer/autoload_files.php
  • หากต้องการวิธีแก้เฉพาะหน้า ให้เรียก Services::pdf(false) หรือ Services::pdfDocument(false) โดยตรง เฮลเปอร์เป็น wrapper บางๆที่ครอบการเรียกเหล่านี้อยู่

เมื่อประมวลผลการแทนที่ค่า BaseConfig จะใช้ชื่อคลาสแบบสั้นในรูปตัวพิมพ์เล็กเป็นคำนำหน้า เนื่องจากคลาสคือ NextPdf คำนำหน้าจึงเป็น nextpdf ไม่ใช่ nextPdf หรือ NextPdf

  • ใช้ nextpdf.fontsPath ไม่ใช่ nextPdf.fontsPath
  • สำหรับคีย์ที่ซ้อนกัน ให้ใช้จุด: nextpdf.signature.certificate
  • รูปแบบชื่อเต็ม NextPDF\CodeIgniter\Config\NextPdf.fontsPath ก็ใช้งานได้เช่นกัน

อาร์เรย์การกำหนดค่าทั้งชุดกลับไปใช้ค่าเริ่มต้น

หัวข้อที่มีชื่อว่า “อาร์เรย์การกำหนดค่าทั้งชุดกลับไปใช้ค่าเริ่มต้น”

เมื่อคุณสืบทอดคลาส NextPdf และกำหนดอาร์เรย์เพียงบางส่วน CodeIgniter จะแทนที่อาร์เรย์ทั้งชุด ระบุคีย์ทุกตัวในอาร์เรย์ที่คุณแทนที่ ดูตัวอย่างอาร์เรย์ทั้งชุดได้ที่ /integrations/codeigniter/configuration/

รีจิสทรีฟอนต์จะตรวจสอบ mbstring และ zlib เพียงหนึ่งครั้งต่อโพรเซส และจะส่งข้อผิดพลาดนี้พร้อมชื่อส่วนขยายที่ขาดหายไป ติดตั้งหรือเปิดใช้งานส่วนขยายที่ระบุใน PHP ขณะรันไทม์ จากนั้นรีสตาร์ตเวิร์กเกอร์หรือพูลของ PHP FastCGI Process Manager (PHP-FPM)

รีจิสทรีฟอนต์จะปฏิเสธ fontsPath ที่มี stream wrapper (://) หรือ null byte ตั้งค่า fontsPath เป็นพาธในระบบไฟล์แบบธรรมดา อย่าชี้ไปที่พาธที่ใช้ wrapper เช่น php://, phar:// หรือพาธลักษณะเดียวกัน

PdfResponse จะทำความสะอาดชื่อไฟล์ พฤติกรรมที่ยืนยันแล้วและคาดการณ์ได้มีดังนี้:

  • ชื่อไฟล์ที่ว่างเปล่าหรือมีแต่ช่องว่างจะกลายเป็น document.pdf
  • ชื่อที่ไม่มีนามสกุล .pdf (หรือ .PDF) จะถูกเติม .pdf ต่อท้าย ส่วน .PDF ที่มีอยู่แล้วจะถูกคงไว้ตามเดิม
  • ชื่อที่มีอักขระที่ไม่ใช่ ASCII จะสร้างทั้ง ASCII fallback และ พารามิเตอร์ RFC 5987 filename*=UTF-8''… ดังนั้นเบราว์เซอร์สมัยใหม่จึงแสดงชื่อเดิม นี่เป็นพฤติกรรมที่คาดการณ์ได้ ไม่ใช่ข้อบกพร่อง
  • ตัวคั่นพาธ null byte และ carriage return/line feed (CR/LF) จะถูกตัดออก

ทุก PdfResponse จะมี X-Content-Type-Options, X-Frame-Options, Content-Security-Policy, X-Robots-Tag และ Referrer-Policy หากเฮดเดอร์เหล่านี้หายไปที่ฝั่งไคลเอ็นต์ แสดงว่าพร็อกซีหรือแอปพลิเคชันกำลังตัดออกหรือเขียนทับในชั้นปลายน้ำ ตรวจสอบการตอบสนองทั้งก่อนและหลัง reverse proxy ของคุณ

คิวจะตรวจสอบชื่องานที่ push เทียบกับคีย์ใน Config\Queue::$jobHandlers และปฏิเสธชื่อใดๆที่ไม่ได้ลงทะเบียนไว้ ลงทะเบียนงานภายใต้คีย์ที่เป็นชื่อ จากนั้น push ชื่อนั้น:

app/Config/Queue.php
public array $jobHandlers = ['generate-pdf' => GeneratePdfJob::class];
// dispatch
\service('queue')->push('pdf-queue', 'generate-pdf', [...]);

การ push GeneratePdfJob::class เป็นชื่องานจะล้มเหลว อาร์กิวเมนต์ตัวที่สองคือคีย์ที่เป็นชื่อ ไม่ใช่สตริงของคลาส

งานจะตรวจสอบ payload ก่อนเริ่มทำงานใดๆ กรณีที่ยืนยันแล้วว่าถูกปฏิเสธจะคืนส่วนของข้อความต่อไปนี้:

สาเหตุส่วนของข้อความ
builder ขาดหายไป ว่างเปล่า หรือไม่ใช่สตริงnon-empty static callable string
builder อยู่นอก App\PdfBuildersnot allowed
builder ตรงกับรูปแบบแต่ไม่สามารถเรียกใช้ได้not a valid callable
outputPath ขาดหายไปหรือว่างเปล่าnon-empty string
outputPath อยู่นอก WRITEPATH/pdfs/outside of allowed directory
outputPath ไม่ได้ลงท้ายด้วย .pdfmust end with .pdf

แก้ไข payload ให้ builder เป็น static callable รูปแบบ App\PdfBuilders\<Class>::<method> ตรวจสอบให้แน่ใจว่าพาธเอาต์พุตหลัง resolve อยู่ภายใน WRITEPATH/pdfs/ และลงท้ายด้วยนามสกุล .pdf

เนื่องจาก codeigniter4/queue เป็น dependency สำหรับการพัฒนาเท่านั้นของแพ็กเกจ แอปพลิเคชันที่รันเวิร์กเกอร์จึงต้อง require แพ็กเกจนี้โดยตรง:

Terminal window
composer require codeigniter4/queue
  • composer show nextpdf/codeigniter — ยืนยันว่า Composer resolve แพ็กเกจแล้ว
  • composer dump-autoload — สร้างรายการสำหรับการค้นพบและ autoload ของเฮลเปอร์ขึ้นใหม่
  • php spark routes — ยืนยันว่าเส้นทาง PDF ของคุณลงทะเบียนแล้ว
  • วิธีตรวจสอบการค้นพบที่เร็วที่สุดคือใช้คอนโทรลเลอร์ที่เรียก Services::pdfDocument(false) และยืนยันว่าผลลัพธ์เป็น Document
  • การแมปคลาสไปยังพาธ — เกี่ยวข้องกับความล้มเหลวของการค้นพบ (PSR-4 Autoloader §x1.x3)
  • /integrations/codeigniter/install/ — ข้อกำหนดสำหรับการค้นพบ
  • /integrations/codeigniter/configuration/ — คำนำหน้า .env และกฎการแทนที่อาร์เรย์
  • /integrations/codeigniter/production-usage/ — การลงทะเบียนคิวที่ถูกต้อง
  • /integrations/codeigniter/boot-and-discovery/ — ลำดับการค้นพบ