آشنایی با دستورات شرطی if elseif else در زبان PHP


فارغ از نوع وب‌ اپلیکیشنی که بخواهیم طراحی کنیم، همواره نیاز به بررسی شروط مختلف در اپلیکیشن وجود دارد که چنین چیزی در زبان PHP با استفاده از دستوارت elseif ،if و else مدیریت می‌شود:

if (First condition) {
    // Do something
} elseif (Second condition) {
    // Do something else
} else {
    // Do something if none of the above is met
}

آنچه در بالا مشاهده می‌شود، ساختار کلی دستورات شرطی در زبان PHP است. در واقع، اگر شرط قرار گرفته داخل پرانترهای مرتبط با if برآورده شود (یا به عبارت دیگر true یا درست باشد)، کدهای قرار گرفته داخل { } اجرا خواهند شد و دستورات elseif و else هرگز اجرا نخواهند شد اما اگر این شرط برآورده نشود، مفسر به سراغ شرط قرار گرفته داخل پرانترهای مرتبط با دستور elseif می‌رود و اگر این شرط برآورده شد، کدهای قرار گرفته داخل { } اجرا خواهند شد و مفسر هرگز به سراغ دستور else نمی‌رود اما اگر این شرط هم برآورده نشد، در نهایت مفسر هر آنچه که داخل { } مرتبط با else قرار گرفته باشد را اجرا خواهد کرد. توجه داشته باشیم که به هر تعداد elseif که بخواهیم می‌توانیم در بلوک شرطی خود بگنجانیم:

if (First condition) {
    // Do something
} elseif (Second condition) {
    // Do something else
} elseif (Third condition) {
    // Do something else
} elseif (Forth condition) {
    // Do something else
} elseif (Fifth condition) {
    // Do something else
} elseif (Sixth condition) {
    // Do something else
} elseif (Nth condition) {
    // Do something else
} else {
    // Do something if none of the above is met
}

گرچه به هر تعدادی که بخواهیم می‌توانیم از دستورات elseif استفاده کنیم، اما در میان دولوپرهای PHP مرسوم است که در چنین شرایطی از ساختار شرطی دیگری تحت عنوان switch استفاده می‌کنند که در آموزش‌های آتی به تفصیل مورد بررسی قرار خواهد گرفت.

در ارتباط با دستورات شرطی، بایستی این نکته را مد نظر داشته باشیم که دستورات elseif و else دلخواه هستند و می‌توانیم هرگز از آنها استفاده نکنیم. به عبارت دیگر داریم:

if (Condition) {
    // Do something
}

در واقع، در اسکریپت فوق چک می‌کنیم ببینیم که آیا Condition (شرط) برابر با true است یا خیر؛ اگر true باشد، دستورات داخل { } اجرا خواهند شد و در غیر این صورت، هیچ اتفاق دیگری رخ نخواهد داد. علاوه بر این، اگر بخواهیم می‌توانیم علائم { } را برای ساده‌تر سورس‌کد حذف کنیم:

if (Condition) 
    // Do something

در این نوع ساختار توجه داشته باشیم که صرفاً اولین خط کدی که پس از دستور if قرار گرفته است به عنوان بلوک if در نظر گرفته خواهد شد و خطوط بعدی خارج از این ساختار تلقی خواهند شد. برای روشن‌تر شدن این مسئله داریم:

if (Condition) 
    // Do something
    // Do something else

در واقع اگر شرط true باشد، هرآنچه کدی که به جای کامنت Do something // قرار گرفته باشد اجرا خواهد شد و هرآنچه کدی که به جای کامنت Do something else // قرار گرفته باشد فارغ از این که شرط true یا false باشد، اجرا خواهد شد.

هشدار
توجه داشته باشیم که حذف علائم { } می‌تواند منجر ناخوانی سورس‌کد گردد. لذا توصیه می‌شود که همواره از علائم { } استفاده شود.

اگر بخواهیم زمانی که از دستور elseif استفاده می‌کنیم علائم { } را حذف کنیم، بایستی به صورت زیر کدهای خود را ریفکتور کنیم:

if (First condition):
    // Do something
elseif (Second condition): 
    // Do something else
else:
    // Do something if none of the above is met
endif;

می‌بینیم که ساختار تا حدودی متفاوت است و کلیدواژهٔ جدیدی تحت عنوان endif استفاده شده است.

به خاطر داشته باشید
لازم به ذکر است که کلیدواژهٔ elseif را هم می‌شود سرهم (elseif) و هم جدا (else if) نوشت. البته این در شرایطی صادق است که از علائم { } استفاده کرده باشیم و چنانچه این علائم را حذف کرده باشیم‌، صرفاً بایستی این کلیدواژه را سرهم (elseif) نوشت که در غیر این صورت ارور خواهیم گرفت.

در ارتباط با نکتهٔ مهم فوق داریم:

if (First condition):
    // Do something
else if (Second condition): // Pay attention to the space between else and if
    // Do something else
else:
    // Do something if none of the above is met
endif;

اگر ساختار فوق را در کدهای واقعی به کار گیریم و اسکریپت را اجرا کنیم، با ارور زیر مواجه خواهیم شد:

Parse error: syntax error, unexpected 'if' (T_IF), expecting ':' in /var/www/sokanacademy-php-course/index.php on line 4

در چه شرایطی دستورات مرتبط با if اجرا خواهند شد؟
به طور کلی،‌ چنانچه نتیجهٔ یک Condition (شرط) اصطلاحاً true باشد، دستورات مرتبط با if اجرا خواهند شد. به طور مثال داریم:

<?php
$condition = '';
if ($condition) {
    echo "The condition is met";
} else {
    echo "The condition is not met";
}

مقدار متغیر condition$ را برابر با یک استرینگ خالی قرار داده‌ایم. حال اگر اسکریپت فوق را اجرا کنیم، از آنجا که از دید مفسر PHP استرینگ خالی برابر با false است، دستور داخل else اجرا خواهد شد. به عنوان مثالی دیگر داریم:

<?php
$condition = 0;
if ($condition) {
    echo "The condition is met";
} else {
    echo "The condition is not met";
}

کماکان مقدار 0 هم برابر با false است و دستور داخل else اجرا خواهد شد. به عنوان مثالی دیگر داریم:

<?php
$condition = false;
if ($condition) {
    echo "The condition is met";
} else {
    echo "The condition is not met";
}

مقدار false که برای متغیر condition$ در نظر گرفته شده است هم کاملاً مشخص است که نیاز if را برآورده نمی‌سازد. به عنوان مثالی دیگر داریم:

<?php
$condition = null;
if ($condition) {
    echo "The condition is met";
} else {
    echo "The condition is not met";
}

پیش از این گفتیم که NULL یکی از انواع دیتاتایپ‌ها در زبان PHP است و این دیتاتایپ هم رفتاری همچون false دارد و نمی‌تواند نیاز دستور شرطی if را برآورده سازد. حال اگر مقادیری همچون موارد زیر را در نظر بگیریم، به سادگی خواهیم توانست وارد دستور شرطی if شویم:

<?php
$condition = true;
/*
Or alternatively
$condition = 1; or
$condition = "This is set";
*/
if ($condition) {
    echo "The condition is met";
} else {
    echo "The condition is not met";
}

به عنوا خروجی اسکریپت فوق داریم:

The condition is met

در واقع، اگر به جای مقدار true برای متغیر condition$ از مقادیری همچون ۱ و یا استرینگ This is set استفاده کنیم، همواره شرط if برابر با true بوده و دستورات داخل علائم { } مرتبط با if اجرا خواهند شد (لازم به ذکر است که ۱ نمود عددی مقدار true و ۰ نمود عددی مقدار false است).

کاربرد فانکشن ()isset در کنار دستورات شرطی
پیش از این با فانکشن ()isset آشنا شدیم و گفتیم کاری که این تابع انجام می‌دهد این است که چک می‌کند ببیند آیا یک متغیر مقداری به غیر از NULL دارد یا خیر؛ اگر این‌گونه بود، مقدار true را بازمی‌گرداند و اگر هم NULL بود مقدار false را باز خواهد گرداند. به عنوان مثال داریم:

<?php
$condition = 0;
if (isset($condition)) {
    echo "The condition is met";
} else {
    echo "The condition is not met";
}

اگر اسکریپت فوق را اجرا کنیم‌، می‌بینیم که دستور مرتبط با if اجرا می‌گردد بدان معنی که خروجی فانکشن ()isset برابر با true است و این در حالی است که اگر خود متغیر condition$ را به عنوان پارامتر ورودی به دستور if پاس دهیم، از دید مفسر PHP هرگز true نیست!

به عبارت دیگر، مقادیر false ،0 و استرینگ خالی که پیش از این چک کردیم که حاوی مقدار false بودند، اگر با استفاده از فانکشن ()isset به کار گرفته شوند، مقدار true بازگردانده خواهد شد و تنها چیزی که مقدار false را باز خواهد گرداند، دیتاتایپ NULL است. به عنوان مثال داریم:

<?php
$condition;
if (isset($condition)) {
    echo "The condition is met";
} else {
    echo "The condition is not met";
}

باتوجه به این که متغیر condition$ تعریف شده ولی مقداردهی نشده است (یا به عبارت دیگر Set نشده است)، خروجی فانکشن ()isset برابر با false بود، فلذا دستور داخل else اجرا خواهد شد.

استفاده از اپراتورهای منطقی و مقایسه‌ای در دستورات شرطی
پیش از این با اپراتورهای منطقی و مقایسه‌ای در زبان PHP آشنا شدیم و این در حالی است که به سادگی می‌توان از این اپراتورها در دستورات شرطی if استفاده کرد:

اپراتور توضیحات
== برابری را نشان می‌دهد.
=== برابری و دیتاتایپ یکسان را نشان می‌دهد.
=! یا <> نابرابری را نشان می‌دهد.
==! نابرابری و عدم برخورداری از دیتاتایپ یکسان را نشان می‌دهد.
< بزرگ‌تر بودن را نشان می‌دهد.
> کوچک‌تر بودن را نشان می‌دهد.
=< بزرگ‌تر یا مساوی را نشان می‌دهد.
=> کوچک‌تر یا مساوی را نشان می‌دهد.
and یا && این اپراتور به معنی «و» است و چنانچه دو طرف آن true باشد، مقدار true بازگردانده خواهد شد.
or یا || این اپراتور به معنی «یا» است و چنانچه یکی از عملوندهای راست یا چپ این اپراتور true باشد، مقدار true بازگردانده خواهد شد.
xor یا ^ در صورتی که یکی از عملوندها true باشد (نه هر دوی آنها)، این اپراتور مقدار true را باز خواهد گرداند.
! این اپراتور مقدار true را باز خواهد گرداند چنانچه عملوند قرار گرفته پس از آن true نباشد!

برای روشن‌تر شدن بحث، اپراتور مقایسه‌ای == را در یک دستور شرطی مورد استفاده قرار داده‌ایم تا مشخص سازیم که آیا پروتکل انتخابی ما امن (https) است یا ناامن (http). برای این منظور داریم:

<?php
$protocol = 'http';
if ($protocol == 'http') {
    echo "Your connection is insecure!";
} elseif ($protocol == 'https') {
    echo "Let`s go. You have a secure connection.";
} else {
    echo "The protocol in undefined!";
}

همان‌طور که ملاحظه می‌شود، متغیری تعریف کرده‌ایم تحت عنوان protocol$ که استرینگی به صورت http داخل آن ذخیره کرده‌ایم. سپس با استفاده از دستورات شرطی if elseif else به بررسی مقدار این متغیر پرداخته‌ایم. 

در واقع، دستور داده‌ایم که اگر مقدار این متغیر برابر با http بود، عبارت !Your connection is insecure در خروجی چاپ شود، اگر https بود عبارت .Let`s go. You have a secure connection چاپ شده و در نهایت اگر نه http بود و نه https، عبارت !The protocol in undefined در معرض دید کاربر قرار گیرد. به طور مثال، اگر اسکریپت فوق را در مرورگر اجرا کنیم، با خروجی زیر مواجه خواهیم شد:

Your connection is insecure!

به عنوان مثالی دیگر، می‌توان نحوهٔ به‌کارگیری اپراتور || به معنی «یا» را مورد بررسی قرار دهیم:

<?php
$experience = 4;
$levelOfProficiency = 'senior';
$age = 27;

if (($experience > 5 || $levelOfProficiency == 'senior') && ($age > 20 && $age < 35)) {
    echo "You might be a developer with a high salary.";
} else {
    echo "Although you can find a job, you don`t have to expect a high salary.";
}

همان‌طور که ملاحظه می‌شود، سه متغیر تعریف کرده‌ایم تحت عناوین levelOfProfiency ،$experience$  و age$ که به ترتیب به معانی «تجربه»، «سطح مهارت» و «سن» هستند. دستور شرطی استفاده شده در کد فوق کمی پیچیده به نظر می‌رسد اما گاهی‌اوقات نیاز به استفاده از ساختارهایی این‌چنین داریم.

در واقع، در دستور if دو شرط مختلف را سنجیده‌ایم اما برای اینکه خوانایی سورس‌کد بالا رود (و احیاناً به تناقض برنخوریم)، آنها را داخل پرانتزهایی جداگانه‌ای قرار داده و مابین هر دو جفت پرانتز هم از علامت && استفاده کرده‌ایم بدین معنا که هر دو شرط بایستی true باشند.

در پرانتز اول، گفته‌ایم که میزان تجربهٔ دولوپر باید بیش از ۵ سال باشد یا سطح مهارت ایشان برابر با senior (ارشد) باشد. در پرانتز دوم هم گفته‌ایم که سن دولوپر بایستی بزرگ‌تر از ۲۰ و کوچک‌تر از ۳۵ سال باشد. حال اسکریپت فوق را اجرا می‌کنیم:

You might be a developer with a high salary.

می‌بینیم که کلیهٔ شروط true هستند، لذا دستور داخل بلوک if اجرا می‌شود و این در حالی است که مثلاً اگر سن دولوپر فرضی را ۲۰ در نظر بگیریم، شروط برآورده نشده و دستور داخل بلوک else اجرا می‌گردد:

<?php
$experience = 4;
$levelOfProficiency = 'senior';
$age = 20;

if (($experience > 5 || $levelOfProficiency == 'senior') && ($age > 20 && $age < 35)) {
    echo "You might be a developer with a high salary.";
} else {
    echo "Although you can find a job, you don`t have to expect a high salary.";
}

به عنوان خروجی داریم:

Although you can find a job, you don`t have to expect a high salary.

واقعیت امر آن است که در دستور شرطی خود در پرانتز دوم گفته‌ایم که حداقل سن بایستی بیش از ۲۰ سال باشد و از آنجا که سن این دولوپر فرضی برابر با ۲۰ است، شراط برآورده نشده و در نتیجه وارد بلوک else می‌شویم.

دستورات شرطی اصطلاحاً Nested (تو در تو)
بسته به میزان پیچیدگی اسکریپتی که می‌نویسیم، گاهی‌اوقات نیاز داریم تا چندین دستور شرطی را با یکدیگر ادغام کنیم تا بتوانیم شرایط مختلفی را ساپورت کنیم. در چنین موقعیت‌هایی می‌بایست با مفهومی تحت عنوان Nested If Statements (دستورات شرطی تو در تو) آشنا شویم. برای روشن‌تر شدن این مبحث، کدهای زیر را مد نظر قرار می‌دهیم:

<?php
$experience = 4;
$levelOfProficiency = 'senior';
$age = 31;

if (($experience > 5 || $levelOfProficiency == 'senior') && ($age > 20 && $age < 35)) {
    if ($age > 20 && $age <= 25) {
        echo "Although you`re so young, you might be a developer with a high salary.";
    } elseif ($age > 26 && $age <= 30) {
        echo "You might be a developer with a high salary. So you can get ready to get married.";
    } else {
        echo "Although you might be a developer with a high salary, you`re getting old.";
    }
} else {
    echo "Although you can find a job, you don`t have to expect a high salary.";
}

ابتدا اسکریپت فوق را اجرا می‌کنیم:

Although you might be a developer with a high salary, you`re getting old.

در واقع، به خاطر true بودن شروط، ابتدا وارد بلوک if اصلی (خارجی) می‌شویم اما در ارتباط با دستورات شرطی داخلی، از آنجا که شروط داخل بلوک‌های if و elseif داخلی برآورده نشده‌اند، وارد بلوک else داخلی شده‌ایم.

آشنایی با اپراتور ? به جای دستورات if else در PHP
پیش از این در بحث معرفی اپراتورها، به معرفی اپراتور ? که تحت عنوان Ternary Operator شناخته می‌شود پرداختیم و گفتیم که از این اپراتور به منظور خلاصه‌نویسی دستورات شرطی if else استفاده می‌شود. برای مثال داریم:

<?php
$experience = 2;
$levelOfProficiency = 'senior';
$hasHighSalary = null;
$hasHighSalary = ($experience >= 4 && $levelOfProficiency == 'senior') ? true : false;
var_dump($hasHighSalary);

به عنوان خروجی اسکریپت فوق داریم:

bool(false)

در واقع، متغیری تعریف کرده‌ایم تحت عنوان hasHighSalary$ (دارای حقوق بالا) که مقدار پیش‌فرض آن را برابر با null قرار داده‌ایم که یکی از دیتاتایپ‌های زبان PHP است. سپس در خط بعد مقدار این متغیر را برابر با یک دستور شرطی با استفاده از اپراتور ? قرار داده‌ایم بدین صورت که گفته‌ایم اگر تجربهٔ دولوپر بزرگ‌تر یا مساوی با ۴ سال بود و سطح مهارت وی senior (ارشد) بود، مقدار بولینی true برای این متغیر در نظر گرفته شود و در غیر این صورت، مقدار false اختصاص یابد و از آنجا که تجربهٔ این دولوپر فرضی برابر با ۲ سال است، می‌بینیم که به درستی مقدار false برای این متغیر در نظر گرفته شده است.

علاوه بر Ternary Operator، در نسخهٔ ۷ زبان PHP اپراتور دیگری معرفی شد به نام Null Coalescing که در پستی در وبلاگ سکان آکادمی تحت عنوان آشنایی با اپراتور Null Coalesce در PHP نسخهٔ ۷ این اپراتور به تفصیل مورد بررسی قرار گرفته است.

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
محسن
محسن
در مورد استفاده از دستورات شرطی if و elseif نکته ای که باید بهش توجه کرد و خیلی از مواق باعث بروز خطا میشه
نوشتن علامت = یا انتصاب به تعریف برنامه نویسی
به جای == یا مقایسه است

در صورت استفاده از علامت = انتصاب و حالت اول به نوعی شرط همیشه درست میشه، چون مقدار مورد نظر داخل متغیر ریخته می شه و بلاک کد مربوطه اجرا میشه
Insight
Insight
برای بیان حالتی که شرط اول دارای مقدار اشتباه بوده و ما میخوایم شرط دیگری رو بررسی کنیم، در زبان های مختلف notation های مختلفی ارائه شده. مثلا در زبان سی و سی پلاس پلاس از else if استفاده میشه. یا در زبان پایتون این کار رو با کلمه‌ی elif انجام میدیم.
زبان پی اچ‌ پی هم حالتی بین این دو رو انتخاب کرده و میشه از elseif استفاده کرد. درمورد دلیل این انتخاب چیز قابل استنادی وجود نداره. ممکنه برای راحتی و سرعت نوشتن یا کوتاه‌تر بودن این کلمه‌ انتخاب شده باشه.
رضا سنگ‌سفیدی
رضا سنگ‌سفیدیطراح رابط کاربری/توسعه‌دهنده php
ممنون. خوب بود.