کاربرد عبارت match در PHP 8 – به زبان ساده


PHP 8 عبارت جدیدی به نام match را معرفی کرده است. این قابلیت قدرتمندی است که گزینه بهتری نسبت به استفاده از گزاره switch در نسخههای پیشین این زبان محسوب میشود. اما شاید بپرسید تفاوتهای این دو در چیست. در ادامه این مقاله در مورد این موضوع و همچنین کاربرد عبارت match در PHP 8 توضیح خواهیم داد.
کار خود را با مقایسه این دو گزاره آغاز میکنیم. در ادامه یک مثال از گزاره کلاسیک سوئیچ PHP را مشاهده میکنید:
1switch ($statusCode) {
2 case 200:
3 case 300:
4 $message = null;
5 break;
6 case 400:
7 $message = 'not found';
8 break;
9 case 500:
10 $message = 'server error';
11 break;
12 default:
13 $message = 'unknown status code';
14 break;
15}
همچنین معادل کد فوق که با استفاده از عبارت match بازنویسی شده، به صورت زیر است:
1$message = match ($statusCode) {
2 200, 300 => null,
3 400 => 'not found',
4 500 => 'server error',
5 default => 'unknown status code',
6};
قبل از هر چیز میبینیم که عبارت match بسیار کوتاهتر است. همچنین مزیتهای زیر را دارد:
- نیازمند گزاره break نیست.
- میتوان شاخههای مختلف را با استفاده از کاما ترکیب کند.
- یک مقدار بازگشت میدهد و از این رو تنها یک بار مقدار را انتساب میدهد.
چنان که میبینید عبارت match نسبت به گزاره قدیمی switch مزیتهای زیادی دارد، اما این مزایا به فهرست فوق محدود نمیشوند. در ادامه در این خصوص بیشتر توضیح میدهیم.
عدم تغییر نوع
عبارت match به جای بررسیهای نوع به شیوه سست، از بررسیهای صریح استفاده میکند.
این کار مانند استفاده از === به جای == است. افراد مختلف ممکن است با این موضوع موافق یا مخالف باشند، اما این موضوع کاملاً جداگانهای است.
1$statusCode = '200';
2
3$message = match ($statusCode) {
4 200 => null,
5 default => 'unknown status code',
6};
7
8// $message = 'unknown status code'
مقادیر نامشخص خطا ایجاد میکنند
اگر فراموش کنید که یک مقدار را بررسی کنید، زمانی که هیچ شاخه default تعیین نشده باشد، PHP یک استثنای default ایجاد میکند. این هم یک قید تصریحی دیگر است، اما از بروز باگهای کوچکی که ممکن است دور از چشم بمانند، جلوگیری میکند.
1$statusCode = 400;
2
3$message = match ($statusCode) {
4 200 => 'perfect',
5};
6
7// UnhandledMatchError
فعلاً تنها امکان استفاده از عبارتهای تکخطی وجود دارد
در هنگام استفاده از عبارت جدید match همانند کلوژرهای کوتاه، فعلاً تنها امکان نوشتن یک عبارت وجود دارد. بلوکهای عبارتی احتمالاً در آینده اضافه خواهند شد، اما این موضوع هنوز به طور دقیقی روشن نیست.
ترکیب شرطها
قبلاً اشاره کردیم که در این عبارت جدید match از گزارههای break استفاده نمیکنیم. این بدان معنی است که امکان خروج پیشفرض از شرطها (fallthrough) نیز مانند حالت ترکیب دو خط case در مثال اول switch این مقاله وجود ندارد. با این حال از سوی دیگر میتوانید شرطها را در همان خط ترکیب کنید و از یک کاما برای جداسازی آنها استفاده کنید.
بنابراین همان کارکرد سوئیچ را در این مورد هم دارید، اما کد کمتری مینویسید و امکان خراب کردن کارها هم کمتر شده است که یک بازی برد-برد محسوب میشود.
1$message = match ($statusCode) {
2 200, 300, 301, 302 => 'combined expressions',
3};
عملکرد در شرطهای پیچیده
در زمان بررسی استدلالها در خصوص عبارت match برخی افراد اشاره کردند که الگوی زیر نسبت به افزودن عبارت match بهتر است:
1$message = [
2 $this->matchesRegex($line) => 'match A',
3 $this->matchesOtherRegex($line) => 'match B',
4][$line] ?? 'no match';
با این حال یک مشکل بزرگ وجود دارد. این تکنیک ابتدا همه تابعهای ریجکس را اجرا میکند که موجب افت عملکرد میشود. از این رو عبارت match گزینه بهتری محسوب میشود.
صدور استثنا
پس از مدتها انتظار و با توجه به روش صدور استثناها در PHP 8، اکنون امکان صدور یک استثنا مستقیماً از درون یک شاخه به صورت زیر پدید آمده است:
1$message = match ($statusCode) {
2 200 => null,
3 500 => throw new ServerError(),
4 default => 'unknown status code',
5};
تطبیق الگو
یک نکته دیگر نیز در مورد عبارت جدید match وجود دارد و آن «تطبیق الگو» (pattern matching) است. این تکنیک در زبانهای دیگر برنامهنویسی نیز استفاده میشود و امکان تطبیق الگوهای پیچیده را به علاوه بر موارد ساده فراهم میسازد. مثلاً میتوان به ریجکس اشاره کرد، اما تصور کنید به جای متن از متغیرها استفاده شده باشد.
تطبیق الگو فعلاً پشتیبانی نمیشود، زیرا یک قابلیت کاملاً پیچیده است، اما برخی اخبار حکایت از اضافه شدن آن در نسخههای آینده دارد که بسیار نویدبخش است.
از بین switch یا match کدام بهتر است؟
اگر بخواهیم عبارت match را در یک جمله خلاصه بکنیم، باید بگوییم که نسخه صریحتر و مدرنتر از گزاره switch محسوب میشود. البته گزاره سوئیچ در برخی موارد و به طور خاص در زمینه انعطافپذیری بیشتر به خصوص در بلوکهای کد چندخطی عملکرد بهتری از خود نشان میدهد. اما صراحت بیشتر عملگر match در کل بهتر است و چشمانداز تطبیق الگو، کل بازی را به نفع آن تغییر خواهد داد.
بسیاری از برنامهنویسان حرفهای سالها است که از گزاره switch استفاده نمیکنند، زیرا معایب زیادی دارد. اینها همگی معایبی هستند که match آنها را اصلاح کرده است. بنابراین با این که هنوز نمیتوان گفت که match گزینه کاملی است، اما کاربردهای مناسب زیادی دارد.