انتقل إلى محتوى الدرس
الدرس 75
دورة PHP

التحميل التلقائي للأصناف PSR-4 وإدارة الحزم عبر Composer في PHPPHP Composer and PSR-4 Class Autoloading

تخلص من استدعاءات require اليدوية عبر إتقان spl_autoload_register ومعيار PSR-4 وإدارة الحزم بأداة Composer.
أقسام الدرس
6
الأمثلة
6
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

في التطبيقات الكبيرة التي تضم مئات الأصناف، تصبح كتابة عشرات أوامر require_once يدوياً في بداية كل ملف بطيئة وهشة ومستحيلة الصيانة.

  • تحميل 200 ملف صنف مسبقاً بينما لا يستخدم الطلب الحالي سوى 6 منها يهدر الذاكرة ووقت المعالجة.
  • نقل ملف أو تغيير اسم مجلد يكسر المسارات النسبية المكتوبة يدوياً في عشرات الملفات.
  • يحل التحميل التلقائي للأصناف (Autoloading) هاتين المشكلتين عبر تحميل ملف الصنف عند الطلب فقط في اللحظة التي يُشار فيها إلى الصنف لأول مرة.

تمرير false كمعامل ثانٍ للدالة class_exists($name, false) يفحص ما إذا كان الصنف محملاً في الذاكرة حالياً دون استدعاء المحمل التلقائي.

مخطط توضيحي: محاكي التحميل التلقائي للأصناف PSR-4 وإدارة الحزم عبر Composer في PHP
PHP
<?php
// Instead of 50 manual require_once lines at the top of every script,
// lazy autoloading resolves only the classes actually used:
$loadedBefore = class_exists("CartCalculator", false);

class CartCalculator {
    public function subtotal(int $qty, int $price): int { return $qty * $price; }
}
$calc = new CartCalculator();
echo "Before={$loadedBefore} | Total=" . $calc->subtotal(3, 120) . "\n";

تقوم الدالة المدمجة spl_autoload_register() بتسجيل دالة رد نداء يستدعيها محرك PHP تلقائياً ويمرر إليها الاسم الكامل للصنف (مع مجال الأسماء) فور طلب صنف غير محمل.

  • تستقبل دالة التحميل التلقائي معاملاً نصياً واحداً $class يمثل الاسم الكامل للصنف (مثل "App\Services\TaxService" بدون شرطة مائلة بادئة).
  • داخل الدالة، يتم استبدال فواصل مجال الأسماء \ بفواصل المجلدات / وإضافة الامتداد .php ثم تضمين الملف إذا كان موجوداً.
  • يمكن تسجيل عدة محملات تلقائية في طابور منظم؛ فإذا لم يجد الأول الملف ينتقل PHP تلقائياً للمحمل التالي.

عند طلب الصنف App\Billing\InvoiceGateway، يستدعي PHP تلقائياً الدالة المسجلة في spl_autoload_register() ويحول اسم الصنف إلى مسار ملف.

PHP
<?php
$resolvedPath = "";
spl_autoload_register(function (string $class) use (&$resolvedPath): void {
    $relative = str_replace("\\", "/", $class) . ".php";
    $resolvedPath = __DIR__ . "/src/" . $relative;
});

class_exists("App\\Billing\\InvoiceGateway", true);
echo basename($resolvedPath) . " -> " . str_contains($resolvedPath, "src/App/Billing/InvoiceGateway.php") . "\n";

معيار PSR-4 هو القياس الرسمي لمنظمة PHP-FIG الذي يربط بادئة مجال الأسماء الرئيسي (مثل App\) بمجلد مصدري أساسي (مثل src/) بحيث يطابق كل مجال فرعي مجلداً فرعياً.

  • وفق قاعدة الربط "App\" => "src/"، يجب أن يوجد الصنف App\Http\HomeController في المسار src/Http/HomeController.php.
  • يجب أن تتطابق حالة الأحرف (الكبيرة والصغيرة) لأسماء المجلدات والملفات مع اسم المجال والصنف تماماً لتجنب فشل التحميل على خوادم Linux الحساسة لحالة الأحرف.
  • يحتوي كل ملف PHP وفق PSR-4 على صنف واحد أو واجهة أو سمة أو تعداد واحد يطابق اسم الملف.

تزيل الدالة psr4Path() بادئة مجال الأسماء المسجلة (App\) وتستبدلها بالمجلد src/ ثم تحول الفواصل وتضيف .php.

PHP
<?php
function psr4Path(string $prefix, string $baseDir, string $fqcn): string {
    if (!str_starts_with($fqcn, $prefix)) return "";
    $relativeClass = substr($fqcn, strlen($prefix));
    return $baseDir . str_replace("\\", "/", $relativeClass) . ".php";
}

echo psr4Path("App\\", "src/", "App\\Catalog\\ProductRepository") . "\n";
echo psr4Path("Tests\\", "tests/", "Tests\\Unit\\CartTest") . "\n";

أداة Composer هي مدير الحزم ومولد التحميل التلقائي القياسي في PHP؛ حيث تضبط إعدادات مشروعك في ملف composer.json وتضّمن ملفاً واحداً فقط هو vendor/autoload.php.

  • حدد الحزم المطلوبة ضمن قسم "require"، وخريطة PSR-4 الخاصة بمشروعك ضمن "autoload": { "psr-4": { "App\\": "src/" } }.
  • انتبه إلى ضرورة مضاعفة الشرطة المائلة العكسية داخل نصوص JSON لتكتب هكذا: "App\\": "src/".
  • ضمّن الملف __DIR__ . "/vendor/autoload.php" مرة واحدة فقط في نقطة دخول التطبيق (مثل public/index.php) لتفعيل التحميل التلقائي لأصنافك وجميع مكتبات vendor.

يحدد ملف composer.json إصدار PHP والحزم المطلوبة، ويربط مجال الأسماء App\ بالمجلد المصدري src/.

مخطط تدفق التنفيذ العملي لقسم إعداد ملف composer.json ومجلد vendor في لغة PHP
PHP
<?php
$composerJson = <<<'JSON'
{
    "name": "acme/storefront",
    "require": { "php": "^8.4", "monolog/monolog": "^3.7" },
    "autoload": { "psr-4": { "App\\": "src/" } }
}
JSON;
$config = json_decode($composerJson, true);
echo "Package: " . $config["name"] . " | App -> " . $config["autoload"]["psr-4"]["App\\"] . "\n";

تتبع حزم Composer نظام الإصدارات الدلالي (MAJOR.MINOR.PATCH مثل 3.7.2)، ويحفظ الملف composer.lock الإصدارات المثبتة بالضبط لضمان تطابق بيئات الفريق وخوادم الإنتاج.

  • يسمح رمز القبعة ^3.7 بتحديثات الميزات الفرعية والإصلاحات الأمنية (>=3.7.0 <4.0.0) مع منع التحديث لإصدار رئيسي يكسر التوافق.
  • احفظ دائماً ملفي composer.json وcomposer.lock في مستودع Git، واستبعد مجلد /vendor/ عبر إضافته إلى .gitignore.
  • عند النشر على خادم الإنتاج، شغّل دائماً composer install --no-dev --optimize-autoloader لقراءة الإصدارات الدقيقة من composer.lock.

يسمح القيد ^3.7 بالإصدار 3.9.4 المتوافق، بينما يمنع الترقية التلقائية إلى الإصدار الرئيسي 4.0.0.

PHP
<?php
namespace App\Release;

class SemVerCheck {
    public static function allowsCaret37(string $ver): bool {
        return version_compare($ver, "3.7.0", ">=") && version_compare($ver, "4.0.0", "<");
    }
}
echo "3.9.4 allowed: " . (SemVerCheck::allowsCaret37("3.9.4") ? "Yes" : "No") . "\n";
echo "4.0.0 allowed: " . (SemVerCheck::allowsCaret37("4.0.0") ? "Yes" : "No") . "\n";

أتقن أوامر Composer الأساسية في الطرفية لتثبيت الحزم، وفصل أدوات الاختبار والتطوير عن بيئة الإنتاج، وتسريع تحميل الأصناف.

  • استخدم composer require vendor/package لحزم الإنتاج، وcomposer require --dev phpunit/phpunit لأدوات الفحص والاختبار الخاصة بالتطوير.
  • لا تشغل أبداً composer update مباشرة على خادم الإنتاج؛ بل شغله محلياً واختبر التحديثات ثم احفظ composer.lock ونفذ composer install على الخادم.
  • استخدم composer dump-autoload -o لتوليد خريطة أصناف محسنة تسرّع الوصول للملفات في الإنتاج.

يمثل الصنف داخل مجال الأسماء App\Support حالة نشر معتمدة على ملف القفل وخريطة الأصناف المحسنة.

أمر Composerالوظيفة الأساسيةمتى يُستخدم
composer initCreates a new composer.json interactivelyStarting a new PHP project
composer require pkg/nameInstalls package and adds it to composer.jsonAdding a new library
composer installInstalls exact versions pinned in composer.lockCloning repo / production deploy
composer updateUpgrades packages within composer.json constraints & updates lockfileLocal maintenance & upgrades
composer dump-autoload -oRegenerates PSR-4 and optimized classmap in vendor/After changing autoload rules or on deploy

PHP
<?php
namespace App\Support;

final readonly class ComposerManifest {
    public function __construct(public string $lockHash, public bool $prodOptimized) {}
    public function summary(): string {
        return "lock={$this->lockHash} | classmap=" . ($this->prodOptimized ? "optimized" : "dynamic");
    }
}
$m = new ComposerManifest("sha256:8f41c", true);
echo $m->summary() . "\n";
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

أتقن أوامر Composer الأساسية في الطرفية لتثبيت الحزم، وفصل أدوات الاختبار والتطوير عن بيئة الإنتاج، وتسريع تحميل الأصناف. استخدم composer require vendor/package لحزم الإنتاج، وcomposer require --dev phpunit/phpunit لأدوات الفحص والاختبار الخاصة بالتطوير. لا تشغل أبداً composer update مباشرة على خادم الإنتاج؛ بل شغله محلياً واختبر التحديثات ثم احفظ composer.lock ونفذ composer install على الخادم. استخدم composer dump-autoload -o لتوليد خريطة أصناف محسنة تسرّع الوصول للملفات في الإنتاج.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Composer & PSR-4 Composer و PSR-4
تخلص من استدعاءات require اليدوية عبر إتقان spl_autoload_register ومعيار PSR-4 وإدارة الحزم بأداة Composer.
للمراجعة
02 Why Manual require Fails at Scale لماذا يفشل التضمين اليدوي بالمشاريع الكبيرة
المفهوم الأساسي لقسم لماذا يفشل التضمين اليدوي بالمشاريع الكبيرة في لغة PHP الحديثة.
للمراجعة
03 Custom Autoloader with spl_autoload_register التحميل التلقائي بدالة spl_autoload_register
الصياغة البرمجية والتطبيق العملي المباشر لقسم التحميل التلقائي بدالة spl_autoload_register.
للمراجعة
04 PSR-4 Directory to Namespace Mapping ربط المجلدات بمجالات الأسماء وفق PSR-4
قواعد التحقق وأفضل الممارسات القياسية الخاصة بقسم ربط المجلدات بمجالات الأسماء وفق PSR-4.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 PHP PHP
PHP: Hypertext Preprocessor
لغة البرمجة النصية على جانب الخادم لبناء تطبيقات الويب الديناميكية وواجهات البرمجة.
للمراجعة
02 CLI CLI
Command-Line Interface
واجهة سطر الأوامر التي تتيح تشغيل ملفات PHP مباشرة عبر الطرفية.
للمراجعة
03 FPM FPM
FastCGI Process Manager
مدير عمليات FastCGI عالي الأداء لمعالجة طلبات خادم الويب في PHP.
للمراجعة
04 HTML HTML
HyperText Markup Language
لغة الترميز القياسية التي يولدها محرك PHP ويرسلها إلى متصفح العميل بعد التنفيذ.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. أنشئ ملف PHP محلياً ونفّذ المثال البرمجي المشروح في قسم لماذا يفشل التضمين اليدوي بالمشاريع الكبيرة للتحقق من المخرجات.

  2. بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم التحميل التلقائي بدالة spl_autoload_register وقارن مخرجات التنفيذ.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

8أسئلة 1أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي8 أسئلة تنتظرك
01

ما الدالة المدمجة في PHP التي تسجل دالة رد نداء لتحميل ملفات الأصناف تلقائياً عند طلب صنف غير محمل؟

تسجل spl_autoload_register() دوال التحميل التلقائي في طابور محرك PHP.

02

وفق قاعدة PSR-4 التي تربط "App\\": "src/"، ما مسار الملف الذي يجب أن يحتوي على الصنف App\Services\Payment\StripeClient؟

تُستبدل البادئة App\ بالمجلد src/، وتتحول المجالات الفرعية واسم الصنف إلى مجلدات وملف بامتداد .php.

03

ما الملف الوحيد الذي يولده Composer وتقوم بتضمينه في نقطة دخول التطبيق (مثل public/index.php) لتفعيل التحميل التلقائي؟

تضمين vendor/autoload.php يفعل محمل Composer التلقائي لجميع أصناف المشروع والحزم المثبتة.

04

ما الفرق بين تشغيل الأمر composer install والأمر composer update في مشروع يحتوي مسبقاً على ملف composer.lock؟

يُستخدم composer install في الإنتاج لضمان تثبيت نفس الإصدارات المختبرة بالضبط.

05

في ملف composer.json، ما الإصدارات التي يسمح قيد الإصدار الدلالي "^3.2" لأداة Composer بتثبيتها؟

يسمح رمز القبعة (^) بالتحديثات المتوافقة حتى ما قبل الإصدار الرئيسي التالي.

06

ما الملفات والمجلدات الخاصة بـ Composer التي يجب حفظها في Git مقابل استبعادها في .gitignore لتطبيق PHP قياسي؟

وجود composer.json وcomposer.lock يكفي لإعادة بناء مجلد vendor/ بدقة على أي جهاز.

07

ما أمر Composer الذي يعيد توليد ملفات التحميل التلقائي vendor/autoload.php بعد تعديل إعدادات PSR-4 في composer.json دون تحميل حزم من الإنترنت؟

يعيد الأمر composer dump-autoload بناء خرائط التحميل التلقائي محلياً.

08

لماذا عمل الصنف App\Billing\Invoice الموجود في المسار src/billing/Invoice.php على جهاز المطور (Windows) ولكنه فشل بخطأ "Class not found" على خادم الإنتاج (Linux)؟

يشترط معيار PSR-4 التطابق التام في حالة الأحرف بين مجال الأسماء وأسماء المجلدات والملفات.