PHP सर्वर साइड पर बहुत सारे दोहराव वाले काम संभालता है। एक सिंगल रिक्वेस्ट को इमेज से भरे फोल्डर को स्कैन करने, स्टेटस बदलने तक डेटाबेस को पोल करने, या जब तक आपके नियम पूरे न हों तब तक यूजर से इनपुट मांगते रहने की आवश्यकता हो सकती है। एक ही कोड ब्लॉक को बार-बार कॉपी और पेस्ट करके ऐसा करना अस्थिर (brittle) होगा और इसे मेंटेन करना लगभग असंभव होगा। लूप्स (Loops) ठीक इसी समस्या को हल करने के लिए होते हैं। वे लॉजिक को एक पुन: प्रयोज्य (reusable) ब्लॉक में लपेट देते हैं, गलतियों को कम करते हैं, और आपके एप्लिकेशन को संक्षिप्त (compact) रखते हैं।
अधिकांश PHP डेवलपर्स स्वाभाविक रूप से for लूप का उपयोग तब करते हैं जब उन्हें पता होता है कि उन्हें कितनी बार (iterations) लूप चलाना है, या while लूप का उपयोग तब करते हैं जब गिनती किसी डायनेमिक कंडीशन पर निर्भर करती है। हालाँकि, एक तीसरा विकल्प भी है, और यह इतना अलग व्यवहार करता है कि सही समय पर इसे चुनने से आपका कोड काफी स्पष्ट हो सकता है। do-while लूप पहले अपने ब्लॉक के अंदर के कोड को चलाता है, और फिर जाँचता है कि क्या इसे दोबारा चलाना चाहिए।
do-while लूप को क्या अलग बनाता है
एक स्टैंडर्ड while लूप में, PHP ब्लॉक में प्रवेश करने से पहले ही कंडीशन (condition) की जाँच करता है। यदि कंडीशन शुरू में ही गलत (false) है, तो ब्लॉक को पूरी तरह से छोड़ दिया जाता है। do-while लूप उस क्रम को उलट देता है। यह कोड को एक बार चलाता है, अंत तक पहुँचता है, और उसके बाद ही यह तय करने के लिए कंडीशन की जाँच करता है कि क्या वापस लूप चलाना है।
इसका सिंटैक्स (syntax) ऐसा दिखता है:
do {
// statements
} while ($condition);
while क्लॉज के बाद सेमीकोलन (semicolon) पर ध्यान दें। वह सेमीकोलन आवश्यक है, और इसे भूलने पर सिंटैक्स एरर (syntax error) आएगा। do और while के बीच का ब्लॉक हमेशा कम से कम एक बार चलता है, भले ही कंडीशन शुरू से ही गलत हो। यह 'पोस्ट-टेस्ट' (post-test) व्यवहार केवल एक विशेषता नहीं है; यही वह मुख्य कारण है जिसके लिए यह लूप मौजूद है।
do-while का उपयोग कब करें
ऐसे तीन सामान्य परिदृश्य (scenarios) हैं जहाँ यह स्ट्रक्चर बेहतरीन काम करता है: मेनू दिखाना, इनपुट को वैलिडेट करना, और किसी ऐसे कार्य को दोबारा प्रयास (retry) करना जो विफल हो सकता है। प्रत्येक मामले में, लॉजिक यह मांग करता है कि आगे बढ़ने का निर्णय लेने से पहले वह क्रिया (action) होनी चाहिए।
मेनू दिखाना
एक कमांड-लाइन टूल या टेक्स्ट-आधारित एडमिन पैनल की कल्पना करें। आपको विकल्पों की एक सूची प्रिंट करनी होगी, यूजर द्वारा एक विकल्प चुनने का इंतज़ार करना होगा, और फिर यह तय करना होगा कि मेनू को दोबारा दिखाना है या नहीं। जब तक मेनू स्क्रीन पर दिखाई न दे, आप यह जाँच नहीं सकते कि यूजर ने '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 वर्ज़न डिस्प्ले, रीड (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 लूप को लूप में प्रवेश करने से पहले एक डमी (dummy) रिक्वेस्ट करनी होगी या एक फर्जी सक्सेस फ्लैग सेट करना होगा, जिससे यह धुंधला हो जाएगा कि वास्तव में क्या हो रहा है। 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);
वह एक बार की गारंटीकृत निष्पादन (execution) ही निर्णायक कारक है। यदि आपके लॉजिक को शून्य या अधिक इटरेशन की आवश्यकता है, तो while एक सुरक्षित टूल है। यदि आपके लॉजिक को एक या अधिक इटरेशन की आवश्यकता है, तो do-while आमतौर पर एक बेहतर (cleaner) टूल है।
कमियाँ और सर्वोत्तम अभ्यास (Pitfalls and Best Practices)
चूंकि do-while लूप कम से कम एक बार निष्पादन (execution) का वादा करता है, इसलिए यदि आप सावधान नहीं हैं, तो यह एक अनंत लूप (infinite loop) भी बन सकता है। यदि ब्लॉक के अंदर कंडीशन में जांची जाने वाली वेरिएबल्स कभी नहीं बदलती हैं, तो PHP तब तक चलता रहेगा जब तक कि यह अधिकतम निष्पादन समय (maximum execution time) तक न पहुँच जाए।
एक अन्य सामान्य गलती अंत में सेमीकोलन (semicolon) छोड़ देना है। निम्नलिखित विफल हो जाएगा:
do {
// code
} while ($x < 5) // syntax error
आपको आदत के कारण do-while का उपयोग करने से बचना चाहिए जब कोई अन्य लूप अधिक स्पष्ट (expressive) हो। यदि आप किसी ऐरे (array) पर इटरेट (iterate) कर रहे हैं, तो foreach लगभग हमेशा बेहतर होता है। यदि आप एक साधारण न्यूमेरिक काउंटर (numeric counter) को मैनेज कर रहे हैं, तो for लूप इनिशियलाइजेशन (initialization), कंडीशन और इंक्रीमेंट को एक ही लाइन में रखता है, जिसे पढ़ना आसान होता है।
प्रदर्शन (performance) के मामले में, PHP में while की तुलना में do-while में कोई महत्वपूर्ण ओवरहेड (overhead) नहीं होता है। इसका लाभ पूरी तरह से संरचनात्मक (structural) है। जब कोई अन्य डेवलपर do-while लूप देखता है, तो वे तुरंत समझ जाते हैं कि किसी भी कंडीशन के मूल्यांकन से पहले ब्लॉक को चलना ही चाहिए। जानकारी का वह एक छोटा सा हिस्सा उन्हें मानक while लूप के ऊपर डमी वेरिएबल्स या डुप्लिकेट सेटअप कोड को ट्रैक करने से बचाता है।
एज केसेस (Edge Cases) और वैकल्पिक पैटर्न
कभी-कभी do-while लूप तब भी उपयोगी होता है जब इसमें कोई यूजर इंटरैक्शन शामिल नहीं होता है। उदाहरण के लिए, जब आप किसी ऐसे जनरेटर (generator) या कर्सर (cursor) का उपयोग कर रहे हों जो कम से कम एक आइटम देता है, तो आप पहले आइटम को प्रोसेस कर सकते हैं और फिर यह जांच सकते हैं कि क्या कर्सर अगली वैध स्थिति (valid next position) पर आगे बढ़ गया है। उन लेगेसी कोडबेस (legacy codebases) में जो आधुनिक रिजल्ट सेट्स (result sets) के बजाय रॉ डेटाबेस रिसोर्सेज (raw database resources) का उपयोग करते हैं, आपको इस तरह का पैटर्न देखने को मिल सकता है:
$row = $result->fetch();
do {
// process $row
} while ($row = $result->fetch());
हालाँकि आधुनिक PHP में PDO के साथ foreach को प्राथमिकता दी जाती है, लेकिन यह पैटर्न दर्शाता है कि कैसे do-while बिना किसी अतिरिक्त ब्रांचिंग (branching) के पहले इटरेशन (iteration) को एक विशेष मामले के रूप में संभालता है।
मुख्य निष्कर्ष (The Real Takeaway)
do-while लूप एक सीमित उपकरण है, लेकिन सही जगह पर यह एकमात्र ऐसा उपकरण है जो तर्कसंगत है। यह आपके सेटअप और वैलिडेशन लॉजिक को एक ही स्थान पर रखता है, यह गारंटी देता है कि किसी कार्य का मूल्यांकन करने से पहले उसे करने का प्रयास किया गया है, और आपके इरादे को कोड पढ़ने वाले अगले व्यक्ति तक सीधे पहुँचाता है। जब कंडीशन को काम पूरा होने के बाद आना चाहिए, तब do-while का उपयोग करें। अन्य सभी मामलों में, सरल while, for, या foreach को ही काम करने दें।
