Introduction to PHP Iterators
जैसा की आपको पता है PHP में arrays objects है। आप for each लूप का प्रयोग करते हुए array के सभी elements को print करवाते है। उसी प्रकार आप for each loop में किसी class का object भी पास कर सकते है और उस class को iterate कर सकते है।
<?php
$arr = array(1,2,3);
foreach($arr as $value)
{
echo $value;
}
?>
लेकिन class को for each लूप के द्वारा iterate करने के लिए आपको अपनी class द्वारा Iterator interface को implement करना होगा और Iterator interface के 5 abstract methods की definition अपनी class में provide करनी होगी। ये methods for loop की तरह ही काम करते है। ये methods निचे दिए जा रहे है –
current() – Used to print current value or perform current task. It is same as for loop body.
key() – This function represent the key that will be used to iterate with in class.
next() – This function is same as for loop increment part.
rewind() – This function is same as for loop initialization part.
valid() – This function is same as for loop condition checking.
आइये अब iteration का एक उदाहरण देखते है।
<?php
class myClass implements Iterator //Implementing iterator interface
{
public function myFunction()
{
echo “<b>Welcome</b><br>”;
}
function rewind() //for loop initialization
{
$this ->i=0;
}
function current() //for loop body
{
echo $i = “<b>Hi,</b>”;
$this -> myFunction();
}
function key() //key to iterate i
{
return $this->i;
}
function next() //increment part of for loop
{
$this -> i++;
}
function valid()
{
return $this -> i <= 5;
}
}
$obj = new myClass();
foreach($obj as $value) //for each loop iterating a class
{
echo $value;
}
?>
ये एक बहुत ही simple उदाहरण है यदि आप for each लूप का उपयोग जानते है तो आसानी से इसे समझ सकते है। यह उदाहरण निचे दिया गया output generate करता है।
Introduction to PHP Generators
एक iterator क्रिएट करने के लिए आप को ऐसी class का object create करना पड़ता है जो Iterator interface को implement करती है। लेकिन generator की मदद से आप easily iterator implement कर सकते है। और इसके लिए आपको ना कोई object क्रिएट करने की जरुरत है और ना ही iterator interface को implement करने की जरुरत है। जैसे आप for each लूप द्वारा किसी array पर iterate करते है वैसे ही आप generator function को भी iterate कर सकते है।
Generator में आप ऐसा code लिखते है जो for each loop को यूज़ करता है और आपके डेटा को iterate करता है और इसके लिए generator memory में कोई array भी क्रिएट नहीं करता है। Normal iterator array क्रिएट करता है जो कई बार memory भी exceed कर जाता है और ऐसे iterator generate होने में समय भी बहुत लगता है।
इसके बजाये आप एक generator function लिख सकते है जो एक normal function की तरह ही होता है सिवाय इसके की generator में आप एक से ज्यादा values return कर सकते है। इसके लिए आप yield keyword यूज़ करते है।
जब generator function पहली बार call होता है तो Generator class का object क्रिएट होता है। ये class Iterator interface को implement करती है। इस क्लास का object आप new keyword द्वारा क्रिएट नहीं कर सकते है। ये सिर्फ तब ही क्रिएट होता है जब generator function कॉल किया जाता है। ये class ऐसे methods provide करती है जिनकी मदद से आप generator को manipulate कर सकते है। और इसी क्लास के object की मदद से आप values को return भी करते है।
जैसा की मैने आपको पहले बताया की generator एक simple function होता है जो एक से ज्यादा values return करता है। लेकिन हम इसे value return करना ना कह कर yield (produce, generate ,पैदा ) करना कहते है। इसीलिए इन functions को generator कहा जाता है। Generators जितनी values की आवश्यकता होती है उतनी ही values produce कर सकते है।
जब generator function कॉल होता है तो ये ऐसा object return करता है जिसे iterate किया जा सकता है (किसी लूप के द्वारा )। जब आप इस object को iterate करते है तो PHP उस generator function को call करती है जब उसे किसी value की आवश्यकता होती है। जब generator कोई value yield करता है तो उसकी state save हो जाती है ताकि दुबारा वही से शुरू हो सके। जब yield करने के लिए कोई value नहीं रहती है तो generator function exit हो जाता है।
Generator functions में आप return statement नहीं लिख सकते है। यदि आप ऐसा करते है तो इससे आपके program में error आएगी। Generators को terminate करने के लिए आप एक empty return statement लिखते है।
Yield keyword किसी return statement की तरह ही होता है बजाय इसके की ये value को yield करने के बाद generator function को exit नहीं करता है बल्कि उसे pause कर देता है।
जब आप किसी array को for each loop में डालते है तो loop उस array की सभी values को print (traverse) करता है। ऐसे ही जब आप किसी generator function को किसी for each loop में डालते है तो for each लूप उस function में generate होने वाली सभी values को print करता है।
जब भी आप generator function create करे तो वो function ऐसा होना चाहिए जो अलग अलग values return करे। एक सी values भी return कर सकता है लेकिन इससे कोई फायदा नहीं होगा क्योंकि फिर वह generator ना रह कर loop ही हो जाता है।
Example
आइये अब एक example के द्वारा generators के concept को समझने का प्रयास करते है –
<?php
function myGeneratorFunc()
{
$message = “<h2>This is a generator function.</h2>”;
$message2 = “<h2>Yield can return many values.</h2>”;
yield $message;
yield $message2;
}
$genobj = myGeneratorFunc();
foreach($genobj as $value)
{
echo “$value”;
}
?>
ऊपर दिए गए उदाहरण में एक generator function create किया गया है। यह function yield keyword द्वारा 2 variables return कर रहा है। Function के बाहर generator function को call किया गया है। जैसा की आपको पता है generator function call होने पर एक object return करता है। इसलिए function call statement एक variable को assign किया गया है। बाद में foreach loop द्वारा इस variable को iterate किया गया है जिससे generator function भी iterate होता है। ये उदाहरण निचे दिया गया output generate करता है।