ย้ายจาก FPDF ไปยัง NextPDF
ภาพรวมโดยสังเขป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสังเขป”คู่มือนี้ช่วยให้คุณย้ายฐานโค้ดที่ใช้ FPDF ไปยัง core ของ NextPDF FPDF เป็นหนึ่งในไลบรารี Portable Document Format (PDF) แบบเก่าของ PHP ที่ถูกนำไปใช้งานอย่างแพร่หลายที่สุด และพื้นผิวการวาดของมัน คือ AddPage, SetFont, Cell, MultiCell, Write, Text, Image, Output ซึ่งขับเคลื่อนด้วยเคอร์เซอร์ x/y แบบกำหนดเอง ย้ายไปยัง API แบบ cell/text ของ NextPDF ได้ค่อนข้างตรงไปตรงมา เพราะเมธอดการวาดระดับล่างของ NextPDF สืบทอดสายเดียวกับ FPDF/TCPDF แต่ NextPDF ไม่ใช่ โคลนแบบ drop-in ของ FPDF มันคือเอนจิน PDF 2.0 สมัยใหม่ที่มีชนิดเข้มงวด การ subset ฟอนต์ การลงนาม PDF/A และการเข้าถึง (tagged PDF) การเปลี่ยนแปลงจริงสองอย่างคือ โมเดลหน่วย (NextPDF ทำงานเป็น PDF points ส่วน FPDF ใช้มิลลิเมตรเป็นค่าเริ่มต้น) และ เวิร์บสำหรับส่งออก (อีนัม OutputDestination แบบมีชนิด แทนอักขระ 'I'/'D'/'F'/'S' ของ FPDF)
ใน core ไม่มี shim คลาส FPDF ให้เขียนจุดเรียกใช้งานแต่ละจุดใหม่โดยใช้การจับคู่เวิร์บ หากต้องการการเปลี่ยนแปลงเริ่มต้นที่น้อยที่สุดสำหรับฐานโค้ด TCPDF 6.x แทน โปรดอ่านอะแดปเตอร์เข้ากันได้กับ TCPDF ซึ่งมีเส้นทาง drop-in ที่เข้ากันได้กับซอร์สเกือบทั้งหมด ส่วน FPDF ไม่มีอะแดปเตอร์เช่นนั้น
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3ให้คง setasign/fpdf (หรือ fpdf/fpdf ของคุณ) ไว้ในระหว่างการย้าย แล้วนำออกหลังการเปลี่ยนผ่านขั้นสุดท้าย (ดูลำดับการย้ายที่ปลอดภัย)
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”FPDF และ NextPDF ใช้แบบจำลองทางความคิดเดียวกัน คือเอกสารที่ประกอบด้วยหน้า, เคอร์เซอร์ (ตำแหน่ง x/y ปัจจุบัน) และเวิร์บที่วาด ณ ตำแหน่งนั้นหรือเลื่อนเคอร์เซอร์นั้นไป SetXY, Cell, Ln และ MultiCell ล้วนอ่านและเปลี่ยนแปลงเคอร์เซอร์ในไลบรารีทั้งสอง ดังนั้นโค้ด FPDF แบบ procedural ส่วนใหญ่จึงแปลได้บรรทัดต่อบรรทัด
ความแตกต่างเหล่านี้เป็นไปโดยเจตนา ไม่ใช่ความบังเอิญ:
- หน่วย คอนสตรักเตอร์ของ FPDF (
new FPDF($orientation, $unit, $size)) มีค่าเริ่มต้นเป็นมิลลิเมตร NextPDF ทำงานเป็น PDF points (1 pt = 1/72 in, ISO 32000-2 §7) ไม่มีปุ่มปรับหน่วยระดับทั้งเอกสาร ให้แปลง mm เป็น points เพียงครั้งเดียว (pt = mm * 72 / 25.4) - ทิศทาง Y คงเดิมสำหรับคุณ เช่นเดียวกับ FPDF พิกัดผู้ใช้ของ NextPDF วาง
y = 0ไว้ที่ขอบบนของหน้าและเพิ่มขึ้นเมื่อลงล่าง ดังนั้นการคำนวณเคอร์เซอร์จึงย้ายได้โดยตรง NextPDF แปลงไปยังจุดกำเนิดมุมล่างซ้ายแบบ PDF-native ภายในเอง - การสร้างเป็นแบบชัดเจน FPDF รวมการวางแนว หน่วย และขนาดไว้ในคอนสตรักเตอร์ ส่วน NextPDF รับอ็อบเจกต์ค่าที่เปลี่ยนแปลงไม่ได้
NextPDF\Core\Config(ขนาดหน้า ระยะขอบ ไดเรกทอรีฟอนต์) และaddPage()แบบชัดเจน - เป็น Unicode เสมอ และ subset เสมอ core build ของ FPDF เป็น Latin-1 และต้องใช้รุ่น tFPDF/UTF-8 เพื่อรองรับ Unicode NextPDF เป็น UTF-8 ทั้งหมด และ เสมอ จะฝังฟอนต์เป็นโปรแกรม subset (ISO 32000-2 §9) ไฟล์
AddFont/font-metric ของ FPDF ไม่มีสิ่งที่เทียบเท่า ให้ลงทะเบียนไดเรกทอรีฟอนต์ TrueType/OpenType แล้วเลือกตระกูลด้วยชื่อ
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”จุดเข้าใช้งานของ core ที่ใช้ด้านล่างคือ Document::createStandalone(), Document::addPage(), Document::setFont(), Document::cell(), Document::multiCell(), Document::text(), Document::write(), Document::ln(), Document::image(), ตัวเข้าถึงเคอร์เซอร์ (setXY/setX/setY/getX/getY), Document::output(?string, OutputDestination), Document::save(string $path): void, Document::getPdfData(): string และอ็อบเจกต์ค่า NextPDF\Core\Config เอกสารอ้างอิงฉบับเต็มของเมธอดการวาด ข้อความ และส่งออกของ core เหล่านี้อยู่ในโมดูล core และดัชนีอ้างอิง ซึ่งสร้างจาก PHPDoc โดยอัตโนมัติ โมดูล Html เป็นเอกสารที่เกี่ยวข้องสำหรับ HTML-to-PDF ไม่ใช่เอกสารอ้างอิงสำหรับเวิร์บในหน้านี้
การจับคู่เวิร์บของ API
หัวข้อที่มีชื่อว่า “การจับคู่เวิร์บของ API”ชื่อเมธอดสาธารณะของ FPDF มีมานานและเป็นที่รู้จักกันดี คอลัมน์ NextPDF ด้านล่างได้รับการยืนยันกับลายเซ็นซอร์สของ core (ดูหลักฐาน / การสืบย้อน)
| FPDF | NextPDF | Notes |
|---|---|---|
new FPDF($orient, $unit, $size) | Document::createStandalone($config) | อาร์กิวเมนต์การวางแนว/หน่วย/ขนาดของคอนสตรักเตอร์กลายเป็น NextPDF\Core\Config (pageSize, margins, fontsDirectory) ไม่มี $unit ให้ทำงานเป็น points หน้าเริ่มต้นของ createStandalone() คือ A4 portrait |
$pdf->AddPage($orient, $size) | $doc->addPage($size, $orientation) | จับคู่ตรง $size เป็นอ็อบเจกต์ค่า PageSize ส่วน $orientation เป็นอีนัม Orientation (Portrait/Landscape) |
$pdf->SetFont($family, $style, $size) | $doc->setFont($family, $style, $size) | จับคู่ตรง $style ใช้รหัส ''/'B'/'I'/'BI' (รวมถึง 'U' underline) เดียวกัน |
$pdf->Cell($w, $h, $txt, $border, $ln, $align, $fill) | $doc->cell($w, $h, $txt, $border, $newLine, $align, $fill) | จับคู่ตรง $align เป็นอีนัม Alignment (Left/Center/Right/Justify) $border รับ bool หรือสตริง 'LTRB' ส่วน $ln กลายเป็น bool $newLine |
$pdf->MultiCell($w, $h, $txt, $border, $align, $fill) | $doc->multiCell($w, $h, $txt, $border, $align) | ตัดคำตามเมตริกฟอนต์จริง ไม่มีอาร์กิวเมนต์ $fill ให้วาด rect() ที่เติมสีก่อนหากต้องการพื้นหลัง |
$pdf->Write($h, $txt, $link) | $doc->write($h, $txt, $link) | ข้อความที่ไหลจากเคอร์เซอร์ $link แนบ annotation ลิงก์ URL |
$pdf->Text($x, $y, $txt) | $doc->text($x, $y, $txt) | ข้อความแบบกำหนดตำแหน่งสัมบูรณ์ จับคู่ตรง |
$pdf->Ln($h) | $doc->ln($h) | ขึ้นบรรทัดใหม่ไปยังระยะขอบซ้าย 0 = ความสูงบรรทัดเริ่มต้น |
$pdf->Image($file, $x, $y, $w, $h) | $doc->image($file, $x, $y, $w, $h) | จับคู่ตรง $x/$y/$w/$h เป็น nullable (null = เคอร์เซอร์ปัจจุบัน / ขนาดตามจริง) |
$pdf->SetXY($x, $y) / SetX / SetY | $doc->setXY($x, $y) / setX / setY | จับคู่ตรง getX()/getY() อ่านค่าเคอร์เซอร์ |
$pdf->SetMargins($l, $t, $r) | $doc->setMargins(new Margin($t, $r, $bottom, $l)) | อ็อบเจกต์ค่า Margin หนึ่งตัว ลำดับคอนสตรักเตอร์คือ (top, right, bottom, left) — ไม่ใช่ (left, top, right) ของ FPDF SetMargins ของ FPDF ไม่มี อาร์กิวเมนต์ bottom (ระยะขอบล่างมาจาก SetAutoPageBreak($auto, $margin)) ดังนั้นจึงต้องเลือก $bottom ด้วยตนเอง โดยทั่วไปเท่ากับระยะขอบบน หรือส่งระยะขอบ auto-page-break |
$pdf->SetAutoPageBreak($auto, $margin) | $doc->setAutoPageBreak($auto, $margin) | จับคู่ตรง |
$pdf->SetDrawColor / SetFillColor / SetTextColor | $doc->setDrawColor / setFillColor / setTextColor | RGB (r, g, b) หรือค่าเดียวสำหรับ grayscale |
$pdf->Line / Rect / SetLineWidth | $doc->line / rect / setLineWidth | จับคู่ตรง rect() รับสตริงสไตล์ ('S'/'F'/'DF') |
$pdf->SetTitle/SetAuthor/SetSubject/SetKeywords/SetCreator | $doc->setTitle/setAuthor/setSubject/setKeywords/setCreator | จับคู่ตรง ลงในข้อมูลเอกสาร / Extensible Metadata Platform (XMP) ตาม ISO 32000-2 §14 |
$pdf->Output($dest, $name) | $doc->output($name, OutputDestination::…) | อักขระปลายทางของ FPDF (I/D/F/S) จับคู่กับอีนัม OutputDestination สังเกตว่า ลำดับอาร์กิวเมนต์สลับกัน (NextPDF ใส่ name ก่อน) |
$pdf->Output('S') | $doc->getPdfData() | คืนค่าไบต์ของ PDF |
$pdf->Output('F', $path) | $doc->save($path) | เขียนไปยัง path ของไฟล์ |
$pdf->GetStringWidth($s) | (ไม่มีเมธอดสาธารณะ) | ความกว้างของสตริงคำนวณภายในระหว่างการตัดคำของ cell()/multiCell() ไม่มีเวิร์บวัดค่าต่อสตริงแบบสาธารณะ ให้ขับเคลื่อนการตัดคำผ่าน multiCell() แทนการวัดด้วยตนเอง |
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\Alignment;use NextPDF\Core\Document;
// FPDF:// $pdf = new FPDF(); // mm, A4 portrait// $pdf->AddPage();// $pdf->SetFont('Arial', 'B', 16);// $pdf->Cell(40, 10, 'Invoice');// $pdf->Output('F', 'out.pdf');
// NextPDF — points, default page is A4 portrait:$doc = Document::createStandalone();$doc->setTitle('Invoice');$doc->addPage();$doc->setFont('Helvetica', 'B', 16.0);$doc->cell(113.4, 28.3, 'Invoice', false, true, Alignment::Left); // ~40mm x ~10mm in points$doc->save(__DIR__ . '/out.pdf');
echo "Wrote out.pdf\n";ตัวอย่างโค้ด — สำหรับการใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — สำหรับการใช้งานจริง”ตัวอย่างนี้สอดคล้องกับ examples/04-text-and-fonts.php โดยใช้ขนาดหน้า ระยะขอบ ไดเรกทอรีฟอนต์ที่ลงทะเบียนไว้อย่างชัดเจน และโมเดล cell ที่ขับเคลื่อนด้วยเคอร์เซอร์ซึ่งฐานโค้ด FPDF ใช้อยู่แล้ว
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\Alignment;use NextPDF\Contracts\OutputDestination;use NextPDF\Core\Config;use NextPDF\Core\Document;use NextPDF\ValueObjects\Margin;use NextPDF\ValueObjects\PageSize;
// Equivalent of: new FPDF('P', 'mm', 'A4') + SetMargins(20, 16, 20)// i.e. FPDF left=20mm, top=16mm, right=20mm. FPDF SetMargins has no bottom// argument, so we pick bottom = top = 16mm. Convert each mm to points// (pt = mm * 72 / 25.4): 16mm = 45.354pt, 20mm = 56.693pt.// Margin constructor order is (top, right, bottom, left) — NOT FPDF's (L, T, R).$config = new Config( pageSize: new PageSize(595.276, 841.890, 'A4'), margins: new Margin(45.354, 56.693, 45.354, 56.693), // top,right,bottom,left in points fontsDirectory: __DIR__ . '/fonts',);
$doc = Document::createStandalone($config);$doc->setTitle('Quarterly Report');$doc->setAuthor('Finance');$doc->addPage();
// SetFont + Cell, the FPDF way — but in points and with a real Unicode font.$doc->setFont('DejaVuSans', 'B', 18.0);$doc->setTextColor(30, 58, 138);$doc->cell(0, 24.0, 'Quarterly Report', false, true, Alignment::Left);
$doc->setFont('DejaVuSans', '', 11.0);$doc->setTextColor(0, 0, 0);$doc->multiCell(0, 16.0, "Body text wraps on real font metrics. Unicode is " . "native, so accented and non-Latin characters need no tFPDF variant — " . "register the family in the fonts directory and select it by name.");
// Equivalent of $pdf->Output('D', 'report.pdf'):$doc->output('report.pdf', OutputDestination::Download);กรณีขอบและจุดที่ควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและจุดที่ควรระวัง”- หน่วย ทุกพิกัด ความกว้าง ความสูง และระยะขอบที่เป็นตัวเลขซึ่งคุณคัดลอกมาจาก FPDF เป็นมิลลิเมตรโดยค่าเริ่มต้น ให้คูณด้วย
72 / 25.4เพื่อแปลงเป็น points เพียงครั้งเดียวระหว่างการย้าย การปนกันของสองหน่วยจะทำให้ทุกอย่างผิดขนาดอย่างเงียบ ๆ - ลำดับอาร์กิวเมนต์ของ
Output()FPDF คือOutput($dest, $name)ส่วน NextPDF คือoutput($name, $dest)ปลายทางเป็นอีนัมOutputDestinationไม่ใช่อักขระ ให้เลือกใช้save()/getPdfData()สำหรับการส่งออกแบบไฟล์ / สตริง - ลำดับของ
SetMarginsFPDF คือ(left, top, right)ส่วนอ็อบเจกต์ค่าMarginของ NextPDF คือ(top, right, bottom, left)ให้จัดลำดับใหม่ อย่าคัดลอกตามตัว - ฟอนต์ ไฟล์เมตริก
AddFont()+.phpของ FPDF ไม่มีสิ่งที่เทียบเท่า ให้วางไฟล์ TrueType/OpenType ในไดเรกทอรีฟอนต์แล้วเรียกsetFont()ด้วยชื่อตระกูล ชื่อ Base14 ของ core (Helvetica,Times,Courier) รีโซลฟ์ได้โดยไม่ต้องมีไฟล์ ภายใต้ PDF/A หรือ tagged PDF ชื่อเหล่านี้จะถูกแทนที่อัตโนมัติด้วยฟอนต์ที่ฝังได้ GetStringWidthไม่มีเมธอดวัดความกว้างสตริงแบบสาธารณะ หากโค้ด FPDF ของคุณวัดสตริงเพื่อจัดวางคอลัมน์ด้วยตนเอง ให้เปลี่ยนบล็อกนั้นเป็นmultiCell()(ซึ่งตัดคำตามเมตริก) หรือการเรียกcell()แบบความกว้างคงที่
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”NextPDF ปล่อยเนื้อหาในรอบสตรีมมิงรอบเดียว (architecture decision record ADR-001) หน่วยความจำสูงสุดแปรตามขนาดเอกสาร ไม่ใช่ตามทรีอ็อบเจกต์ที่ถูกเก็บไว้ งบประมาณสำหรับตัวอย่างในคู่มือนี้คือ wall_ms: 2000, peak_mb: 128 สำหรับเอกสารยาว ให้ขับเคลื่อนเนื้อหาผ่านการเรียก addPage() ซึ่งเป็นรูปแบบลูปเดียวกับที่รายงาน FPDF ใช้อยู่แล้ว
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”- เมทาดาตา
SetTitle()/SetAuthor()จับคู่กับตัวตั้งค่าแบบมีชนิดที่เขียนข้อมูลเอกสาร / XMP ตาม ISO 32000-2 §14 อย่าเก็บความลับไว้ที่นั่น - path ของรูปภาพ
image()ปฏิเสธ scheme แบบ stream-wrapper และไบต์ NUL ที่ฝังอยู่ก่อนอ่าน ให้ส่ง path ที่แอปพลิเคชันควบคุม - ไม่มีโค้ดในเอกสาร NextPDF ไม่รันสคริปต์ใด ๆ ในเอกสาร และไม่มีสิ่งใดใน FPDF ที่เปลี่ยนเรื่องนี้
ความสอดคล้องตามมาตรฐาน
หัวข้อที่มีชื่อว่า “ความสอดคล้องตามมาตรฐาน”| Statement | Spec | Clause |
|---|---|---|
| รูปแบบ/การวางแนวของหน้าจับคู่กับกล่องขอบเขตของหน้า | ISO 32000-2 | §7 |
| ฟอนต์ถูกเขียนเป็นโปรแกรมฟอนต์ที่ฝัง/subset | ISO 32000-2 | §9 |
| ชื่อเรื่อง / เมทาดาตาลงในข้อมูลเอกสาร / XMP | ISO 32000-2 | §14 |
| เส้น สี่เหลี่ยม และรูปภาพคือการวาด content-stream | ISO 32000-2 | §8 |
NextPDF สร้างเนื้อหาตาม ISO 32000-2 มันไม่ได้ยืนยันว่าผลลัพธ์ทางภาพเหมือนกับ FPDF ให้ตรวจทานผลลัพธ์อีกครั้งทุกครั้งที่คุณเปลี่ยนเรนเดอเรอร์
บริบทเชิงพาณิชย์
หัวข้อที่มีชื่อว่า “บริบทเชิงพาณิชย์”ไม่เกี่ยวข้อง core ของ NextPDF ครอบคลุมเส้นทางการย้าย FPDF ที่อธิบายไว้ที่นี่
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”รายละเอียดการย้าย (ส่วนที่ R6 กำหนด)
หัวข้อที่มีชื่อว่า “รายละเอียดการย้าย (ส่วนที่ R6 กำหนด)”หน้านี้เหมาะกับใคร
หัวข้อที่มีชื่อว่า “หน้านี้เหมาะกับใคร”ทีมที่รัน FPDF (หรือ tFPDF) สำหรับการสร้าง PDF ฝั่งเซิร์ฟเวอร์แบบ procedural หากโค้ดของคุณคือลำดับการเรียก AddPage / SetFont / Cell / MultiCell / Image / Output ที่ขับเคลื่อนด้วย SetXY และ Ln การจับคู่เวิร์บ ครอบคลุมพื้นผิวทั้งหมดของคุณ
อยู่ในขอบเขต: เวิร์บการวาดของ FPDF โมเดลเคอร์เซอร์ ฟอนต์ สี เส้นและสี่เหลี่ยม เมทาดาตา และการส่งออก อยู่นอกขอบเขต: เครื่องมือไฟล์เมตริก AddFont ของ FPDF และส่วนขยายสคริปต์ FPDF จากภายนอก (บาร์โค้ด การหมุน บุ๊กมาร์ก) — ให้จับคู่สิ่งเหล่านั้นกับโมดูล NextPDF ที่สอดคล้องกัน (Barcode, Transforms, Navigation) ซึ่งไม่ครอบคลุมในที่นี้
แผนที่ความเข้ากันได้
หัวข้อที่มีชื่อว่า “แผนที่ความเข้ากันได้”ความเข้ากันได้เชิงพฤติกรรม ไม่ใช่ shim แบบ drop-in core ไม่มี shim คลาส FPDF ให้เขียนจุดเรียกใช้งานทุกจุดใหม่ เวิร์บเรียงตัวกันได้ใกล้เคียงเพราะ API แบบ cell/text ของ NextPDF สืบสายร่วมกับ FPDF/TCPDF แต่โมเดลหน่วย ลำดับอาร์กิวเมนต์ของ Output และชนิด Margin/อีนัมแตกต่างกัน ดังนั้นการคัดลอกตามตัวจึงผิด การแปลจึงถูก
แผนที่หน่วยและการกำหนดค่า
หัวข้อที่มีชื่อว่า “แผนที่หน่วยและการกำหนดค่า”| FPDF construct | NextPDF | Notes |
|---|---|---|
$unit ('mm' default) | (no equivalent) | ทำงานเป็น PDF points แปลงมิติด้วย pt = mm * 72 / 25.4 เพียงครั้งเดียวระหว่างการย้าย |
$orientation ('P'/'L') | Orientation enum on addPage(), or swap PageSize width/height | Landscape = width > height |
$size ('A4', [w,h]) | Config->pageSize (PageSize value object) | รูปแบบที่มีชื่อกลายเป็นมิติแบบ point ที่ชัดเจน มีแฟกทอรี PageSize::A4()…A0() และ Letter/Legal |
SetMargins($l, $t, $r) | Config->margins (Margin VO) | ลำดับคอนสตรักเตอร์ (top, right, bottom, left) |
AddFont($family, $style, $file) | fonts directory + setFont() by name | ทิ้งไฟล์เมตริก วางไฟล์ TTF/OTF ใน Config->fontsDirectory |
ส่วนต่างของการจัดการฟอนต์
หัวข้อที่มีชื่อว่า “ส่วนต่างของการจัดการฟอนต์”- ไดเรกทอรีฟอนต์ การลงทะเบียน
AddFontต่อฟอนต์ของ FPDF ยุบรวมเป็นไดเรกทอรีฟอนต์บวกกับการจับคู่ตระกูลด้วยsetFont()เริ่มต้นด้วยConfig->fontsDirectory(เส้นทางค้นหาเริ่มต้น) ลงทะเบียนไดเรกทอรีเพิ่มเติมผ่านFontRegistry::addFontDirectory()หรือDocument::addFontDirectory()เมื่อฟอนต์อยู่ในมากกว่าหนึ่งที่ - เป็น Unicode เสมอ ไม่มีค่าเริ่มต้น Latin-1 และไม่มี build tFPDF แยกต่างหาก อินพุต UTF-8 คือมาตรฐาน
- subset เสมอ NextPDF subset ฟอนต์ที่ฝังเสมอ (ISO 32000-2 §9) ตัวเลือกการฝังฟอนต์ของ FPDF ไม่มีสิ่งที่เทียบเท่าและไม่จำเป็น
- ตั้งฐานกลีฟใหม่ การจับคู่และการ fallback ของฟอนต์เป็นเรื่องเฉพาะเอนจิน นามแฝงฟอนต์ของ FPDF อาจต้องใช้ชื่อตระกูลที่แม่นยำ ความแตกต่างในการแทนที่เป็นสิ่งที่คาดหมายได้ ไม่ใช่ข้อบกพร่อง
ความแตกต่างเชิงพฤติกรรม
หัวข้อที่มีชื่อว่า “ความแตกต่างเชิงพฤติกรรม”- การแปลงหน่วย (mm → pt) — ความผิดพลาดในการย้ายที่พบบ่อยที่สุด ดูด้านบน
- ลำดับอาร์กิวเมนต์ของ
Outputสลับกัน และปลายทางกลายเป็นอีนัม Margin/Alignment/Orientationเป็นอ็อบเจกต์/อีนัมแบบมีชนิด ไม่ใช่อักขระหรือทริปเล็ตตามตำแหน่ง(l, t, r)- ไม่มี
GetStringWidthสาธารณะ — ขับเคลื่อนการตัดคำผ่านmultiCell() - การ rasterize อิสระ — การตัดบรรทัดและการแบ่งหน้าบนเนื้อหาหนาแน่นอาจต่างกัน ให้ตั้งฐานความแตกต่างทางภาพใหม่
สิ่งเหล่านี้เป็นความแตกต่างเชิงพฤติกรรมที่มีเอกสารกำกับ ไม่ใช่ข้อบกพร่องของเอนจินใดเอนจินหนึ่ง
ไม่รองรับ / ไม่มีสิ่งที่เทียบเท่าโดยตรง
หัวข้อที่มีชื่อว่า “ไม่รองรับ / ไม่มีสิ่งที่เทียบเท่าโดยตรง”- ตัวเลือก
$unitของ FPDF — ไม่ได้สร้างแบบจำลอง (เป็น points เสมอ) - ไฟล์เมตริก
AddFont()+.php/.z— ถูกแทนที่ด้วยไดเรกทอรีฟอนต์ GetStringWidth()— ไม่มีเวิร์บวัดความกว้างสตริงแบบสาธารณะ- อักขระปลายทาง
'I'/'D'/'F'/'S'ของ FPDF — ถูกแทนที่ด้วยอีนัมOutputDestination+save()/getPdfData()
โค้ดที่ขึ้นอยู่กับสิ่งเหล่านี้ไม่ “ย้าย” แบบคำต่อคำ ให้แสดงใหม่ด้วยแถวด้านบน
ลำดับการย้ายที่ปลอดภัย
หัวข้อที่มีชื่อว่า “ลำดับการย้ายที่ปลอดภัย”- เพิ่ม
nextpdf/coreควบคู่กับ FPDF คง FPDF ไว้ก่อน - เลือกเอกสารความเสี่ยงต่ำหนึ่งฉบับ แปลงคอนสตรักเตอร์ผ่านแผนที่หน่วย แล้วย้ายแต่ละเวิร์บด้วยแผนที่เวิร์บ แปลงทุกพิกัด mm เป็น points
- วางฟอนต์ของเอกสารใน
Config->fontsDirectoryแล้วเลือกด้วยชื่อตระกูล ทิ้งการเรียกAddFont - สร้าง PDF ทั้งสองสำหรับอินพุตเดียวกันแล้วเทียบความต่างทางภาพ ความแตกต่าง (การแทนที่ฟอนต์ การตัดบรรทัด) เป็นสิ่งที่คาดหมายได้สำหรับเอนจินอิสระ — ยอมรับได้ต่อเอกสาร
- แทนที่การจัดวางด้วยตนเองที่อิงกับ
GetStringWidthด้วยการเรียกmultiCell()หรือcell()แบบความกว้างคงที่ - ทำซ้ำต่อเอกสาร โดยเริ่มจากความเสี่ยงต่ำสุดก่อน คง FPDF ไว้จนถึงการเปลี่ยนผ่านครั้งสุดท้าย
- นำ FPDF ออกจาก
composer.jsonหลังการเปลี่ยนผ่านขั้นสุดท้าย
การทดสอบการย้าย
หัวข้อที่มีชื่อว่า “การทดสอบการย้าย”- ทำ snapshot ผลลัพธ์ FPDF สำหรับเอกสารตัวแทนก่อนเปลี่ยนโค้ด (golden inputs โดยไบต์จะต่างกัน)
- สำหรับเอกสารที่ย้ายแต่ละฉบับ ให้ยืนยันการยอมรับด้วยการตรวจสอบของคุณเอง (เทียบความต่างทางภาพ + การแยกข้อความ) พฤติกรรม cell/font ของ NextPDF ถูกตรวจสอบโดย
examples/04-text-and-fonts.phpบวกกับชุดทดสอบ Font และ text-output ในtests/ของ core การยอมรับการย้ายเป็นเรื่องเฉพาะเอกสารและยังคงเป็นความรับผิดชอบของคุณ - เพิ่มการทดสอบ regression ต่อเอกสารที่ย้าย
หลักฐาน / การสืบย้อน
หัวข้อที่มีชื่อว่า “หลักฐาน / การสืบย้อน”ทุกข้อความเชิงพฤติกรรมของ NextPDF ในหน้านี้มีลายเซ็นซอร์สในที่เก็บ ตัวอย่าง หรือ architecture decision record (ADR) รองรับ หรือสำหรับคุณสมบัติรูปแบบ PDF มีคลอส ISO 32000-2 ในส่วน citations: ของ frontmatter และตารางความสอดคล้อง รองรับ พฤติกรรมของ FPDF ถูกยืนยันเพียงว่า “เอนจินอิสระ — คาดหมายความแตกต่างที่มีเอกสารกำกับ” เท่านั้น หน้านี้ไม่อ้างความเทียบเท่าใดที่อาร์ติแฟกต์ในที่เก็บไม่ได้พิสูจน์
| NextPDF behavioral claim | In-repo evidence (path) |
|---|---|
AddPage maps to addPage(?PageSize, Orientation): static. | src/Core/Concerns/HasPages.php (addPage()). |
SetFont($family, $style, $size) maps to setFont(string, string, float): static; ''/'B'/'I'/'BI'/'U' styles. | src/Core/Concerns/HasTypography.php (setFont()). |
Cell maps to cell($w, $h, $txt, $border, $newLine, $align, $fill): static. | src/Core/Concerns/HasTextOutput.php (cell()). |
MultiCell maps to multiCell($w, $h, $txt, $border, $align): static (metric-based wrap). | src/Core/Concerns/HasTextOutput.php (multiCell(), wrapText()). |
Write/Text/Ln map to write()/text()/ln(). | src/Core/Concerns/HasTextOutput.php (write(), text(), ln()). |
SetXY/SetX/SetY/GetX/GetY map directly; SetMargins takes a Margin VO. | src/Core/Concerns/HasPages.php (setXY(), getX(), setMargins()); src/ValueObjects/Margin.php ((top, right, bottom, left)). |
Image maps to image($file, ?$x, ?$y, ?$w, ?$h): static; rejects scheme/NUL paths. | src/Core/Concerns/HasImages.php (image(), assertImageFilePath()). |
Line/Rect/SetLineWidth/SetDrawColor/SetFillColor/SetTextColor map directly. | src/Core/Concerns/HasDrawing.php (line(), rect(), setLineWidth()); src/Core/Concerns/HasColors.php (setDrawColor(), setFillColor(), setTextColor()). |
createStandalone() default page is A4 portrait (595.276 × 841.890 pt). | src/Core/Document.php (createStandalone()); src/ValueObjects/PageSize.php (A4()). |
Output destination is the OutputDestination enum (Inline/Download/File/String); Output('S') → getPdfData(), Output('F', $p) → save($p). | src/Contracts/OutputDestination.php; src/Core/Concerns/HasOutput.php (output()). |
SetTitle/SetAuthor/… map to typed metadata setters; land in the info dictionary / XMP. | src/Core/Concerns/HasMetadata.php (setTitle(), setAuthor()); ISO 32000-2 §14 (frontmatter citations:). |
| Fonts are always embedded as subset programs. | src/Core/Concerns/HasTypography.php (buildFontData()); ISO 32000-2 §9 (frontmatter citations:). |
| Content is emitted single-pass. | docs/architecture/adr/ADR-001-stream-based-rendering-pipeline.md. |
การย้อนกลับ
หัวข้อที่มีชื่อว่า “การย้อนกลับ”แพ็กเกจทั้งสองยังติดตั้งอยู่จนถึงการเปลี่ยนผ่านครั้งสุดท้าย ดังนั้นการย้อนกลับต่อจุดเรียกใช้งานหมายถึงการคืนจุดเรียกใช้งานนั้นกลับไปยังเส้นทาง FPDF หลังการเปลี่ยนผ่านครั้งสุดท้าย การย้อนกลับหมายถึงการคืน FPDF และโค้ดเดิมจากระบบควบคุมเวอร์ชัน ไม่มีการย้ายข้อมูลเข้ามาเกี่ยวข้อง
ข้อพิจารณาด้านประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ข้อพิจารณาด้านประสิทธิภาพ”ดูประสิทธิภาพ โมเดลรอบเดียวขจัดต้นทุนบัฟเฟอร์ที่ถูกเก็บไว้ ต้นทุนใหม่ต่อเอกสารคือการรีโซลฟ์ฟอนต์แบบ eager (ขั้นที่ 3) ซึ่งแคชได้ผ่านไดเรกทอรีฟอนต์
กับดักที่พบบ่อย
หัวข้อที่มีชื่อว่า “กับดักที่พบบ่อย”- คัดลอกพิกัดมิลลิเมตรเป็น points โดยไม่มีการแปลง
* 72 / 25.4 - ปล่อย
Output()ไว้ในลำดับ($dest, $name)ของ FPDF หรือส่งอักขระแทนอีนัมOutputDestination - คัดลอก
SetMargins($l, $t, $r)ตรง ๆ เข้าไปในMargin(ซึ่งลำดับคือtop, right, bottom, left) - คาดหวังให้ไฟล์เมตริก
AddFontย้ายได้ ให้วางไฟล์ TTF/OTF ในไดเรกทอรีฟอนต์แทน - มองหาสิ่งที่เทียบเท่า
GetStringWidthให้ใช้multiCell()สำหรับการตัดคำ - คาดหวังผลลัพธ์ที่เหมือนกันทุกไบต์/พิกเซล (เอนจินอิสระ — คู่มือนี้ไม่เคยอ้างว่าเป็น drop-in หรือเข้ากันได้ 100%)