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

الواجهات في PHP: implements والثوابت والأمثلة

تسرد الواجهة في PHP توابع يتعهد الصنف بامتلاكها: interface Shape { public function area(): float; }، وعلى class Circle implements Shape عندها أن تعرّف area(). تعلّم التلميح بالأنواع مع الواجهات، وتنفيذ عدة واجهات، وثوابت الواجهات، ووراثة الواجهات، والواجهات المدمجة مثل Countable، والواجهة مقابل الصنف المجرد.

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

تصرّح الواجهة في PHP بتوابع يتعهد الصنف بتوفيرها، دون أي شيفرة: interface Shape { public function area(): float; }. يجب على الصنف الذي يكتب implements Shape أن يعرّف area()، وأي دالة تلمّح بالنوع Shape ستقبل ذلك الصنف.

لا تعرف describe() ولا تهتم بأي صنف تتلقاه. فهي لا تعتمد إلا على التعهد الذي تقدمه الواجهة، لذا يعمل معها Triangle implements Shape جديد دون تغيير سطر واحد.

البرمجة على الواجهة

السبب المعتاد لكتابة واجهة هو جعل الشيفرة تعتمد على قدرة لا على صنف محدد. هنا تقبل خدمة الطلبات أي Notifier، فتستطيع الشيفرة نفسها إرسال البريد في بيئة الإنتاج وجمع الرسائل في الاختبار:

تنفيذ عدة واجهات

يرث الصنف أبًا واحدًا على الأكثر، لكنه يستطيع تنفيذ ما يحتاجه من واجهات. اذكرها بعد implements، مفصولة بفواصل، وعرّف توابعها كلها:

JsonSerializable إحدى واجهات PHP المدمجة: تنفيذها يتحكم فيما تنتجه json_encode() للكائن.

ثوابت الواجهات

تستطيع الواجهة التصريح بثوابت. يرثها كل صنف ينفّذها، ويمكنك قراءتها عبر اسم الواجهة أو اسم الصنف:

لا يمكن أن تكون للواجهات خصائص في PHP 8.3، بل توابع وثوابت فقط. ويمكن أن تكون التوابع ساكنة: تُلزم public static function fromArray(array $data): static; في الواجهة كل صنف بتعريف ذلك التابع الساكن. ولمجموعة ثابتة من القيم المترابطة، كثيرًا ما يكون التعداد أنسب من قائمة ثوابت في واجهة.

الواجهة تستطيع وراثة واجهات أخرى

تستخدم الواجهات extends أيضًا، وعلى عكس الأصناف تستطيع وراثة عدة واجهات معًا. ويجب على الصنف الذي ينفّذ الواجهة الابنة أن يعرّف توابع السلسلة كلها:

الواجهات المدمجة: Countable وIteratorAggregate وStringable

تأتي PHP بواجهات تربط الكائنات باللغة. تجعل Countable الدالة count($obj) تعمل، وتجعل IteratorAggregate الحلقة foreach تعمل، وتُنفَّذ Stringable تلقائيًا لأي صنف فيه تابع __toString():

نسيان تابع

إذا ادعى صنف أنه ينفّذ واجهة لكنه أغفل تابعًا، تتوقف PHP بخطأ فادح يسمّي التابع المفقود:

أضف تابع total() فيعمل السكربت. ويمكن لـ الصنف المجرد أن يترك توابع الواجهة دون تعريف، وهذا هو المخرج الذي تقترحه رسالة الخطأ.

الواجهة مقابل الصنف المجرد

كلاهما يعرّف توابع يجب أن يملكها الصنف، وكلاهما يمكن استخدامه تلميحًا بالنوع. والفرق في ما يمكن أن يحتويه كل منهما وفي عدد ما يستطيع الصنف استخدامه:

الواجهةالصنف المجرد
أجسام التوابعلا شيء (تواقيع فقط)توابع مجردة ومكتملة
الخصائصلانعم
البانييمكن التصريح به، ونادرًا ما يفيدنعم، مع شيفرة
رؤية التوابععامة فقطعامة ومحمية وخاصة
الثوابتنعمنعم
العدد لكل صنفأي عدد (implements A, B, C)واحد (extends Base)
الاستخدام المعتادقدرة: Exportable وCountableشيفرة مشتركة لعائلة: Model وController

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

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

ما هي الواجهة في PHP؟

قائمة من تواقيع التوابع العامة دون أجسام: interface Logger { public function log(string $msg): void; }. يجب على الصنف الذي يقول implements Logger أن يعرّف كل تابع فيها، وأي شيفرة تلمّح بالنوع Logger تقبل ذلك الصنف.

هل يستطيع صنف PHP تنفيذ عدة واجهات؟

نعم. اذكرها بعد implements، مفصولة بفواصل: class File implements Readable, Writable, Countable. ويجب أن يعرّف الصنف توابعها كلها. وهكذا تغطي PHP ما تفعله الوراثة المتعددة في لغات أخرى.

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

لا تصرّح الواجهة إلا بتوابع عامة (وثوابت)؛ ليس فيها خصائص ولا شيفرة توابع، ويستطيع الصنف تنفيذ كثير منها. أما الصنف المجرد فيمكن أن يحمل خصائص وبانيًا وتوابع مكتملة بجانب توابعه المجردة، لكن الصنف لا يرث إلا واحدًا. استخدم الواجهة لقدرة ("يمكن تصديره")، والصنف المجرد لشيفرة مشتركة في عائلة من الأصناف.

هل يمكن أن تكون للواجهة في PHP خصائص؟

ليس في PHP 8.3: قد تحتوي الواجهة تواقيع توابع وثوابت (const VERSION = 2;)، لكن لا خصائص. ولم تصل تصريحات الخصائص في الواجهات (property hooks) إلا في PHP 8.4.

كيف أتحقق من أن كائنًا ينفّذ واجهة في PHP؟

استخدم instanceof: تكون $obj instanceof Countable صحيحة عندما ينفّذ صنف الكائن الواجهة، مباشرة أو عبر صنف أب. وتعيد class_implements($obj) أسماء كل الواجهات التي ينفّذها الصنف.

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

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

ابدأ الآن