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

المرحلة 00 · الأساس — قبل ما تبدأدرس 2 من 216 دقيقة قراءةآخر تحديث:

Lesson 02 / 21

PHP & Composerمراجعة سريعة.

قبل ما تدخل Magento، فيه أساسيات لازم تكون مرتاح معاها. مش كل PHP — بس اللي هتشوفه فعلًا في كود Magento: مميزات PHP 8 الأساسية، والـ Composer وautoloading والـ namespaces.

● Prerequisites PHP 8+ Composer PSR-4

كود Magento 2 والـ extensions الحديثة بيستخدموا مميزات PHP 8 زي type declarations و constructor promotion و readonly properties، وكل class عايش جوّه namespace. الـ Composer بيدير الـ packages والاعتماديات، وبيعمل autoloading بمعيار PSR-4 اللي بيربط الـ namespace بمسار الملف، فمش محتاج require يدوي. الأساس ده بيخلّي قراية كود Magento أسهل بكتير.

// ليه المراجعة دي Magento مكتوب بـ PHP حديثة وبيعتمد على Composer بالكامل. لو المفاهيم دي مش واضحة، كود Magento هيبان غامض. الهدف مش نعلّمك PHP من الصفر — الهدف نراجع اللي هتحتاجه بالظبط عشان تقرا وتكتب كود Magento بثقة.
◆ Part 1 — PHP الحديثة
01

Type Declarations

تحديد أنواع البيانات — بتشوفها في كل كلاس في Magento.

إيه هي

الـ type declarations بتحدد نوع الـ parameters والـ return والـ properties. بتخلّي الكود أوضح وبتمسك الأخطاء بدري.

typed codephp
class Product
{
    // typed property
    private string $name;
    private float $price = 0.0;

    // typed params + return type
    public function setPrice(float $price): void
    {
        $this->price = $price;
    }

    public function getName(): string
    {
        return $this->name;
    }
}
nullable و union types

?string معناها string أو null. وint|string معناها الاتنين مقبولين (union type من PHP 8).

في Magento كل الـ interfaces والـ classes في Magento الحديثة بتستخدم type declarations. لما تشوف : ProductInterface بعد method، دي return type بتقولك إيه اللي بيرجع.
• • •
02

Constructor Promotion

اختصار PHP 8 اللي Magento بيستخدمه بكثافة في الـ DI.

المشكلة القديمة

قبل PHP 8، عشان تحقن dependency كنت بتكتبها 3 مرات: property، parameter، وتعيين. تكرار ممل.

old way — verbosephp
class MyService
{
    private ProductRepository $repo;

    public function __construct(
        ProductRepository $repo
    ) {
        $this->repo = $repo; // assignment
    }
}
PHP 8 — promotedphp
class MyService
{
    // property + param + assignment in one!
    public function __construct(
        private readonly ProductRepository $repo
    ) {}
}
i
الـ readonly (من PHP 8.1) معناها القيمة تتحدد مرة واحدة في الـ constructor وبعدها متتغيّرش — مثالية للـ dependencies اللي مالهاش تتبدّل.
في Magento ده أهم feature تعرفه، لأن كل constructor في Magento تقريبًا بيحقن dependencies. الكود الحديث بيستخدم الـ promotion، فلازم تكون فاهمه عشان تقرا الـ DI.
• • •
03

مميزات PHP 8 مفيدة

حاجات صغيرة بتشوفها كتير في الكود الحديث.

Nullsafe Operator

الـ ?-> بيتجنّب error لو الـ object null. بدل ما تشيك يدوي.

nullsafephp
// old: needs null check
$country = null;
if ($order) {
    $country = $order->getAddress()->getCountry();
}

// PHP 8: nullsafe chain
$country = $order?->getAddress()?->getCountry();
Match Expression

زي switch بس أنضف، بيرجع قيمة، وبيقارن بدقة (strict).

matchphp
$label = match($status) {
    1 => 'Pending',
    2 => 'Complete',
    default => 'Unknown',
};
Enums (PHP 8.1)

نوع بيحدد مجموعة قيم ثابتة ممكنة — بدل الـ constants المبعثرة.

enumphp
enum Status: string
{
    case Pending = 'pending';
    case Complete = 'complete';
}
i
مش لازم تحفظهم كلهم دلوقتي. المهم تتعرّف عليهم عشان لما تشوفهم في كود Magento متتلغبطش. هتألفهم مع الوقت.
• • •
04

Namespaces

أساس تنظيم الكود في Magento — وبيرتبط مباشرة بالـ autoloading.

إيه هو

الـ namespace زي "عنوان" للكلاس، بيمنع تضارب الأسماء. ممكن يكون عندك Product في مكانين، والـ namespace بيميّزهم.

Vendor/Module/Model/Product.phpphp
// declares the namespace
namespace Vendor\Module\Model;

// import a class from another namespace
use Magento\Catalog\Api\ProductRepositoryInterface;

class Product
{
    public function __construct(
        private readonly ProductRepositoryInterface $repo
    ) {}
}
تشبيه الـ namespace زي العنوان الكامل للبيت. ممكن يكون فيه "أحمد" كتير في المدينة، بس "أحمد، شارع كذا، عمارة كذا" واحد بس. الـ use زي إنك تحفظ العنوان في جهات الاتصال عشان تناديه بالاسم بس.
في Magento الـ namespace بيطابق مسار الملف بالظبط. Vendor\Module\Model\Product بيكون في Vendor/Module/Model/Product.php. ده مش صدفة — ده اللي بيخلّي الـ autoloading يشتغل (الجزء الجاي).
• • •
◆ Part 2 — Composer
05

Composer — الأساس

مدير الحزم اللي Magento كله مبني عليه.

إيه هو

الـ Composer هو مدير الحزم (dependency manager) بتاع PHP. بيدير المكتبات اللي مشروعك محتاجها، بيحمّلها، وبيظبّط الـ autoloading.

composer.json

الملف اللي بيعرّف مشروعك: اسمه، اعتمادياته، وإعدادات الـ autoload. Magento نفسه والـ modules بتاعتك كلها بتتعرّف هنا.

composer.jsonjson
{
    "name": "vendor/module-custom",
    "require": {
        "php": "~8.1.0",
        "magento/framework": "*"
    },
    "autoload": {
        "psr-4": {
            "Vendor\\Module\\": ""
        }
    }
}
أوامر تعرفها
  • composer install — يحمّل الاعتماديات حسب الـ lock file.
  • composer require vendor/pkg — يضيف حزمة جديدة.
  • composer dump-autoload — يعيد بناء خريطة الـ autoload.
  • composer update — يحدّث الاعتماديات (بحذر في production).
i
الـ composer.lock بيثبّت الإصدارات الدقيقة المثبّتة، عشان كل بيئة تركّب نفس النسخ بالظبط. متعدّلوش يدوي.
• • •
06

Autoloading & PSR-4

السحر اللي بيخلّي الكلاسات تتحمّل تلقائيًا — قلب Magento.

المشكلة اللي بيحلّها

من غير autoloading، كنت هتكتب require 'path/to/file.php' لكل كلاس تستخدمه. مع آلاف الكلاسات في Magento، ده مستحيل.

الحل: PSR-4

الـ PSR-4 معيار بيربط الـ namespace بمسار الملف. لما تستخدم كلاس، الـ autoloader بيترجم الـ namespace لمسار وبيحمّل الملف تلقائيًا.

namespace → file pathtext
# PSR-4 mapping:
# "Vendor\Module\" => "app/code/Vendor/Module/"

# so this class...
Vendor\Module\Model\Product

# ...auto-loads from this file:
app/code/Vendor/Module/Model/Product.php
تشبيه الـ autoloader زي موظف مكتبة ذكي. بدل ما تجيب الكتاب بنفسك، بتقوله اسم الكتاب (namespace)، وهو عارف بالظبط على أي رف يلاقيه (file path) وبيجيبهولك فورًا.
في Magento ده السبب إن الـ namespace لازم يطابق مسار الملف بدقة. لو حطّيت الكلاس في مكان غلط أو الـ namespace مش مظبوط، Magento مش هيلاقيه. أغلب أخطاء "class not found" سببها ده.
!
لو ضفت كلاس جديد ومش لاقيه Magento، جرّب composer dump-autoload — أحيانًا خريطة الـ autoload محتاجة تتحدّث.

PHP & Composer ✓

دلوقتي عندك الأساس اللي محتاجه قبل Magento: type declarations، constructor promotion، الـ namespaces، والـ Composer/PSR-4. دي مش كل PHP — بس دي اللي هتشوفها وتستخدمها في Magento يوميًا.

الخلاصة اللي تربط كله: الـ namespace بيطابق مسار الملف، والـ PSR-4 بيحمّله تلقائيًا، والـ Composer بيدير كل ده. بمجرد ما تفهم الربط ده، بنية Magento كلها هتبقى منطقية.

// prerequisites · php 8 & composer · ready for magento

خلّصت الدرس؟علّمه عشان تتابع تقدّمك في الكورس.

كاتب الدرس

Abdulrahman Masoud

عندك سؤال على الدرس أو محتاج مساعدة في مشروع Magento؟ كلّمني.

أسئلة شائعة

يعني إيه Constructor Promotion في PHP 8؟

قبل PHP 8 كنت بتكتب الـ dependency 3 مرات: property، وparameter، وتعيين جوّه الـ constructor. مع الـ promotion بتكتبها مرة واحدة زي private readonly ProductRepository $repo جوّه أقواس الـ constructor، وPHP بيعمل الـ property والتعيين لوحده. ده مهم جدًا عشان تقرا كود الـ DI في Magento.

إيه فايدة readonly في PHP 8.1؟

الـ readonly معناها إن قيمة الـ property بتتحدد مرة واحدة في الـ constructor وبعدها متتغيّرش. ده بيخلّيها مثالية للـ dependencies اللي بتتحقن ومالهاش تتبدّل طول عمر الـ object.

ما الفرق بين composer install و composer update؟

composer install بيحمّل الاعتماديات بالإصدارات الدقيقة المتثبّتة في composer.lock، فكل بيئة بتركّب نفس النسخ بالظبط. composer update بيحدّث الاعتماديات لإصدارات أحدث، فاستخدمه بحذر في production، ومتعدّلش الـ lock file يدوي.

إزاي PSR-4 autoloading بيشتغل في PHP؟

الـ PSR-4 معيار بيربط الـ namespace بمسار الملف، فلما تستخدم كلاس الـ autoloader بيترجم اسمه لمسار ويحمّل الملف تلقائيًا بدل ما تكتب require لكل كلاس. مثلًا مع mapping Vendor\Module\ على app/code/Vendor/Module/، الكلاس Vendor\Module\Model\Product بيتحمّل من app/code/Vendor/Module/Model/Product.php.

ليه بيظهر class not found في Magento 2؟

أغلب الحالات سببها إن الـ namespace مش مطابق لمسار الملف بدقة، أو إن الكلاس متحطوط في مكان غلط، فالـ autoloader مش بيلاقيه. ولو ضفت كلاس جديد ولسه مش ظاهر، جرّب composer dump-autoload عشان تعيد بناء خريطة الـ autoload.

إيه أهم مميزات PHP 8 اللي بتظهر في كود Magento؟

أهمهم الـ type declarations (ومعاها nullable زي ?string وunion types زي int|string) والـ constructor promotion مع readonly. وهتقابل كمان الـ nullsafe operator ?-> اللي بيتجنّب error لو الـ object null، والـ match اللي بيرجع قيمة وبيقارن strict، والـ enums من PHP 8.1.