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

التعدادات في PHP: enum المدعوم وfrom() وtryFrom() وcases()

التعداد في PHP (8.1 وما بعدها) نوع بقائمة ثابتة من القيم: enum Status: string { case Active = 'active'; }. تعلّم التعدادات الخالصة والمدعومة، و->value و->name، والتحويل بـ from() وtryFrom()، وسرد الحالات بـ cases()، والتوابع، والثوابت، والواجهات، والتعدادات في match.

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

يعرّف التعداد في PHP (PHP 8.1 وما بعدها) نوعًا بمجموعة ثابتة من القيم الممكنة، هي حالاته: enum Status { case Active; case Banned; }. تستخدم الحالة على شكل Status::Active، والمعامل ذو النوع Status لا يقبل شيئًا آخر. ويعطي التعداد المدعوم، enum Status: string، كل حالة أيضًا قيمة يمكنك تخزينها وتحويلها مرة أخرى بـ Status::from().

قبل التعدادات، كان الشيء نفسه قائمة من الثوابت النصية، ولم يكن هناك ما يمنع خطأً إملائيًا مثل 'actve' من الوصول إلى قاعدة البيانات. ومع Status نوعًا للمعامل، لا يمكن تمرير إلا الحالات الثلاث.

التعدادات الخالصة والتعدادات المدعومة

حالات التعداد الخالص أسماء فقط. ويصرّح التعداد المدعوم بنوع بعد الاسم، int أو string، ويجب عندها أن تكون لكل حالة قيمة فريدة من ذلك النوع. لكل حالة ->name؛ ولا تملك ->value إلا الحالات المدعومة.

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

تحويل قيمة بـ from() وtryFrom()

تحصل التعدادات المدعومة على تابعين ساكنين لتحويل قيمة مخزنة مرة أخرى إلى حالة. ترمي from() الخطأ ValueError لقيمة غير معروفة؛ وتعيد tryFrom() القيمة null، وهي تتلاءم جيدًا مع ?? لقيمة افتراضية:

استخدم tryFrom() مع كل ما أرسله إليك مستخدم، وfrom() مع القيم التي كتبتها شيفرتك، حيث تعني القيمة غير المعروفة خطأً تريد أن تعرف به. ويتبع الوسيط قواعد أنواع المعاملات العادية: في تعداد int، تعيد Priority::from('5') الحالة Priority::Normal في الوضع الافتراضي لأن '5' تُحوَّل إلى 5 أولًا، وPriority::from('5x') خطأ TypeError، ومع declare(strict_types=1) يكون أي نص خطأ TypeError. ويشمل ذلك tryFrom(): ترمي Priority::tryFrom('abc') خطأً بدل إعادة null، لذا افحص مُدخلات النموذج لتعداد int بـ filter_var($raw, FILTER_VALIDATE_INT) أولًا.

سرد كل الحالات بـ cases()

تعيد Enum::cases() مصفوفة بكل حالة، بترتيب التصريح بها. وهكذا تبني قائمة منسدلة، أو تتحقق من قائمة، أو تحصل على كل القيم بـ array_column:

شغّله، واختر خطة واضغط Choose: يعمل السكربت نفسه مرة أخرى مع امتلاء $_POST['plan']، وتحوّل tryFrom() النص المرسل مرة أخرى إلى حالة Plan. والقيمة المزوّرة مثل plan=gold تعطي null، فلا يُحدَّد أي خيار.

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

يمكن أن تكون للتعدادات توابع وتوابع ساكنة وثوابت، ويمكنها تنفيذ واجهات. داخل التابع، $this هي الحالة الحالية، وهذا يجعل match ($this) الطريقة الطبيعية لربط بيانات بكل حالة. وما لا يمكن أن يكون للتعداد هو الخصائص: البيانات الخاصة بكل حالة تأتي من التوابع.

التعدادات في match

تقارن match بـ ===، والحالة في التعداد مطابقة لنفسها فقط، لذا يتلاءم match والتعدادات. إذا نسيت حالة ووصلت تلك الحالة إلى match، ترمي PHP الخطأ UnhandledMatchError بدل أن تعيد لا شيء بصمت:

راجع match لترى كيف يختلف match عن switch.

التعدادات في JSON وبوصفها نصوصًا

تكتب json_encode() الحالة المدعومة على شكل قيمتها. ولا يمكن ترميز التعداد الخالص، وتفشل echo لأي حالة، لأن التعداد كائن لا نص. اطبع ->value أو ->name بدلًا من ذلك:

ترمي echo Role::Admin; الخطأ Error ("Object of class Role could not be converted to string")، ولا يمكن للتعدادات تنفيذ __toString(). وعند العودة، يعطي JSON نصًا عاديًا، فحوّله بـ from() أو tryFrom() كما هو معروض. مزيد عن الترميز في json_encode.

أخطاء شائعة مع التعدادات

تتكرر ثلاثة أخطاء كثيرًا. الحالة لا تساوي قيمتها أبدًا، ولا يمكن أن تكون الحالة مفتاح مصفوفة، ولا تعمل new على تعداد:

إذا احتجت إلى خريطة مفاتيحها الحالات نفسها، فاستخدم SplObjectStorage أو WeakMap، اللتين تقبلان الكائنات مفاتيح.

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

كيف أحصل على قيمة تعداد في PHP؟

في التعداد المدعوم، اقرأ ->value: Status::Active->value تساوي 'active'. ولكل حالة أيضًا ->name، اسم الحالة نصًا ('Active'). أما التعداد الخالص (دون : string أو : int) فليس له إلا ->name.

ما الفرق بين from() وtryFrom() في تعدادات PHP؟

كلتاهما تحوّل قيمة إلى حالة في تعداد مدعوم. تعيد Status::from('active') الحالة أو ترمي ValueError عندما لا تحمل أي حالة تلك القيمة؛ وتعيد Status::tryFrom('nope') القيمة null بدلًا من ذلك. استخدم tryFrom() لمُدخلات المستخدم وfrom() عندما تكون القيمة الخاطئة خطأً برمجيًا.

كيف أحصل على كل قيم تعداد في PHP؟

تعيد Status::cases() كل حالة بترتيب التصريح. ولقيم تعداد مدعوم استخدم array_column(Status::cases(), 'value')، وللأسماء array_column(Status::cases(), 'name').

ما الفرق بين التعداد الخالص والتعداد المدعوم؟

حالات التعداد الخالص (enum Suit { case Hearts; }) أسماء فقط. ويعطي التعداد المدعوم (enum Suit: string { case Hearts = 'H'; }) كل حالة قيمة int أو string فريدة، تحتاجها لتخزينها في قاعدة بيانات، أو وضعها في نموذج أو JSON، وتحويلها مرة أخرى بـ from() أو tryFrom().

هل يمكن أن تكون للتعداد في PHP توابع؟

نعم. يمكن أن تكون للتعدادات توابع وتوابع ساكنة وثوابت، ويمكنها تنفيذ واجهات. داخل التابع، $this هي الحالة الحالية، لذا فإن return match ($this) { self::Active => 'green', self::Banned => 'red' }; نمط شائع. ولا يمكن أن تكون للتعدادات خصائص.

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

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

ابدأ الآن