PHP سرور سائیڈ پر بہت سے تکراری کاموں کو سنبھالتا ہے۔ ایک ہی درخواست کے لیے تصاویر سے بھرے فولڈر کو اسکین کرنا، اسٹیٹس تبدیل ہونے تک ڈیٹا بیس کو پول کرنا، یا جب تک آپ کے اصول پورے نہ ہوں صارف سے ان پٹ مانگتے رہنا پڑ سکتا ہے۔ اسی کوڈ کے بلاک کو کاپی اور پیسٹ کر کے یہ سب کرنا ناپائیدار ہوگا اور اسے برقرار رکھنا تقریباً ناممکن ہوگا۔ لوپس (Loops) بالکل اسی مسئلے کو حل کرنے کے لیے موجود ہیں۔ وہ لاجک کو ایک دوبارہ استعمال کے قابل بلاک میں لپیٹ دیتے ہیں، غلطیوں کو کم کرتے ہیں، اور آپ کی ایپلی کیشن کو جامع رکھتے ہیں۔
زیادہ تر PHP ڈویلپرز فطری طور پر for لوپ کا استعمال کرتے ہیں جب انہیں معلوم ہو کہ کتنی بار دہرانا (iterations) ہے، یا while لوپ کا استعمال کرتے ہیں جب گنتی کسی متحرک (dynamic) شرط پر منحصر ہو۔ تاہم، ایک تیسرا آپشن بھی ہے، اور یہ اتنا مختلف ہے کہ اسے صحیح وقت پر منتخب کرنا آپ کے کوڈ کو نمایاں طور پر واضح بنا سکتا ہے۔ do-while لوپ پہلے اپنے بلاک کے اندر موجود کوڈ کو چلا کر دیکھتا ہے، اور پھر چیک کرتا ہے کہ آیا اسے دوبارہ چلنا چاہیے یا نہیں۔
do-while لوپ کو کیا چیز مختلف بناتی ہے
ایک معیاری while لوپ میں، PHP بلاک میں داخل ہونے سے پہلے ہی شرط کا جائزہ لیتا ہے۔ اگر شرط شروع میں ہی غلط (false) ہو، تو بلاک کو مکمل طور پر چھوڑ دیا جاتا ہے۔ do-while لوپ اس ترتیب کو الٹ دیتا ہے۔ یہ کوڈ کو ایک بار چلاتا ہے، آخر تک پہنچتا ہے، اور صرف تب شرط کو چیک کرتا ہے تاکہ فیصلہ کر سکے کہ آیا لوپ کو واپس دہرانا ہے۔
اس کا سنٹیکس (syntax) ایسا نظر آتا ہے:
do {
// statements
} while ($condition);
while کلاز کے بعد سیمیکولن (semicolon) پر غور کریں۔ وہ سیمیکولن ضروری ہے، اور اسے بھول جانے سے سنٹیکس ایرر (syntax error) آئے گا۔ do اور while کے درمیان والا بلاک ہمیشہ کم از کم ایک بار چلتا ہے، چاہے شرط شروع سے ہی غلط کیوں نہ ہو۔ یہ "post-test" رویہ محض ایک انوکھی بات نہیں ہے؛ بلکہ یہی وہ اصل وجہ ہے جس کی وجہ سے یہ لوپ موجود ہے۔
do-while کا استعمال کب کریں
تین عام صورتحال ہیں جہاں یہ ڈھانچہ بہترین کام کرتا ہے: مینو دکھانا، ان پٹ کی تصدیق کرنا، اور کسی ایسے کام کو دوبارہ کرنے کی کوشش کرنا جو ناکام ہو سکتا ہے۔ ہر صورت میں، لاجک یہ تقاضا کرتی ہے کہ عمل پہلے ہو جائے تاکہ آپ فیصلہ کر سکیں کہ اسے جاری رکھنا ہے یا نہیں۔
مینو دکھانا
ایک کمانڈ لائن ٹول یا ٹیکسٹ پر مبنی ایڈمن پینل کا تصور کریں۔ آپ کو آپشنز کی ایک فہرست پرنٹ کرنے، صارف کے انتخاب کا انتظار کرنے، اور پھر یہ فیصلہ کرنے کی ضرورت ہے کہ آیا مینو دوبارہ دکھانا ہے۔ آپ یہ چیک نہیں کر سکتے کہ صارف نے 'exit' کا انتخاب کیا ہے یا نہیں جب تک مینو اسکرین پر ظاہر نہ ہو جائے۔
$choice = 0;
do {
echo "1. View Reports\n";
echo "2. Export Data\n";
echo "3. Exit\n";
$choice = (int) readline("Select an option: ");
if ($choice === 1) {
// fetch and display reports
} elseif ($choice === 2) {
// run export logic
}
} while ($choice !== 3);
ایک عام while لوپ تکنیکی طور پر اسے سنبھال سکتا ہے، لیکن یہ آپ کو لوپ شروع ہونے سے پہلے مینو کے آؤٹ پٹ کو ایک بار دہرانے پر مجبور کرے گا، یا صرف ابتدائی شرط کو پورا کرنے کے لیے $choice کو کسی فرضی ویلیو کے ساتھ شروع (initialize) کرنا پڑے گا۔ اس سے متعلقہ لاجک دو مختلف جگہوں پر بکھر جاتی ہے۔ do-while ورژن ڈسپلے، ریڈ (read)، اور چیک کو ایک منظم بلاک کے اندر رکھتا ہے۔
ان پٹ کی تصدیق
ان پٹ کی تصدیق اکثر اسی پیٹرن پر عمل کرتی ہے۔ آپ صارف کو پرومپٹ (prompt) دینا چاہتے ہیں، جو انہوں نے دیا اس کا معائنہ کرنا چاہتے ہیں، اور اگر وہ آپ کے اصولوں پر پورا نہ اترے تو اسے دہرانا چاہتے ہیں۔ چونکہ معائنہ سے پہلے پرومپٹ کا ہونا ضروری ہے، اس لیے do-while لوپ قدرتی طور پر یہاں فٹ بیٹھتا ہے۔
do {
$username = readline("Choose a username (min 3 chars): ");
$isValid = strlen($username) >= 3;
if (!$isValid) {
echo "That username is too short.\n";
}
} while (!$isValid);
ایک معیاری while لوپ کے ساتھ، آپ کو $username کو ایک خالی اسٹرنگ کے ساتھ سیٹ کرنا ہوگا اور لوپ سے اوپر پرومپٹ لائن کو ڈپلیکیٹ کرنا ہوگا تاکہ شرط کے پاس جائزہ لینے کے لیے کچھ ہو۔ یہ تکرار بگ (bugs) کا سبب بنتی ہے۔ اگر آپ بعد میں پرومپٹ میسج تبدیل کرتے ہیں، تو ہو سکتا ہے کہ آپ کو لوپ کے اندر اسے ایڈٹ کرنا یاد رہے لیکن اس کے اوپر والی کاپی بھول جائیں۔ do-while کا ڈھانچہ اس خطرے کو ختم کر دیتا ہے کیونکہ یہ اس بات کی ضمانت دیتا ہے کہ کسی بھی شرط کے ٹیسٹ ہونے سے پہلے پرومپٹ بلاک کے اندر چلے گا۔
ناکام شدہ کام کو دوبارہ کرنے کی کوشش کرنا
نیٹ ورک ریکویسٹ، فائل لاک، اور ڈیٹا بیس رائٹس کبھی کبھی پہلی کوشش میں ناکام ہو جاتے ہیں لیکن تھوڑی دیر بعد کامیاب ہو جاتے ہیں۔ آپ عام طور پر کم از کم ایک بار کوشش کرنا چاہتے ہیں، اور پھر صرف تب تک کوشش جاری رکھنا چاہتے ہیں جب تک ناکامی برقرار رہے اور آپ کے پاس صبر باقی ہو۔
$attempts = 0;
$maxRetries = 3;
$success = false;
do {
$attempts++;
$response = @file_get_contents('https://api.example.com/status');
if ($response !== false) {
$success = true;
} elseif ($attempts < $maxRetries) {
sleep(1);
}
} while (!$success && $attempts < $maxRetries);
if (!$success) {
// log the permanent failure
}
یہاں اہم تفصیل یہ ہے کہ ریکویسٹ بھیجی جاتی ہے اس سے پہلے کہ PHP کبھی پوچھے، "کیا یہ کام کر گیا؟" ایک while لوپ کو لوپ میں داخل ہونے سے پہلے ایک ڈمی ریکویسٹ کرنی پڑے گی یا کامیابی کا ایک فرضی فلیگ سیٹ کرنا پڑے گا، جس سے اصل میں کیا ہو رہا ہے وہ چھپ جائے گا۔ do-while ورژن اس ترتیب کو ایماندار بناتا ہے: کوشش کریں، معائنہ کریں، اور فیصلہ کریں۔
do-while اور while کا موازنہ
ان دو لوپس کے درمیان فرق وقت (timing) کا ہے۔ ایک ایسے ویری ایبل پر غور کریں جو ایسی حالت میں شروع ہوتا ہے جو کسی بھی ٹیسٹ میں ناکام ہو جائے گا:
$x = 10;
while ($x < 5) {
echo $x; // Never runs
}
اسی ابتدائی ویلیو کے مقابلے میں، do-while لوپ اس طرح کام کرتا ہے:
$x = 10;
do {
echo $x; // Runs once, outputs 10
} while ($x < 5);
وہ واحد یقینی ایگزیکیوشن ہی فیصلہ کن عنصر ہے۔ اگر آپ کی لاجک کو صفر یا اس سے زیادہ بار دہرانے (iterations) کی ضرورت ہے، تو while ایک محفوظ ٹول ہے۔ اگر آپ کی لاجک کو ایک یا اس سے زیادہ بار دہرانے کی ضرورت ہے، تو do-while عام طور پر ایک بہتر اور صاف ستھرا ٹول ہے۔
خطرات اور بہترین طریقے
چونکہ do-while لوپ کم از کم ایک بار ایگزیکیوشن (execution) کی ضمانت دیتا ہے، اس لیے اگر آپ محتاط نہ ہوں تو یہ ایک انفینٹ لوپ (infinite loop) کا باعث بھی بن سکتا ہے۔ اگر کنڈیشن میں چیک کیے جانے والے ویری ایبلز بلاک کے اندر کبھی تبدیل نہ ہوں، تو PHP ہمیشہ کے لیے چلتا رہے گا یا جب تک کہ یہ زیادہ سے زیادہ ایگزیکیوشن ٹائم (maximum execution time) تک نہ پہنچ جائے۔
ایک اور عام غلطی آخر میں سیمیکولن (semicolon) لگانا بھول جانا ہے۔ درج ذیل کوڈ فیل ہو جائے گا:
do {
// code
} while ($x < 5) // syntax error
آپ کو عادت کے تحت do-while کا استعمال کرنے سے بھی گریز کرنا چاہیے جب کوئی دوسرا لوپ زیادہ واضح ہو۔ اگر آپ کسی ایرے (array) پر پیمائش (iterate) کر رہے ہیں، تو foreach تقریباً ہمیشہ بہتر ہوتا ہے۔ اگر آپ ایک سادہ عددی کاؤنٹر (numeric counter) کا انتظام کر رہے ہیں، تو for لوپ انیشلائزیشن (initialization)، کنڈیشن اور انکریمنٹ (increment) کو ایک ہی لائن میں رکھتا ہے، جسے دیکھنا اور سمجھنا آسان ہوتا ہے۔
کارکردگی (performance) کے لحاظ سے، PHP میں while کے مقابلے میں do-while کا کوئی خاص اضافی بوجھ (overhead) نہیں ہے۔ اس کا فائدہ مکمل طور پر ساختی (structural) ہے۔ جب کوئی دوسرا ڈویلپر do-while لوپ دیکھتا ہے، تو وہ فوراً سمجھ جاتا ہے کہ کسی بھی کنڈیشن کے جائزہ لینے سے پہلے بلاک کا چلنا ضروری ہے۔ معلومات کا یہ ایک چھوٹا سا حصہ انہیں اسٹینڈرڈ while لوپ کے اوپر ڈمی ویری ایبلز یا ڈپلیکیٹ سیٹ اپ کوڈ کو ٹریس کرنے سے بچاتا ہے۔
ایج کیسز (Edge Cases) اور متبادل پیٹرنز
بعض اوقات do-while لوپ تب بھی مفید ہوتا ہے جب صارف کی کوئی مداخلت (user interaction) شامل نہ ہو۔ مثال کے طور پر، جب کسی جنریٹر (generator) یا کرسر (cursor) کا استعمال کیا جا رہا ہو جو کم از کم ایک آئٹم فراہم کرتا ہے، تو آپ پہلے آئٹم کو پروسیس کر سکتے ہیں اور پھر چیک کر سکتے ہیں کہ آیا کرسر اگلے درست مقام پر پہنچ گیا ہے۔ لیگیسی کوڈ بیسز (legacy codebases) میں جو جدید رزلٹ سیٹس کے بجائے خام ڈیٹا بیس ریسورسز (raw database resources) استعمال کرتے ہیں، وہاں آپ کو اس طرح کا پیٹرن نظر آ سکتا ہے:
$row = $result->fetch();
do {
// process $row
} while ($row = $result->fetch());
اگرچہ جدید PHP میں PDO کے ساتھ foreach کو ترجیح دی جاتی ہے، لیکن یہ پیٹرن ظاہر کرتا ہے کہ کس طرح do-while اضافی برانچنگ (branching) کے بغیر پہلی ایٹریشن (iteration) کو ایک خصوصی کیس کے طور پر سنبھالتا ہے۔
اصل خلاصہ
do-while لوپ ایک محدود استعمال والا ٹول ہے، لیکن صحیح جگہ پر یہ واحد ٹول ہے جو منطقی طور پر درست ہے۔ یہ آپ کے سیٹ اپ اور ویلیڈیشن لاجک کو ایک ہی جگہ رکھتا ہے، اس بات کی ضمانت دیتا ہے کہ کسی عمل کا فیصلہ کرنے سے پہلے اسے کرنے کی کوشش کی جائے، اور آپ کے مقصد کو کوڈ پڑھنے والے اگلے شخص تک براہ راست پہنچاتا ہے۔ جب کنڈیشن کام مکمل ہونے کے بعد آنا ضروری ہو، تو do-while استعمال کریں۔ باقی تمام صورتوں میں، سادہ while، for یا foreach کو کام کرنے دیں۔
