Kodokon kodokon.com

PHP الحديثة: الأنواع الصارمة، والتعدادات، وmatch

تبنَّ PHP اليوم: الأنواع الصارمة، والدوال السهمية، ومُعامِل الأمان من null، والتعدادات، وتعبير match.

9 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

تحتضن PHP الحديثة التنميط. تعطّل declare(strict_types=1)، الموضوعة كأول تعليمة في الملف، التحويلات الضمنية: فتمرير السلسلة '10' إلى وسيط من النوع float يُطلق TypeError بدلًا من تحويلها بصمت. حدِّد أنواع الوسائط والقيم المُرجَعة: فتظهر أخطاؤك مبكرًا، في المكان الصحيح، بدلًا من أن تظهر بعد ثلاثة ملفات.

PHP
<?php

declare(strict_types=1);

function applyDiscount(
    float $price,
    float $rate = 0.1
): float {
    return round($price * (1 - $rate), 2);
}

echo applyDiscount(49.99);
echo PHP_EOL;
echo applyDiscount(100.0, 0.25);
توقيع مُنمَّط: عقد الدالة صريح.

تختصر الدوال السهمية fn الدوال المجهولة ذات التعبير الواحد. وميزتها الكبرى مقارنة بالإغلاقات التقليدية: أنها تلتقط تلقائيًا متغيرات النطاق الأب، دون عبارة use. وهي تتألق مع array_map() وarray_filter().

PHP
<?php

declare(strict_types=1);

$prices = [12.5, 49.9, 8.0, 120.0];
$rate = 0.2;

$discounted = array_map(
    fn (float $p): float => round($p * (1 - $rate), 2),
    $prices
);

$affordable = array_filter(
    $discounted,
    fn (float $p): bool => $p < 50
);

print_r($affordable);
يُلتقَط المتغير rate دون عبارة use.

يقطع مُعامِل الأمان من null ?-> الاستدعاء حالما تكون إحدى الحلقات في السلسلة null، بدلًا من التسبب في خطأ فادح. وعند دمجه مع ??، يستبدل بأهرام من عبارات if سطرًا واحدًا سهل القراءة.

PHP
<?php

declare(strict_types=1);

class Address
{
    public function __construct(
        public readonly string $city
    ) {
    }
}

class User
{
    public function __construct(
        public readonly ?Address $address = null
    ) {
    }
}

$alice = new User(new Address('Lyon'));
$bob = new User();

echo $alice->address?->city ?? 'Unknown city';
echo PHP_EOL;
echo $bob->address?->city ?? 'Unknown city';
لا خطأ بالنسبة لـ Bob: تتوقف السلسلة عند أول null.

تمنح التعدادات نوعًا حقيقيًا لمجموعات القيم المغلقة (الحالات، الأدوار): فيصبح من المستحيل إنشاء حالة غير موجودة. وmatch تحسين واضح على switch: مقارنة صارمة، ونتيجة تُرجَع كقيمة، وUnhandledMatchError إذا لم تطابق أيّ حالة - وهي حماية من السهو.

PHP
<?php

declare(strict_types=1);

enum OrderStatus: string
{
    case Pending = 'pending';
    case Shipped = 'shipped';
    case Delivered = 'delivered';

    public function label(): string
    {
        return match ($this) {
            self::Pending => 'Pending',
            self::Shipped => 'Shipped',
            self::Delivered => 'Delivered',
        };
    }
}

$status = OrderStatus::from('shipped');
echo $status->label();
تعداد مدعوم بسلاسل نصية: مثالي لقاعدة بيانات.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. مع declare(strict_types=1)، ماذا يحدث إذا مرّرت السلسلة '10' إلى وسيط من النوع float؟
    • تحوّل PHP السلسلة بصمت إلى 10.0
    • تُطلق PHP مجرد تحذير وتستمر
    • تُطلق PHP خطأ TypeError
  2. ما الذي يميّز الدالة السهمية fn() عن الإغلاق التقليدي function()؟
    • يمكنها أن تحتوي على عدة تعليمات
    • تلتقط تلقائيًا متغيرات النطاق الأب، دون عبارة use
    • تعمل بسرعة أكبر
    • لا يمكنها التصريح بالأنواع
  3. أيّ ميزة يمتلكها تعبير match على switch؟
    • يقارن بصرامة (===)، ويُرجِع قيمة، ويُطلق خطأً إذا لم تطابق أيّ حالة
    • يقبل المقارنات المرنة (==) لمزيد من المرونة
    • يسمح بالانتقال من حالة إلى التي تليها