تخطَّ إلى المحتوى

العقود / الرمز الشريطي

يُعرِّف مجال الرمز الشريطي أربعة عقود: مُرمِّزًا أحادي البُعد (1⁨D⁩)، ومُرمِّزًا ثنائي البُعد (2⁨D⁩)، ومُرمِّزًا عامًا قابلًا للاكتشاف عبر السجل، ومحلِّل بيانات ⁨GS1.⁩ وتُحدِّد هذه العقود معًا الشكل الذي يجب أن تلتزم به خدمات الرمز الشريطي. تُسجِّل تطبيقات الترميز (⁨symbology⁩) نفسها وفق هذه العقود.

Terminal window
composer require nextpdf/core:^3

يُحوِّل مُرمِّز الرمز الشريطي سلسلة الحمولة (⁨payload⁩) إلى مصفوفة الوحدات التي يرسمها كاتب صيغة المستند المحمول (⁨PDF⁩). يفصل ⁨NextPDF⁩ عقود المُرمِّزات بحسب الأبعاد. يتولّى Barcode1DEncoderInterface الترميزات الخطية، بما في ذلك ⁨Code 128⁩ و⁨EAN-13⁩، ويُعيد كائن قيمة BarcodeData. ويتولّى Barcode2DEncoderInterface الترميزات المصفوفية، بما في ذلك رمز الاستجابة السريعة (⁨QR⁩) و⁨Data Matrix.⁩ ويُعيد كائن قيمة Barcode2DData مع خريطة خيارات للإعدادات الخاصة بالترميز، مثل مستوى تصحيح الأخطاء.

BarcodeEncoderInterface هو عقد مزوِّد الخدمة العام. يُطبِّقه أيُّ مُرمِّز ثنائي البُعد قابل للاكتشاف عبر BarcodeEncoderRegistry. يُعيد العقد إمّا مصفوفة Barcode2DData أحادية اللون وإمّا مصفوفة BarcodeColorData ملوّنة، بحيث يستطيع المُرمِّز المُسجَّل إنتاج رمز ملوّن دون واجهة منفصلة. يُتوقَّع أن تكون المُرمِّزات عديمة الحالة (⁨stateless⁩) خارج إعدادات وقت الإنشاء. ويُعيد السجل نسخةً مشتركةً واحدةً لكل نوع مُسجَّل، لذلك تُعَدُّ أي حالة خاصة بكل استدعاء عيبًا.

Gs1DataParserInterface هو عقد البيانات المُهيكَلة. يُحلِّل سلسلة عناصر ⁨GS1⁩ إلى كائن مُحدَّد النوع، ثم يُعيد ترميز ذلك الكائن لحامل رمز الاستجابة السريعة (⁨QR⁩) أو ⁨Data Matrix⁩ أو ⁨Code 128.⁩ وهذا يُبقي قواعد ⁨GS1⁩ منفصلةً عن الترميز. يتحقّق المحلِّل من مُعرِّفات التطبيق (⁨Application Identifiers⁩) مرةً واحدة. وتُنسِّق الطرق الخاصة بكل حامل البنيةَ المُحلَّلة نفسها لكل هدف. العقود الأربعة stable. BarcodeEncoderInterface مستقر منذ 3.0.0؛ والبقية مستقرة منذ 1.0.0. لا تُضاف الطرق الجديدة إلّا مع تطبيقات افتراضية.

النوعالصنفالأعضاء الرئيسيةالاستقرارمنذ
Barcode1DEncoderInterfaceواجهةencode(string): BarcodeDataمستقر1.0.0
Barcode2DEncoderInterfaceواجهةencode(string, array): Barcode2DDataمستقر1.0.0
BarcodeEncoderInterfaceواجهةencode(string, array): Barcode2DData|BarcodeColorDataمستقر3.0.0
Gs1DataParserInterfaceواجهةparse()، encodeForQrCode()، encodeForDataMatrix()، encodeForCode128()مستقر1.0.0

في العقود ثنائية البُعد، تكون مصفوفة $options خاصةً بالترميز، مثل مستوى تصحيح الأخطاء لرمز الاستجابة السريعة (⁨QR⁩). لا يُقيِّد العقد مفاتيح هذه المصفوفة. ويُوثِّق كل مُرمِّز مُسجَّل مجموعة خياراته الخاصة.

examples/10-barcodes.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Barcode\Barcode2DType;
use NextPDF\Barcode\BarcodeType;
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Barcode Examples');
$doc->addPage();
$doc->setFont('helvetica', '', 10);
$doc->cell(0, 6, 'Code 128:', newLine: true);
$doc->write1DBarcode('NEXTPDF-2026', BarcodeType::C128, x: 15, y: null, w: 80, h: 20);
$doc->ln(28);
$doc->cell(0, 6, 'QR Code (URL):', newLine: true);
$doc->write2DBarcode('https://nextpdf.dev', Barcode2DType::QRCode, x: 15, y: null, w: 40, h: 40);
$doc->save(__DIR__ . '/output/10-barcodes.pdf');

يحلّ write1DBarcode() وwrite2DBarcode() المُرمِّز عبر السجل. ونادرًا ما تتعامل شِفرة تطبيقك مع العقود مباشرةً. سمِّ الترميز، فيوفِّر السجل المُرمِّز.

examples/contracts/barcode-production.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\Barcode2DEncoderInterface;
use NextPDF\Contracts\Gs1DataParserInterface;
use NextPDF\Exception\BarcodeException;
use Psr\Log\LoggerInterface;
final readonly class Gs1LabelService
{
public function __construct(
private Gs1DataParserInterface $parser,
private Barcode2DEncoderInterface $dataMatrix,
private LoggerInterface $logger,
) {}
/**
* Parse a GS1 element string and encode it as a Data Matrix.
*
* @param string $elementString A GS1 element string with Application Identifiers.
*/
public function encodeLabel(string $elementString): \NextPDF\Barcode\Barcode2DData
{
try {
$parsed = $this->parser->parse($elementString);
$payload = $this->parser->encodeForDataMatrix($parsed);
return $this->dataMatrix->encode($payload, ['errorCorrection' => 'high']);
} catch (BarcodeException $e) {
$this->logger->error('GS1 label encoding failed', [
'error' => $e->getMessage(),
]);
throw $e;
}
}
}

تعتمد الخدمة على عقدَي المحلِّل والمُرمِّز. تُسجِّل كتلة الالتقاط BarcodeException المُحدَّد وتُعيد رميه؛ ولا تلتقط أبدًا \Exception مجردًا.

  • المُرمِّز المُسجَّل مُشترَك. تُفسِد الحالةُ الخاصة بكل استدعاء في المُرمِّز عملياتِ العرض المتزامنة. أبقِ المُرمِّزات عديمة الحالة خارج إعدادات المُنشئ.
  • قد يُعيد BarcodeEncoderInterface::encode() بيانات ملوّنة أو أحادية اللون. يجب على الشِفرة التي تستهلكها أن تعالج كلاًّ من Barcode2DData وBarcodeColorData، لا أن تفترض أنها أحادية اللون.
  • لا يتحقّق العقد من مصفوفة $options ثنائية البُعد. تتجاهل معظم المُرمِّزات المفاتيح غير المعروفة بصمت. تحقّق من اسم المفتاح بالرجوع إلى توثيق المُرمِّز نفسه.
  • تحليل ⁨GS1⁩ صارم في القواعد النحوية. تُثير سلسلة عناصر تتضمن مُعرِّف تطبيق غير معروف BarcodeException بدلاً من إنتاج تحليل جزئي. تحقّق من المُدخَل مسبقًا.
  • العقود أحادية البُعد وثنائية البُعد غير قابلة للتبديل. تمرير حمولة ⁨QR⁩ إلى مُرمِّز أحادي البُعد يُنتج رمزًا غير صالح. يوجِّه السجل وفق نوع الترميز، لذلك فضِّل السجل على استدعاء عقد مباشر.

تتناسب تكلفة الترميز مع طول الحمولة وحجم المصفوفة الهدف، لا مع العقد الذي تستدعيه. تُرمَّز حمولة ⁨Code 128⁩ قصيرة في أجزاء من المليون من الثانية. أمّا رمز ⁨QR⁩ الكثيف مع تصحيح أخطاء عالٍ فهو أثقل حالة ثنائية البُعد. ومع ذلك يبقى ضمن performance_budget البالغ 1500 ⁨ms⁩ على الجدار و64 ⁨MB⁩ كذروة لصفحة المثال متعددة الرموز بهامش واسع. تُحسَب المصفوفة مرةً واحدة وتُرسَم بوصفها مُشغِّلات ⁨PDF.⁩ قابلية الاستنساخ bitwise لأن الحمولة والخيارات نفسها تُنتج دائمًا مصفوفة الوحدات نفسها. بحث السجل يعمل بزمن ⁨O⁩(1). وخوارزمية الترميز هي التي تؤدي العمل الفعلي.

كثيرًا ما تكون حمولات الرمز الشريطي متأثّرة بالمهاجم، مثل محدِّد موقع موارد مُوحَّد (⁨URL⁩) مُستخرَج، أو رقم تسلسلي، أو رمز تتبُّع. تُرمِّز العقود البايتات؛ ولا تُفسِّرها. يظل رمز ⁨QR⁩ الذي يُرمِّز عنوان ⁨URL⁩ معاديًا رمز ⁨QR⁩ صالحًا، لذلك تقع مسؤولية الثقة في الحمولة على المستهلك لا على المُرمِّز. قيِّد طول الحمولة قبل الترميز لضبط حجم المصفوفة وتجنُّب حجب الخدمة عبر رمز مفرط الحجم. يرفض محلِّل ⁨GS1⁩ مُعرِّفات التطبيق المُشوَّهة، ما يُزيل سطح حقن واحدًا. ولا يتحقّق من المحتوى الدلالي للحقول الصالحة. عامِل بيانات الرمز الشريطي المفكوكة بوصفها مُدخَلاً غير موثوق كلما عادت إلى التطبيق.

الادّعاءالمعيارالمرجع
تتبع رموز ⁨QR⁩ مواصفة ترميز مصفوفة رمز ⁨QR.⁩⁨ISO/IEC 18004⁩ترميز رمز ⁨QR⁩
تتبع رموز ⁨Data Matrix⁩ مواصفة ترميز ⁨Data Matrix.⁩⁨ISO/IEC 16022⁩ترميز ⁨Data Matrix⁩
تتبع رموز ⁨Code 128⁩ مواصفة ترميز ⁨Code 128⁩ الخطي.⁨ISO/IEC 15417⁩ترميز ⁨Code 128⁩
تُحلَّل سلاسل عناصر ⁨GS1⁩ وفق قواعد مُعرِّف تطبيق ⁨GS1.⁩المواصفات العامة لـ ⁨GS1⁩مُعرِّفات التطبيق

يُشار إلى هذه المعايير بالرقم والبند. وهي غير موجودة في مجموعة الاستشهادات القابلة للتحقّق، لذلك لا يُسجَّل أيُّ reference_id. يُعيد المحرك صياغة المتطلَّب ويستشهد بالمصدر. راجِع المعايير المنشورة للحصول على قواعد الترميز المُعتمَدة.

يُعرِّف ⁨Core⁩ عقود المُرمِّزات ويُثبِّتها، ويشحن الترميزات الشائعة. تُسجِّل إصدارات ⁨Pro⁩ و⁨Enterprise⁩ مجموعة مُرمِّزات موسّعة لترميزات رمز شريطي إضافية مقابل BarcodeEncoderInterface نفسه، بحيث يحصل أي نشر تجاري على تغطية إضافية دون تغيير في واجهة برمجة التطبيقات (⁨API⁩). يحلّ ⁨Core⁩ المُرمِّزات المُسجَّلة عبر BarcodeEncoderRegistry. سطح العقد مُطابِق عبر جميع الإصدارات.