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

السمات في PHP: use وعدة سمات وinsteadof

السمة في PHP كتلة قابلة لإعادة الاستخدام من التوابع والخصائص تنسخها إلى صنف بـ use TraitName;. تعلّم استخدام عدة سمات، وحل تعارض الأسماء بـ insteadof وas، والأعضاء المجردة والساكنة في السمات، وأي تابع يفوز، والسمة مقابل الواجهة مقابل الصنف المجرد.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

السمة في PHP كتلة قابلة لإعادة الاستخدام من التوابع والخصائص. تصرّح بها بـ trait Name { ... } وتجلبها إلى أي صنف بـ use Name; داخل جسم الصنف. تنسخ PHP أعضاء السمة إلى الصنف، فتعمل تمامًا كأنك كتبتها هناك.

ليس لـ User وRobot أب مشترك، ومع ذلك صار لكليهما hello(). وُجدت السمات لهذه الحالة: أصناف PHP لا ترث إلا صنفًا واحدًا، والسمة تشارك الشيفرة أفقيًا، بين أصناف غير مترابطة.

السمات مع الخصائص

تستطيع السمة جلب خصائص مع توابعها. وتستخدم التوابع $this مثل أي تابع في الصنف، لأنها بعد نسخ السمة تصبح توابع الصنف:

لا يجوز للصنف التصريح بخاصية بالاسم نفسه لخاصية في السمة ما لم يتطابق التصريحان (الرؤية والنوع والقيمة الافتراضية نفسها)؛ وإلا فهو خطأ فادح.

استخدام عدة سمات

اذكر عدة سمات في جملة use واحدة، مفصولة بفواصل، أو اكتب عدة أسطر use. ويحصل الصنف على أعضائها كلها:

حل التعارضات بـ insteadof وas

عندما تعرّف سمتان تابعًا بالاسم نفسه، ترفض PHP التخمين وتتوقف بخطأ فادح. داخل كتلة use، تختار insteadof الفائز، وتُبقي as التابع الخاسر باسم آخر:

مع use EnglishGreeting, FrenchGreeting; عادية دون كتلة، يتوقف السكربت قبل طباعة أي شيء:

PHP Fatal error:  Trait method FrenchGreeting::greet has not been applied as Host::greet, because of collision with EnglishGreeting::greet in /home/index.php on line 12

تستطيع as أيضًا تغيير الرؤية. تجعل use Loggable { log as protected; } التابع log() من السمة محميًا في هذا الصنف فقط، وتضيف use Loggable { log as private writeLog; } اسمًا بديلًا خاصًا.

الأعضاء المجردة والساكنة في السمة

تستطيع السمة أن تطلب شيئًا من الصنف الذي يستخدمها بالتصريح بتابع مجرد. ويمكن أن تكون لها أيضًا توابع ساكنة وخصائص ساكنة. وكل صنف يستخدم السمة يحصل على نسخته الخاصة من الخاصية الساكنة:

يعدّ Car وBike كلٌّ على حدة، لأن الخاصية الساكنة تُنسخ إلى كل صنف. وهذا يختلف عن خاصية ساكنة مصرّح بها في صنف أب مشترك، يتشاركها كل الأبناء؛ وتعرض صفحة static تلك الحالة.

أي تابع يفوز: الصنف أم السمة أم الأب

إذا وُجد اسم التابع نفسه في الصنف ذاته، وفي سمة يستخدمها، وفي صنفه الأب، تختار PHP بهذا الترتيب: تابع الصنف نفسه، ثم تابع السمة، ثم تابع الأب. وداخل السمة، تظل parent:: تصل إلى نسخة الأب:

السمة ليست نوعًا

لا تطابق instanceof سمة أبدًا، والمعامل الذي نوعه اسم سمة يرفض كل كائن بـ TypeError. لتسأل «هل لهذا الصنف هذا السلوك»، اقرن السمة بواجهة، أو افحص الصنف بـ class_uses():

النمط أعلاه هو المعتاد: الواجهة Exportable هي ما تلمّح به الدوال وما تفحصه instanceof، والسمة ExportsProperties تنفيذ جاهز تستطيع الأصناف استخدامه أو استبداله. السمة وحدها شيفرة مشتركة بلا عقد؛ وعندما تلاحظ أنك تفحص class_uses() في منطق العمل، فالسمة كانت تحتاج إلى واجهة بجانبها. وللشيفرة المشتركة بين عائلة من الأصناف المترابطة، قد يكون الصنف المجرد الخيار الأبسط.

الأسئلة الشائعة

ما هي السمة في PHP؟

السمة مجموعة مسماة من التوابع (والخصائص) يُصرَّح بها بـ trait Name { } ويجلبها الصنف بـ use Name;. تنسخ PHP أعضاء السمة إلى الصنف، فتتصرف كأنك كتبتها هناك. وهي طريقة لمشاركة الشيفرة بين أصناف ليس لها أب مشترك.

هل يستطيع صنف PHP استخدام عدة سمات؟

نعم: use Timestamps, SoftDeletes; أو عدة أسطر use. إذا عرّفت سمتان تابعًا بالاسم نفسه، يجب أن تختار واحدًا بـ insteadof، مثل use A, B { A::hello insteadof B; }، ويمكنك الإبقاء على الآخر باسم جديد بـ B::hello as helloB;.

ما الفرق بين السمة والواجهة في PHP؟

الواجهة نوع بلا شيفرة: تقول أي التوابع يجب أن يملكها الصنف، وتعمل instanceof معها. والسمة شيفرة بلا نوع: تلصق أجسام التوابع في صنف، لكن $obj instanceof SomeTrait خاطئة دائمًا. وكثيرًا ما يجتمعان: واجهة للنوع، وسمة بتنفيذ افتراضي.

هل يمكن أن يكون للسمة باني أو توابع مجردة؟

نعم لكليهما. تستطيع السمة التصريح بـ abstract public function name(): string; لتلزم الصنف المستخدم بتوفير ذلك التابع، وتستطيع تعريف __construct، مع أن الباني في سمة يتعارض بسهولة مع باني الصنف نفسه ونادرًا ما يكون فكرة جيدة.

أي تابع يفوز إذا عرّف الصنف والسمة التابع نفسه؟

يفوز تابع الصنف نفسه على تابع السمة، ويفوز تابع السمة على تابع موروث من الصنف الأب. فالترتيب: الصنف، ثم السمة، ثم الأب.

رسم توضيحي للغات البرمجة في Coddy

تعلّم البرمجة مع Coddy

ابدأ الآن