العقود / الدفق
لمحة سريعة
قسم بعنوان «لمحة سريعة»يتضمن نطاق الدفق واجهتين experimental: StreamingWriterInterface لإخراج PDF تدريجيًا، وCursorInterface لتأليف المحتوى على مستوى الصفحة. يوفّر Core محركًا نهائيًا مختبَرًا يطبّق الواجهتين. فئات المحرك داخلية، لذلك استخدم العقد experimental العام بدلًا من تطبيق المحرك بنفسك. وبما أن المستوى experimental، فقد يتغير العقد في إصدار ثانوي مع إشعار إهمال مسبق. ثبّت الإصدار بإحكام أو غلّفه خلف مهايئ خاص بك قبل الاعتماد عليه في الإنتاج.
التثبيت
قسم بعنوان «التثبيت»composer require nextpdf/core:^3نظرة مفاهيمية
قسم بعنوان «نظرة مفاهيمية»يُسلسِل كاتب الدفق كل صفحة أثناء تأليفها، وقد يدفعها إلى الإخراج قبل بدء الصفحة التالية. استخدمه عندما قد يتجاوز المستند ميزانية الذاكرة المتاحة. يحتفظ الكاتب الموجود في الذاكرة بالمستند كاملًا، أما كاتب الدفق فلا يفعل ذلك. يعرّف StreamingWriterInterface آلة حالات صارمة. تبدأ النسخة الجديدة في الحالة CLOSED. ينقلها open() إلى OPEN ويكتب ترويسة PDF إلى دفق يوفّره المُستدعي. ينقلها newPage() إلى PAGING ويُرجِع مؤشرًا. يكتب close() بنية الإحالة المرجعية والمُذيّل، ثم ينقلها إلى حالة نهائية CLOSED. يربط دفق الإحالة المرجعية كل رقم كائن بإزاحته بالبايت، كما يغطي ذلك ISO 32000-2 §7. تُشغَّل جلسة واحدة فقط لكل نسخة. بعد close() تصبح النسخة مُستنفَدة. يملك المُستدعي مورد الدفق. يكتب الكاتب إليه، لكنه لا يغلقه أبدًا.
CursorInterface هو سطح الكتابة على مستوى الصفحة. تحصل على مؤشر من StreamingWriterInterface::newPage()، ويظل صالحًا حتى تُنهيه، أو حتى يُنهيه استدعاء newPage() التالي تلقائيًا، أو حتى يُبطله close(). الإبطال دائم. لا يمكن إعادة تنشيط المؤشر. أي طريقة تُستدعى على مؤشر مُبطَل تطرح LogicException. يكتب المؤشر عوامل تشغيل دفق المحتوى الخام، ويُعيّن الخط النشط، ويكتب نصًا مُموضَعًا. يرمّز دفق المحتوى محتوى الصفحة كتسلسل من عوامل تشغيل الرسوميات، كما يغطي ذلك ISO 32000-2 §8. المؤشر سطح منخفض المستوى: لا يجري تشكيل النص، ولا إعادة الترتيب ثنائية الاتجاه، ولا فصل الأسطر، ولا أي تخطيط. تبقى هذه من مسؤوليات مستوى المستند. يظل ثابت المؤشر الواحد قائمًا طوال الوقت: لا يكون صالحًا في أي وقت أكثر من مؤشر واحد.
كلتا الواجهتين experimental، ويوفّر Core محركًا عاملًا خلفهما: تطبيق StreamingWriterInterface نهائي، ومؤشر صفحته، ومصرف إهمال يُستخدم لقياس أداء الذاكرة. فئات المحرك هذه داخلية وليست جزءًا من السطح العام. لاستخدام الدفق، اعتمد على العقد experimental ودع Core يوفّر التطبيق. يشير PHPDoc في كل نوع إلى ADR كاتب الدفق لآلة حالات دورة الحياة ومسوّغ النطاق. وبما أن المستوى experimental، فقد يتغير توقيع العقد في إصدار ثانوي مع إشعار إهمال مسبق. ثبّت الإصدار بإحكام أو غلّفه خلف مهايئ خاص بك قبل الاعتماد عليه في الإنتاج.
سطح الـ API
قسم بعنوان «سطح الـ API»| النوع | الصنف | الأعضاء الرئيسيون | الاستقرار | منذ |
|---|---|---|---|---|
StreamingWriterInterface | واجهة | open(resource, Config)، newPage(?PageSize): CursorInterface، close() | تجريبي (محرك مُورَّد) | 3.1.0 |
CursorInterface | واجهة | writeContent(string)، setFont(string, string, float)، writeText(float, float, string)، finalizePage() | تجريبي (محرك مُورَّد) | 3.1.0 |
يطرح open() InvalidArgumentException عند تمرير دفق غير قابل للكتابة، وLogicException إذا كان الكاتب مفتوحًا بالفعل. close() ليس آمنًا عند تكرار الاستدعاء. استدعاؤه مرتين يطرح استثناءً.
عينة شيفرة — بداية سريعة
قسم بعنوان «عينة شيفرة — بداية سريعة»<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\StreamingWriterInterface;use NextPDF\Core\Config;
/** * Drive a streaming writer through one page. * * The parameter is the experimental contract; Core supplies the * implementation. Type-hint the interface and let the engine satisfy it. * * @param StreamingWriterInterface $writer A Core-supplied streaming writer. * @param resource $stream A writable, caller-owned stream. */function writeOnePage(StreamingWriterInterface $writer, $stream): void{ $writer->open($stream, new Config()); $cursor = $writer->newPage(); $cursor->setFont('helvetica', '', 12.0); $cursor->writeText(72.0, 720.0, 'Streamed page.'); $cursor->finalizePage(); $writer->close(); // The caller closes $stream after close() returns.}تستهدف الدالة الواجهة experimental، لذلك تبقى منفصلة عن فئة المحرك. يحقن Core تطبيقًا عاملًا عند موضع الاستدعاء.
عينة شيفرة — إنتاج
قسم بعنوان «عينة شيفرة — إنتاج»<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\StreamingWriterInterface;use NextPDF\Core\Config;use NextPDF\ValueObjects\PageSize;use Psr\Log\LoggerInterface;
final readonly class LargeReportStreamer{ public function __construct( private StreamingWriterInterface $writer, private LoggerInterface $logger, ) {}
/** * Stream a multi-page report to a caller-owned file handle. * * @param resource $stream Writable file handle owned by the caller. * @param list<list<string>> $pages One list of text lines per page. */ public function stream($stream, array $pages): void { $this->writer->open($stream, new Config());
try { foreach ($pages as $lines) { $cursor = $this->writer->newPage(PageSize::A4()); $cursor->setFont('helvetica', '', 11.0);
$y = 760.0; foreach ($lines as $line) { $cursor->writeText(72.0, $y, $line); $y -= 14.0; }
$cursor->finalizePage(); } } finally { $this->writer->close(); } }}تضمن كتلة finally إغلاق الكاتب وكتابة المُذيّل، حتى إذا طرحت حلقة الصفحات استثناءً. يظل الدفق مملوكًا للمُستدعي، وهو من يغلقه.
الحالات الحدّية والمزالق
قسم بعنوان «الحالات الحدّية والمزالق»- اعتمد على الواجهة لا على فئة المحرك. المحرك الذي يطبّق كلا العقدين داخلي وليس جزءًا من السطح العام. لا تُنشئه بـ
newولا تُشِر إليه بالاسم. استخدم تلميح النوعStreamingWriterInterfaceودع Core يوفّر التطبيق. - العقد
experimental. قد يتغير توقيعه في إصدار ثانوي، مع إشعار إهمال مسبق. ثبّت الإصدار بإحكام أو غلّفه خلف مهايئ خاص بك قبل الاعتماد عليه في الإنتاج. - يصبح المؤشر غير صالح في اللحظة التي يُستدعى فيها
newPage()أوclose()التالي. الاحتفاظ بمؤشر قديم واستدعاء طريقة عليه يطرحLogicException. أنهِه صراحةً لزيادة الوضوح. close()ليس آمنًا عند تكرار الاستدعاء. استدعاؤه مرتين خطأ من المُستدعي، وليس حالة قابلة للتعافي. يطرح العقد استثناءً.- لا يغلق الكاتب الدفق أبدًا. إذا نسيت إغلاق مَقبِض يملكه المُستدعي بعد عودة
close()، فإنك تُسرّب واصف ملف. - يدفع المحرك كل صفحة مُنهاة بحيث لا تنمو الذاكرة المقيمة مع عدد الصفحات. الملف الدقيق لاستهلاك الذاكرة خاصية من مستوى
experimentalوقد يتغير بين الإصدارات الثانوية. لا تُضمِّن افتراضًا ثابتًا مبنيًا على قياس واحد.
الأداء
قسم بعنوان «الأداء»يحدّ تصميم الدفق من ذروة الذاكرة. يدفع المحرك المُورَّد كل صفحة مكتملة ويُحرّر مخزنها المؤقت، بحيث لا تنمو المجموعة المقيمة مع عدد الصفحات، بخلاف الكاتب الموجود في الذاكرة. يُفرِّغ المحرك سجلات الإحالة المرجعية وشجرة الصفحات إلى دفقات مؤقتة مدعومة بالقرص للحفاظ على بصمة العملية شبه ثابتة. أرقام الذاكرة والزمن الفعلي الملموسة خاصية من مستوى experimental وقد تتغير بين الإصدارات الثانوية، لذلك لا تؤكّد هذه الصفحة أي رقم ثابت. إن performance_budget البالغ 1500 ms زمنًا فعليًا و64 MB ذروةً هو غلاف اللوحة، وليس ضمانًا تعاقديًا. قابلية إعادة الإنتاج bitwise: المحتوى والتهيئة نفساهما يُنتجان مخرجات متطابقة بالبايت، وهو ما تثبّته اختبارات الأساس الذهبي للمحرك.
ملاحظات أمنية
قسم بعنوان «ملاحظات أمنية»طريقة writeContent() في المؤشر هي مَخرج طوارئ منخفض المستوى. تُلحق البايتات المُزوّدة بدفق محتوى الصفحة حرفيًا، ولا تتحقق من بنية عوامل التشغيل أو دلالاتها. الإدخال غير الموثوق المُمرَّر إلى writeContent() يُنتج PDF تالفًا أو خبيثًا. عامِل هذه الطريقة كسطح للإدخال الموثوق فقط، وفضِّل writeText() لأي نص يتأثر بالمُستدعي. يُهرّب المؤشر المُورَّد النص المُمرَّر إلى writeText() وفق قواعد سلسلة PDF الحرفية، لكنه لا يُنقّي عوامل التشغيل الخام. نموذج الدفق المملوك للمُستدعي خاصية أمنية أيضًا. يكتب المحرك إلى الدفق، لكنه لا يغلقه أو يعيد فتحه أبدًا، لذلك لا يمكنه إعادة توجيه الإخراج. سطح الهجوم وقت التشغيل حقيقي لأن المحرك مُورَّد. يجب على المُستدعين ألّا يُغذّوا writeContent() أبدًا ببايتات غير موثوقة، ويجب على المحرك أن يحترم ثوابت العقد.
المطابقة
قسم بعنوان «المطابقة»| الادعاء | المعيار | البند | الدليل |
|---|---|---|---|
| يُرمّز دفق المحتوى محتوى الصفحة كتسلسل من عوامل تشغيل الرسوميات، التي يُلحقها المؤشر. | ISO 32000-2 | §8 | |
| يُصدِر الكاتب بنية إحالة مرجعية تربط كل رقم كائن بإزاحته بالبايت عند الإغلاق. | ISO 32000-2 | §7 |
كلا البندين مثبَّتان في المسرد ومُعاد صياغتهما. لا يُعيد NextPDF إنتاج أي نص معياري. يحتوي ADR كاتب الدفق المُشار إليه من PHPDoc العقد على دورة الحياة ومسوّغ النطاق.
السياق التجاري
قسم بعنوان «السياق التجاري»يُورَّد محرك دفق مختبَر في Core مفتوح المصدر خلف هذه العقود experimental. فئات المحرك داخلية، لذلك استخدم الدفق من خلال العقد العام بدلًا من اسم فئة محدد. يتّبع NextPDF Pro وNextPDF Enterprise العقد نفسه، لذلك تظل الشيفرة المكتوبة على أساس StreamingWriterInterface في Core صالحة مع تطبيق Premium للعقد نفسه. القيد هو المستوى experimental، لا الإصدار أو التوفر. قد يتغير التوقيع في إصدار ثانوي مع إشعار إهمال مسبق.
انظر أيضًا
قسم بعنوان «انظر أيضًا»- العقود: 41 واجهة عامة (SPI) تغطي نظرة عامة على SPI ومستويات الاستقرار.
- العقود / المستند تغطي الكاتب الموجود في الذاكرة الذي تُكمّله هذه العقود.
- الكاتب يغطي كائن PDF ومُصدِر الإحالة المرجعية.
- HTML / قيود الدفق (ADR-001) تغطي مسوّغ نطاق الدفق.
- الأداء يغطي مسوّغ الحد من الذاكرة لإخراج الدفق.