Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

مقدمة إلى السمات

جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 51 من 91.

يدعم PHP الوراثة الفردية فقط - حيث يمكن للفئة (class) أن ترث من فئة أب واحدة فقط. ولكن ماذا لو كنت بحاجة إلى مشاركة الوظائف عبر فئات متعددة غير مرتبطة؟ هنا يأتي دور الـ traits.

السمة (trait) هي آلية لإعادة استخدام الكود تتيح لك تعريف الدوال (methods) والخصائص (properties) التي يمكن إدراجها في فئات (classes) متعددة. فكر في السمات (traits) كعملية نسخ ولصق على مستوى اللغة - حيث يصبح الكود الخاص بالسمة جزءاً من الفئة التي تستخدمها.

<?php
trait Timestampable {
    private string $createdAt;
    
    public function setCreatedAt(): void {
        $this->createdAt = date('Y-m-d H:i:s');
    }
    
    public function getCreatedAt(): string {
        return $this->createdAt;
    }
}

class Article {
    use Timestampable;
    
    public function __construct(public string $title) {
        $this->setCreatedAt();
    }
}

$article = new Article("PHP Traits");
echo $article->getCreatedAt();

تستورد الكلمة المفتاحية use داخل الفئة (class) أعضاء الـ trait. الآن، أصبح لدى Article إمكانية الوصول إلى setCreatedAt() و getCreatedAt() كما لو تم تعريفهما مباشرة في الفئة.

يمكن استخدام نفس الـ trait في فئات غير مرتبطة تماماً - فئة Comment، أو فئة User، أو أي فئة أخرى تحتاج إلى وظيفة الطابع الزمني (timestamp). هذا يحل محدودية الوراثة الأحادية من خلال السماح بمشاركة الكود بشكل أفقي عبر التسلسل الهرمي للفئات الخاصة بك.

challenge icon

التحدي

سهل

لنقم ببناء نظام ترحيب بسيط يوضح كيف تسمح لك السمات (traits) بمشاركة الوظائف عبر فئات (classes) غير مرتبطة. ستقوم بإنشاء سمة توفر إمكانية الترحيب، ثم تستخدمها في فئتين مختلفتين تماماً.

ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:

  • Greetable.php — أنشئ سمة تسمى Greetable توفر وظيفة الترحيب. يجب أن تحتوي السمة على:
    • خاصية خاصة $greeting (سلسلة نصية string)
    • دالة setGreeting(string $greeting) تقوم بتخزين رسالة الترحيب
    • دالة greet() تقوم بإرجاع رسالة الترحيب
  • Person.php — أنشئ فئة Person تستخدم سمة Greetable. قم بتضمين ملف السمة واستخدم خاصية الترويج في المنشئ (constructor promotion) لتعريف خاصية عامة $name. في المنشئ، استدعِ setGreeting() لضبط الترحيب على "Hello, I'm [name]".
  • Robot.php — أنشئ فئة Robot تستخدم أيضاً سمة Greetable. قم بتضمين ملف السمة واستخدم خاصية الترويج في المنشئ لتعريف خاصية عامة $model. في المنشئ، استدعِ setGreeting() لضبط الترحيب على "Beep boop, I am model [model]".

في main.php، قم بتضمين ملفي الفئتين. ستتلقى مدخلين: اسم شخص ورقم طراز روبوت. أنشئ مثيلات (instances) من كلتا الفئتين واطبع ترحيباتهما في أسطر منفصلة.

يوضح هذا قوة السمات (traits) — حيث أن Person و Robot فئتان غير مرتبطتين تماماً ولا يوجد بينهما أب مشترك، ومع ذلك تكتسب كلتاهما نفس وظيفة الترحيب من خلال السمة. تقوم كل فئة بتخصيص كيفية استخدام هذه الوظيفة بطريقتها الخاصة.

ورقة مرجعية

الـ trait هي آلية لإعادة استخدام الكود تتيح لك مشاركة الأساليب (methods) والخصائص (properties) عبر فئات (classes) متعددة غير مرتبطة، مما يحل مشكلة قيود الوراثة الأحادية في لغة PHP.

قم بتعريف trait باستخدام الكلمة المفتاحية trait:

<?php
trait Timestampable {
    private string $createdAt;
    
    public function setCreatedAt(): void {
        $this->createdAt = date('Y-m-d H:i:s');
    }
    
    public function getCreatedAt(): string {
        return $this->createdAt;
    }
}

استخدم trait داخل فئة (class) باستخدام الكلمة المفتاحية use:

class Article {
    use Timestampable;
    
    public function __construct(public string $title) {
        $this->setCreatedAt();
    }
}

تصبح أساليب وخصائص الـ trait جزءاً من الفئة كما لو تم تعريفها مباشرة داخلها. يمكن لفئات متعددة غير مرتبطة استخدام نفس الـ trait لمشاركة الوظائف بشكل أفقي عبر التسلسل الهرمي للفئات لديك.

جرّب بنفسك

<?php

require_once 'Person.php';
require_once 'Robot.php';

// قراءة المدخلات
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));

// TODO: مع الاسم المعطى Person قم بإنشاء كائن من الفئة
// TODO: مع الطراز المعطى Robot قم بإنشاء كائن من الفئة
// TODO: Person اطبع تحية الـ
// TODO: (على سطر جديد) Robot اطبع تحية الـ

?>
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming