PHP सर्व्हर साईडवर खूप वेळा करावी लागणारी पुनरावृत्तीची कामे (repetitive work) हाताळते. एका सिंगल रिक्वेस्टमध्ये इमेजने भरलेल्या फोल्डरला स्कॅन करणे, स्टेटस बदलत नाही तोपर्यंत डेटाबेस तपासणे (poll), किंवा जोपर्यंत वापरकर्त्याचे इनपुट तुमच्या नियमात बसत नाही तोपर्यंत विचारणे यांसारखी कामे करावी लागतील. हे सर्व कोडचे ब्लॉक्स कॉपी-पेस्ट करून करणे अत्यंत अस्थिर (brittle) ठरेल आणि ते मेंटेन करणे जवळजवळ अशक्य होईल. लूप्स (Loops) नेमकी हीच समस्या सोडवण्यासाठी अस्तित्वात आहेत. ते लॉजिकला एका पुन्हा वापरण्यायोग्य (reusable) ब्लॉक मध्ये गुंडाळतात, चुका कमी करतात आणि तुमचे ॲप्लिकेशन सुटसुटीत ठेवतात.
बहुतेक PHP डेव्हलपर्सना जेव्हा माहित असते की त्यांना किती वेळा पुनरावृत्ती (iterations) करायची आहे, तेव्हा ते आपोआप for लूप वापरतात, किंवा जेव्हा संख्या एखाद्या डायनॅमिक कंडिशनवर अवलंबून असते, तेव्हा while लूप वापरतात. मात्र, तिसरा पर्याय देखील आहे, आणि तो इतका वेगळा वागतो की योग्य वेळी त्याचा वापर केल्यास तुमचा कोड अधिक स्पष्ट होऊ शकतो. do-while लूप प्रथम त्याच्या ब्लॉक मधील कोड कार्यान्वित करतो आणि त्यानंतर तो पुन्हा चालवायचा की नाही हे तपासतो.
do-while लूप वेगळा काय ठरवतो
एका स्टँडर्ड while लूपमध्ये, PHP ब्लॉक मध्ये प्रवेश करण्यापूर्वीच कंडिशन तपासते. जर कंडिशन सुरुवातीलाच 'false' असेल, तर तो ब्लॉक पूर्णपणे वगळला जातो. do-while लूप ही प्रक्रिया उलट करते. तो कोड एकदा चालवतो, शेवटपर्यंत पोहोचतो आणि त्यानंतरच पुन्हा लूप करायचा की नाही हे ठरवण्यासाठी कंडिशन तपासतो.
सिंटॅक्स (Syntax) असा दिसतो:
do {
// statements
} while ($condition);
while क्लॉज नंतरचा सेमीकोलन (semicolon) लक्षात घ्या. तो सेमीकोलन आवश्यक आहे आणि तो विसरल्यास सिंटॅक्स एरर (syntax error) येईल. do आणि while मधील ब्लॉक नेहमी किमान एक वेळ कार्यान्वित होतो, जरी कंडिशन सुरुवातीपासूनच 'false' असली तरीही. हे '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 ला एखादी बनावट (phony) व्हॅल्यू द्यावी लागेल. यामुळे संबंधित लॉजिक दोन वेगवेगळ्या ठिकाणी विखुरले जाते. do-while आवृत्ती डिस्प्ले, रीड आणि चेक या सर्वांना एका सुटसुटीत ब्लॉक मध्ये ठेवते.
इनपुट व्हॅलिडेट करणे
इनपुट व्हॅलिडेशनमध्ये देखील अनेकदा अशीच पद्धत अवलंबली जाते. तुम्हाला वापरकर्त्याला प्रॉम्प्ट द्यायचा असतो, त्यांनी काय दिले आहे ते तपासायचे असते आणि जर ते तुमच्या नियमात बसले नाही तर पुन्हा प्रक्रिया करायची असते. तपासणी करण्यापूर्वी प्रॉम्प्ट देणे आवश्यक असल्याने, 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 रचना तो धोका दूर करते.
अयशस्वी झालेल्या कामाचा पुन्हा प्रयत्न करणे
नेटवर्क रिक्वेस्ट, फाईल लॉक्स आणि डेटाबेस राइट्स कधीकधी पहिल्या प्रयत्नात अयशस्वी होतात पण त्यानंतर लगेच यशस्वी होतात. तुम्हाला सहसा किमान एकदा प्रयत्न करायचा असतो, आणि त्यानंतर जोपर्यंत त्रुटी (failure) कायम आहे आणि तुमच्याकडे संयम आहे तोपर्यंत प्रयत्न सुरू ठेवायचे असतात.
$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 हे सहसा अधिक सुटसुटीत साधन आहे.
धोके आणि सर्वोत्तम पद्धती (Pitfalls and Best Practices)
do-while लूप किमान एक वेळा कार्यान्वित होण्याची खात्री देते, परंतु जर तुम्ही काळजी घेतली नाही तर ते अनंत लूप (infinite loop) देखील तयार करू शकते. जर ब्लॉकच्या आत अट (condition) मध्ये तपासले जाणारे व्हेरिएबल्स कधीही बदलले नाहीत, तर PHP कायमस्वरूपी किंवा कमाल एक्झिक्यूशन टाइम (maximum execution time) येईपर्यंत चालू राहील.
दुसरी एक सामान्य चूक म्हणजे शेवटी सेमीकोलन (semicolon) विसरणे. खालील उदाहरण अयशस्वी होईल:
do {
// code
} while ($x < 5) // syntax error
जेव्हा दुसरा लूप अधिक स्पष्ट (expressive) असतो, तेव्हा केवळ सवयीपोटी do-while वापरणे टाळावे. जर तुम्ही एखाद्या ॲरेवर (array) इटरेट करत असाल, तर foreach नेहमीच सरस ठरते. जर तुम्ही एखादा साधा न्यूमेरिक काउंटर (numeric counter) मॅनेज करत असाल, तर for लूपमध्ये इनिशियलायझेशन (initialization), अट (condition) आणि इन्क्रिमेंट (increment) एकाच ओळीत राहतात, ज्यामुळे ते वाचणे सोपे जाते.
कामगिरीच्या (performance) दृष्टीने, PHP मध्ये while च्या तुलनेत do-while मध्ये कोणताही अतिरिक्त भार (overhead) नसतो. याचा फायदा पूर्णपणे स्ट्रक्चरल (structural) आहे. जेव्हा दुसरा डेव्हलपर do-while लूप पाहतो, तेव्हा त्यांना लगेच समजते की कोणतीही अट तपासण्यापूर्वी तो ब्लॉक चालणे आवश्यक आहे. ही एक छोटीशी माहिती त्यांना डमी व्हेरिएबल्स शोधण्यापासून किंवा मानक while लूपच्या वर डुप्लिकेट सेटअप कोड तपासण्यापासून वाचवते.
एज केसेस (Edge Cases) आणि पर्यायी पॅटर्न (Alternate Patterns)
कधीकधी युजर इंटरअॅक्शन नसतानाही do-while लूप उपयुक्त ठरते. उदाहरणार्थ, जेव्हा तुम्ही एखादा जनरेटर (generator) किंवा कर्सर (cursor) वापरत असता जो किमान एक आयटम देतो, तेव्हा तुम्ही पहिला आयटम प्रोसेस करू शकता आणि त्यानंतर कर्सर वैध पुढील स्थानावर गेला आहे की नाही हे तपासू शकता. आधुनिक रिझल्ट सेटऐवजी रॉ डेटाबेस रिसोर्सेस (raw database resources) वापरणाऱ्या जुन्या कोडबेसमध्ये (legacy codebases), तुम्हाला असा पॅटर्न पाहायला मिळू शकतो:
$row = $result->fetch();
do {
// process $row
} while ($row = $result->fetch());
जरी आधुनिक PHP मध्ये PDO सोबत foreach ला पसंती दिली जात असली, तरी हा पॅटर्न दर्शवतो की do-while अतिरिक्त ब्रांचिंगशिवाय (branching) पहिल्या इटरेशनला (iteration) एक विशेष केस म्हणून कसे हाताळते.
मुख्य निष्कर्ष (The Real Takeaway)
do-while लूप हे एक मर्यादित साधन आहे, परंतु योग्य ठिकाणी तेच एकमेव साधन ठरते जे तर्कसंगत आहे. हे तुमचे सेटअप आणि व्हॅलिडेशन लॉजिक (validation logic) एकाच ठिकाणी ठेवते, एखादी कृती तपासण्यापूर्वी ती करण्याचा प्रयत्न केला जाईल याची खात्री देते आणि कोड वाचणाऱ्या पुढच्या व्यक्तीला तुमचा हेतू थेट कळवते. जेव्हा काम पूर्ण झाल्यानंतर अट तपासणे आवश्यक असते, तेव्हा do-while वापरा. इतर सर्व प्रकरणांमध्ये, साध्या while, for, किंवा foreach ला काम करू द्या.
