درآمدی بر کاربردهای دستور break در حلقه‌ها در زبان PHP


خواه از foreach استفاده کنیم و خواه از دیگر انواع حلقه‌های PHP همچون for و while، گاهی نیاز خواهیم داشت تا بسته به منطق وب‌ اپلیکیشن‌مان، در روند اجرای حلقه‌ها دخالت نماییم که برای این منظور، می‌توان از دستورات break و continue استفاده کرد که در این آموزش تمرکز روی دستور break بوده و در آموزش بعد بیشتر با کاربردهای continue آشنا خواهید شد.

آشنایی با دستور break در زبان PHP
در مبحث آشنایی با دستور switch در زبان PHP، با کاربرد دستور break آشنا شدیم. در حقیقت، break به منظور خاتمه دادن به پروسهٔ اجرای یک حلقه می‌تواند مورد استفاده قرار گیرد:

همان‌طور که در تصویر فوق مشاهده می‌شود، در دو صورت کلی است که به نقطهٔ پایانی برنامه‌ می‌رسیم:

- چنانچه شرط اصطلاحاً False باشد.
- چنانچه دستور break در حلقه استفاده شده باشد.

برای درک بهتر کاربرد break در حلقه‌ها، سناریویی را در دنیای واقعی در نظر می‌گیریم بدین صورت که در وب اپلیکیشن خود این امکان را در اختیار کاربران قرار می‌دهیم که جهت لاگین کردن به سایت، سه بار تلاش کنند و چنانچه در فرصت‌های در نظر گرفته‌ شده و با استفاده از نام‌کاربری و رمزعبور صحیح موفق به لاگین کردن نشوند، به منظور رعایت مسائل امنیتی، تا چند دقیقه اجازه تلاش جهت ورود به سایت را نخواهند داشت.

نکته
این مکانیسمی است که اکثر سایت‌ها برای جلوگیری از فعالیت بات‌ها اِعمال می‌کنند.

حال چنانچه بخواهیم چنین چیزی را در وب اپلیکیشن خود پیاده کنیم، خواهیم داشت:

$tries = 0;
$username = 'admin';
$password = '123456';
$userData = ['username' => 'behzad', 'password' => '9f41a95cba557b2894771eed96e07a4ded82537f'];

for ($counter = 1 ; ; $counter = $counter + 1) {
    $tries++;
    echo "Please enter you username in here ... and your password in here ... (It`s your try No $counter)<br>";
    if ($tries == 3) {
        echo "You tries more than $tries times and you are blocked!";
        break;
    } else if ($username == $userData['username'] && $password == $userData['password']) {
        echo "After $tries try(ies), You are logged in successfully.";
        break;
    }
}

ابتدا به تفسیر برنامه‌ٔ فوق پرداخته سپس آن را اجرا می‌کنیم. همان‌طور که در خط اول ملاحظه می‌شود، متغیری ساخته‌ایم تحت عنوان tries$ با مقدار پیش‌فرض صفر که این وظیفه را در برنامه‌ٔ ما خواهد داشت تا تعداد دفعاتی که کاربر برای لاگین تلاش می‌کند را در خود ذخیره سازد. در ادامه نیز دو متغیر تحت عناوین username$ و password$ ایجاد کرده‌ایم به ترتیب با مقادیری همچون admin و 123456 و در نهایت هم آرایه‌ای تحت عنوان userData$ داریم که حاوی دو اندیس تحت عناوین username و password است که مقادیری دلخواه همچون چیزهایی که ملاحظه می‌کنید برایشان در نظر گرفته شده است.

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

به عنوان پارامتر اول این حلقه،‌ متغیری تعریف کرده‌ایم تحت عنوان counter$ به معنی شمارنده که مقدار پیش‌فرض یک برایش در نظر گرفته شده که این متغیر قرار است تا به کاربر نشان دهد که دفعهٔ چندم است که برای ورود به سایت تلاش می‌کند. همان‌طور که پیش از این گفتیم، پارامتر دوم (شرط) حذف شده اما کماکان علامت ; مرتبط با آن سر جایش باقی است که در غیر این صورت با ارور مواجه خواهیم شد و در نهایت به پارامتر سوم (Step) می‌رسیم که در این بخش دستور داده‌ایم تا در هر بار اجرای حلقه، مقدار متغیر counter$ یک واحد افزایش یابد (این در حالی است که به جای این ساختار خیلی راحت‌تر می‌شد تا از ++counter$ استفاده کرد اما دلیل استفاده از این رویکرد فقط نشان دادن حالات مختلف کدنویسی است.)

اسکریپت داخل { } پیش از هر چیز با اصطلاحاً Increment یا افزایش یک واحد به متغیر tries$ شروع می‌شود چرا که می‌خواهیم در هر بار اجرا یک واحد به مقدار پیش‌فرض این متغیر که صفر است اضافه کنیم تا متوجه شویم کاربر چند بار برای ورود به سایت تلاش کرده است و چنانچه از حد مجاز (سه دفعه) تجاوز کرد، جلوی وی را بگیریم. سپس با استفاده از دستور echo اِسترینگی را چاپ می‌‌کنیم با این مضمون که نام‌کاربری و رمزعبور خود را وارد نمایید.

سپس از یک دستور شرطی if else if استفاده نموده‌ایم بدین صورت که شرط if گفته‌ایم که اگر مقدار متغیر tries$ برابر با ۳ بود، متنی در معرض دید کاربر قرار گیرد با این مضمون که «شما بیش از ۳ بار اقدام به ورود به سایت کرده‌اید و مسدود هستید!» و نکتهٔ بسیار مهم اینجا است که در این بلوک حتماً می‌بایست از دستور break استفاده نماییم تا از حلقه خارج شویم. در دستور شرطی دوم یا else if هم گفته‌ایم که اگر مقدار متغیرهای username$ و password$ برابر با مقادیر در نظر گرفته‌ شده برای اندیس‌های username و password در آرایهٔ userData$ بود، این بدان معنا است که نام‌کاربری و رمزعبور صحیح هستند و کاربر بایستی لاگین شود که برای همین منظور، اِسترینگی با معنای تحت‌الفظی «شما با موفقیت لاگین شدید.» در معرض دید کاربر قرار می‌دهیم اما مجدد نکتهٔ مهمی که در این بخش از کد وجود دارد الزام استفاده از دستور break است چرا که قصد داریم به محض اینکه دیتای ورودی صحیح بود، از حلقه خارج شویم. حال یک بار اسکریپت فوق را اجرا می‌کنیم:

Please enter you username in here ... and your password in here ... (It`s your try No 1)
Please enter you username in here ... and your password in here ... (It`s your try No 2)
Please enter you username in here ... and your password in here ... (It`s your try No 3)
You tries more than 3 times and you are blocked!

در تفسیر نحوهٔ عملکرد برنامه در مثال فوق، بایستی گفت که مقدار در نظر گرفته‌ شده برای اندیس‌های username و password با مقدار پیش‌فرض متغیرهای username$ و password$ یکسان نیستند؛ پس هرگز وارد بلوک else if نخواهیم شد بلکه در عوض اجرای اسکریپت‌های داخل { } ادامه می‌یابد و هر دفعه هم یک واحد به مقدار متغیر tries$ اضافه می‌گردد و این کار تا زمانی ادامه می‌یابد که این مقدار به عدد ۳ رسیده که در این صورت وارد بلوک if می‌شویم و اینجا است که به کاربر (یا ربات) هشدار داده می‌شود که بیش از حد مجاز برای ورود به سایت تلاش کرده، فلذا مسدود شده است و با استفاده از دستور break هم از این حلقه خارج می‌شویم. برای بار دوم اجرا، ابتدا اسکریپت فوق را به شکل زیر ریفکتور کرده سپس دست به اجرای آن می‌زنیم:

$tries = 0;
$username = 'admin';
$password = '123456';
$userData = ['username' => 'admin', 'password' => '123456'];

for ($counter = 1 ; ; $counter = $counter + 1) {
    $tries++;
    echo "Please enter you username in here ... and your password in here ... (It`s your try No $counter)<br>";
    if ($tries == 3) {
        echo "You tries more than $tries times and you are blocked!";
        break;
    } else if ($username == $userData['username'] && $password == $userData['password']) {
        echo "After $tries try(ies), You are logged in successfully.";
        break;
    }
}

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

Please enter you username in here ... and your password in here ... (It`s your try No 1)
After 1 try(ies), You are logged in successfully.

در واقع، این بار حلقه فقط یک مرتبه اجرا شده، مقدار متغیر tries$ از صفر به یک تغییر یافته و مستقیماً وارد بلوک else if شده‌ایم چرا که مقادیر پیش‌فرض اندیس‌های username و password با مقادیر پیش‌فرض متغیرهای username$ و password$ یکسانند اما مجدد بایستی گفت که نکتهٔ مهم در اینجا، استفاده از دستور break داخل بلوک else if است که در غیر این صورت، برنامه‌ به درستی کار نخواهد کرد. به عنوان مثال داریم:

if ($tries == 3) {
    echo "You tries more than $tries times and you are blocked!";
    break;
} else if ($username == $userData['username'] && $password == $userData['password']) {
    echo "After $tries try(ies), You are logged in successfully.";
    // break;
}

همان‌طور که ملاحظه می‌شود، دستور break قرار گرفته داخل بلوک else if را کامنت کرده‌ایم. حال یک بار دیگر برنامه را اجرا می‌کنیم:

Please enter you username in here ... and your password in here ... (It`s your try No 1)
After 1 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 2)
After 2 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 3)
You tries more than 3 times and you are blocked!

می‌بینیم علیرغم اینکه نام‌کاربری و رمزعبور صحیح هستند، اما مسدود شدیم و دلیل این مسئله هم آن است که هیچ منطقی در برنامه وجود ندارد تا پس از درست بودن دیتای کاربر، وی را از حلقه خارج سازد و این کار آن‌قدر ادامه می‌یابد تا در نهایت تعداد دفعات مجاز تلاش برای ورود به سایت بیش از ۳ بار شده و وارد بلوک if شویم. حال اگر دستور break داخل if را هم به صورت زیر کامنت کنیم، نتیجه کاملاً‌ مشخص است که داخل یک حلقهٔ به اصطلاح Infinite (بی‌پایان) خواهیم افتاد:

if ($tries == 3) {
    echo "You tries more than $tries times and you are blocked!";
    // break;
} else if ($username == $userData['username'] && $password == $userData['password']) {
    echo "After $tries try(ies), You are logged in successfully.";
    // break;
}

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

Please enter you username in here ... and your password in here ... (It`s your try No 1)
After 1 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 2)
After 2 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 3)
You tries more than 3 times and you are blocked!Please enter you username in here ... and your password in here ... (It`s your try No 4)
After 4 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 5)
After 5 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 6)
After 6 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 7)
After 7 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 8)
After 8 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 9)
After 9 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 10)
After 10 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 11)
After 11 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 12)
After 12 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 13)
After 13 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 14)
After 14 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 15)
After 15 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 16)
After 16 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 17)
After 17 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 18)
After 18 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 19)
After 19 try(ies), You are logged in successfully.Please enter you username in here ... and your password in here ... (It`s your try No 20)
.
.
.

این حلقه تا بی‌نهایت ادامه خواهد داشت تا ما اقدام به متوقف کردن برنامه به صورت دستی کنیم!

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
عبدالحمید ارجمند
عبدالحمید ارجمندAndroid Developer - Java - عاشق گجتهای اپل و مایکــ
با سلام ، ممنونیم از وقتی که برای تدریس و تدوین آموزشها صرف میکنید ، قطعاً مثمر ثمر خواهند بود. پیشنهادی که دارم این هست که به محض انتشار نسخه ی fuchsia برای توسعه دهنده گان ، آموزشهای این سری را استارت بزنید تا اینکه بایکدیگر از پیشگامان باشیم.
بهزاد مرادی
بهزاد مرادی مدرس، کپی‌رایتر و دولوپر
سلام
نظر لطف شماست. راستش برنامه‌ای که برای این دوره در نظر دارم این هست که بسیار کامل و جامع باشد (ان‌شاء‌الله) که همین مسئله اجازه نمی‌ده حتی به مقاله‌ نوشتن در وبلاگ فکر کنم چه رسد به شروع آموزش جدید.
دوره‌هایی مثل همین فیوشا را به دیگر سایت‌های ایران واگذار می‌‌کنیم 😉

در پاسخ به

عبدالحمید ارجمند
عبدالحمید ارجمندAndroid Developer - Java - عاشق گجتهای اپل و مایکــ
وای خدایا ، گویا میخواید کولاک کنید 😀 .

با اینکه پی اچ پی انتهایی نداره اما نهایتاً به مقداری بسنده میکنید دیگه ، اون روز وقتشه که فیوشا رو استارت بزنید .

در پاسخ به