ينبغي أولا فهم ما الذي تقوم به الدوال المولدة generators قبل التطرق لـ yield نفسها، فالأولى تقتضي استعمال الأخيرة.
تعد المولدات في PHP تقدم طريقة أسرع وأسهل لإستخدام المكررات Iterators، فبدل السياق التالي لإضافة 100 الى كل عنصر من مصفوفة عددية:
function myFunct($items) {
$result = [];
foreach ($items as $item) {
$result[] = $item + 100;
}
return $result;
}
يتم كتابة صيغة المولد كـ:
function myFunct($items) {
foreach ($items as $item) {
yield $item + 100;
}
}
ففي الأولى:
يتم انشاء مصفوفة جديدة.
نقوم تباعا باستعمال تكرارة foreach بالإضافة الى المصفوفة الجديدة كل عنصر من عناصر المصفوفة القديمة مضافا اليه 100.
وفي الأخير نقوم بإعادة المصفوفة الجديدة كخرج.
أما في الثانية:
فنحن نقوم مباشرة بإضافة الـ 100 الى كل عنصر من عناصر المصفوفة القديمة.
وكل هذا يكون دون الحاجة حتى الى اعادة خرج أو اعادة تعيين مصفوفة جديدة لإعادتها كخرج لاحقا.
و yield هنا هي أساس عمل هاته الدالة المولدة، فهي تعمل بشكل مشابه لـ return سوى أن هاته الأخيرة توقف تنفيذ الشيفرة. و yield تواصل تنفيذها الى القيمة التي ما بعدها. بمعنى: لو استقبلت الدالة المولدة المصفوفة [1,2] فهي لن تعيد 1 وتوقف تنفيذ الشيفرة عند اول تكرارة، بل ستقوم بإعادة تعيين 1 بالقيمة المسندة الى yield وتواصل العملية الى 2 وهكذا.
بجانب فرق السرعة والضغط على الخادم الذي يكون في صالح المولدات لما يكون الأمر متعلق بالمكررات، يختلف العائد في كل من الأولى والثانية قليلا. فعند استدعاء الدالة المولِّدة للمرة الأولى تعيد الدالة كائنًا من الصنف Generator.ولو قمت بتفحص عائد الدالة المولدة سترى ذلك:
function myFunct($items) {
foreach ($items as $item) {
yield $item + 100;
}
}
print_r(myFunct([0 ,1 , 2]));
الخرج:
Generator Object
(
)
في حين ان خرج الدالة العادية الأولى سيكون عاديا:
[100 ,101 , 102]
هذا الكائن المعاد يطبق واجهة المكرر Iterator يمكن الوصول الى قيمها التي تعرف كخصائص كالتالي:
function myFunc($items) {
foreach ($items as $item) {
yield $item + 100;
}
}
foreach(myFunc([1,2,3]) as $i){
echo $i.'/';
}
// => 101/102/103/
قد تحتاج الاستزادة بالتعرف على المولدات في PHP و PHP Object Iteration.