الفرق بين المراجعتين لصفحة: «PHP/foreach»

من موسوعة حسوب
< PHP
لا ملخص تعديل
 
ط نقل عبد اللطيف ايمش صفحة PHP/Control Structures/foreach إلى PHP/foreach: إعادة هيكلة التوثيق
 
(4 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة)
سطر 17: سطر 17:
تتيح الصيغة الثانية إجراء عملية إسناد إضافية وهي إسناد مفتاح العنصر الحالي إلى المتغير <code>‎$key</code> في كل دورة.
تتيح الصيغة الثانية إجراء عملية إسناد إضافية وهي إسناد مفتاح العنصر الحالي إلى المتغير <code>‎$key</code> في كل دورة.


تتيح PHP تخصيص [[PHP/OOP/iterations|دورات الكائنات]].
تتيح PHP تخصيص [[PHP/object iteration|دورات الكائنات]].


ملاحظة: في PHP 5 يعاد تعيين مؤشر المصفوفة تلقائيًا إلى العنصر الأول في المصفوفة عند بدء تنفيذ عبارة <code>foreach</code>، وهذا يعني عدم الحاجة إلى استدعاء الدالة <code>[[PHP/Function/reset|reset()‎]]</code> قبل حلقة <code>foreach</code>.
ملاحظة: في PHP 5 يعاد تعيين مؤشر المصفوفة تلقائيًا إلى العنصر الأول في المصفوفة عند بدء تنفيذ عبارة <code>foreach</code>، وهذا يعني عدم الحاجة إلى استدعاء الدالة <code>[[PHP/reset|reset()‎]]</code> قبل حلقة <code>foreach</code>.


تعتمد حلقة <code>foreach</code> في عملها على المؤشر الداخلي للمصفوفة في PHP 5، ويؤدي تغيير هذا المؤشر داخل الحلقة إلى نتائج غير متوقعة، أما في PHP 7 فلا تعتمد <code>foreach</code> على المؤشر الداخلي للمصفوفة.
تعتمد حلقة <code>foreach</code> في عملها على المؤشر الداخلي للمصفوفة في PHP 5، ويؤدي تغيير هذا المؤشر داخل الحلقة إلى نتائج غير متوقعة، أما في PHP 7 فلا تعتمد <code>foreach</code> على المؤشر الداخلي للمصفوفة.
سطر 38: سطر 38:
</syntaxhighlight>
</syntaxhighlight>


تحذير: تبقى العلاقة المرجعية قائمة بين المتغير <code>‎$value</code> وبين العنصر الأخير في المصفوفة حتى بعد الخروج من حلقة <code>foreach</code>، لذا ينصح بإلغاء هذه العلاقة باستخدام الدالة <code>[[PHP/Function/unset|unset()‎]]</code>، وإلا فإنك ستواجه الحالة الموضحة في المثال التالي.
تحذير: تبقى العلاقة المرجعية قائمة بين المتغير <code>‎$value</code> وبين العنصر الأخير في المصفوفة حتى بعد الخروج من حلقة <code>foreach</code>، لذا ينصح بإلغاء هذه العلاقة باستخدام الدالة <code>[[PHP/unset|unset()‎]]</code>، وإلا فإنك ستواجه الحالة الموضحة في المثال التالي.


بعد اكتمال حلقة <code>foreach</code> الأولى تأخذ عناصر المصفوفة القيم (2، 4، 6، 8) وتبقى العلاقة بين المتغير <code>‎$value</code> والعنصر الأخير في المصفوفة قائمة ما لم تقطع بواسطة الدالة <code>[[PHP/Function/unset|unset()]]</code>‎.
بعد اكتمال حلقة <code>foreach</code> الأولى تأخذ عناصر المصفوفة القيم (2، 4، 6، 8) وتبقى العلاقة بين المتغير <code>‎$value</code> والعنصر الأخير في المصفوفة قائمة ما لم تقطع بواسطة الدالة <code>[[PHP/unset|unset()]]</code>‎.


في حلقة <code>foreach</code> الثانية ستُحدّث قيمة العنصر <code>‎$arr[3]</code>‎ إلى القيم المأخوذة من المصفوفة <code>‎$arr</code>، وفي النهاية تُنسخ قيمة العنصر ما قبل الأخير إلى القيمة الأخيرة:
في حلقة <code>foreach</code> الثانية ستُحدّث قيمة العنصر <code>‎$arr[3]</code>‎ إلى القيم المأخوذة من المصفوفة <code>‎$arr</code>، وفي النهاية تُنسخ قيمة العنصر ما قبل الأخير إلى القيمة الأخيرة:
سطر 75: سطر 75:
</syntaxhighlight>
</syntaxhighlight>


ملاحظة: لا تدعم <code>foreach</code> القابلية على تجاوز رسائل الخطأ باستخدام [[PHP/Operators/errorcontrol|العامل]] '<code>@</code>'.
ملاحظة: لا تدعم <code>foreach</code> القابلية على تجاوز رسائل الخطأ باستخدام [[PHP/errorcontrol operators|العامل]] '<code>@</code>'.


لربما لاحظت أن الشيفرتين التاليتين متطابقتان تمامًا من الناحية العملية:
لربما لاحظت أن الشيفرتين التاليتين متطابقتان تمامًا من الناحية العملية:
سطر 173: سطر 173:
(PHP 5 >= 5.5.0, PHP 7)
(PHP 5 >= 5.5.0, PHP 7)


أتاح الإصدار 5.5 من اللغة التنقل عبر مصفوفة من المصفوفات وتفكيك المصفوفات المتداخلة إلى متغيرات في الحلقة وذلك باستخدام الدالة <code>[[PHP/Function/list|list()]]</code>‎ كقيمة في الحلقة، فعلى سبيل المثال:
أتاح الإصدار 5.5 من اللغة التنقل عبر مصفوفة من المصفوفات وتفكيك المصفوفات المتداخلة إلى متغيرات في الحلقة وذلك باستخدام الدالة <code>[[PHP/list|list()]]</code>‎ كقيمة في الحلقة، فعلى سبيل المثال:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">


سطر 256: سطر 256:
|-
|-
|5.5.0
|5.5.0
|دعم تفكيك المصفوفات المتداخلة باستخدام الدالة <code>[[PHP/Function/list|list()‎]]</code>.
|دعم تفكيك المصفوفات المتداخلة باستخدام الدالة <code>[[PHP/list|list()‎]]</code>.
|}
|}


== مصادر ==
== مصادر ==
* [http://php.net/manual/en/control-structures.foreach.php صفحة foreach في توثيق PHP الرسمي.]
* [http://php.net/manual/en/control-structures.foreach.php صفحة foreach في توثيق PHP الرسمي.]
[[تصنيف:PHP]]
[[تصنيف:PHP|{{SUBPAGENAME}}]]
[[تصنيف:PHP Control Structures]]
[[تصنيف:PHP Control Structures|{{SUBPAGENAME}}]]

المراجعة الحالية بتاريخ 03:49، 4 أبريل 2018

(PHP 4, PHP 5, PHP 7)

تقدّم بنية foreach طريقة سهلة للتنقل بين عناصر المصفوفات، وتعمل هذه البنية مع المصفوفات والكائنات فقط، ويؤدي استخدامها مع متغير ذي نوع بيانات مختلف أو متغير غير مهيئ إلى إطلاق خطأ.

لهذه البنية صيغتان:

foreach (array_expression as $value)
    statement
foreach (array_expression as $key => $value)
    statement

تنتقل الصيغة الأولى عبر المصفوفة بحسب التعبير المقدّم إليها (array_expression). وفي كل دورة تسند اللغة قيمة العنصر الحالي إلى المتغير ‎$value ويتقدّم المؤشر الداخلي للمصفوفة إلى الأمام خطوة واحدة (أي أنك ستنظر إلى العنصر التالي في الدورة التالية).

تتيح الصيغة الثانية إجراء عملية إسناد إضافية وهي إسناد مفتاح العنصر الحالي إلى المتغير ‎$key في كل دورة.

تتيح PHP تخصيص دورات الكائنات.

ملاحظة: في PHP 5 يعاد تعيين مؤشر المصفوفة تلقائيًا إلى العنصر الأول في المصفوفة عند بدء تنفيذ عبارة foreach، وهذا يعني عدم الحاجة إلى استدعاء الدالة reset()‎ قبل حلقة foreach.

تعتمد حلقة foreach في عملها على المؤشر الداخلي للمصفوفة في PHP 5، ويؤدي تغيير هذا المؤشر داخل الحلقة إلى نتائج غير متوقعة، أما في PHP 7 فلا تعتمد foreach على المؤشر الداخلي للمصفوفة.

لإجراء التعديلات مباشرة على عناصر المصفوفة داخل الحلقة يمكن إلحاق العلامة & باسم المتغير، وهكذا تُسند القيمة إلى المتغير بالمرجعية.

<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value);
// إلغاء الإشارة مع العنصر الأخير
?>

تحذير: تبقى العلاقة المرجعية قائمة بين المتغير ‎$value وبين العنصر الأخير في المصفوفة حتى بعد الخروج من حلقة foreach، لذا ينصح بإلغاء هذه العلاقة باستخدام الدالة unset()‎، وإلا فإنك ستواجه الحالة الموضحة في المثال التالي.

بعد اكتمال حلقة foreach الأولى تأخذ عناصر المصفوفة القيم (2، 4، 6، 8) وتبقى العلاقة بين المتغير ‎$value والعنصر الأخير في المصفوفة قائمة ما لم تقطع بواسطة الدالة unset()‎.

في حلقة foreach الثانية ستُحدّث قيمة العنصر ‎$arr[3]‎ إلى القيم المأخوذة من المصفوفة ‎$arr، وفي النهاية تُنسخ قيمة العنصر ما قبل الأخير إلى القيمة الأخيرة:

<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}

foreach ($arr as $key => $value) {
    // $arr[3] ستُحدَّث قيمة من المتغير $arr
    echo "{$key} => {$value} ";
    print_r($arr);
}

// المخرجات
// 0 => 2 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 2 )
// 1 => 4 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 4 )
// 2 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
// 3 => 6 Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
?>

قبل الإصدار 5.5 من PHP كانت الإشارة إلى المتغير ‎$value ممكنة فقط في حال كانت المصفوفة قابلة للإشارة (بمعنى أنّها مسندة إلى متغير). الشيفرة التالية تعمل في الإصدار 5.5.0 من اللغة فقط:

<?php
foreach (array(1, 2, 3, 4) as &$value) {
    $value = $value * 2;
}
?>

ملاحظة: لا تدعم foreach القابلية على تجاوز رسائل الخطأ باستخدام العامل '@'.

لربما لاحظت أن الشيفرتين التاليتين متطابقتان تمامًا من الناحية العملية:

<?php
$arr = array("one", "two", "three");
reset($arr);
while (list(, $value) = each($arr)) {
    echo "Value: $value<br />\n";
}

foreach ($arr as $value) {
    echo "Value: $value<br />\n";
}
?>

الشيفرتان التاليتان متطابقتان أيضًا:

<?php
$arr = array("one", "two", "three");
reset($arr);
while (list($key, $value) = each($arr)) {
    echo "Key: $key; Value: $value<br />\n";
}

foreach ($arr as $key => $value) {
    echo "Key: $key; Value: $value<br />\n";
}
?>

إليك المزيد من الأمثلة لتوضيح طريقة الاستخدام:

<?php
// المثال 1: القيمة فقط

$a = array(1, 2, 3, 17);

foreach ($a as $v) {
    echo "Current value of \$a: $v.\n";
}

// المثال 2: القيمة مع صيغة الوصول اليدوية إلى عناصر المصفوفة لغرض التوضيح

$a = array(1, 2, 3, 17);

$i = 0;
// لغرض التوضيح فقط

foreach ($a as $v) {
    echo "\$a[$i] => $v.\n";
    $i++;
}

// المثال 3: المفتاح والقيمة


$a = array(
    "one" => 1,
    "two" => 2,
    "three" => 3,
    "seventeen" => 17
);

foreach ($a as $k => $v) {
    echo "\$a[$k] => $v.\n";
}

// المثال 4: مصفوفات متعددة الأبعاد

$a = array();
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";

foreach ($a as $v1) {
    foreach ($v1 as $v2) {
        echo "$v2\n";
    }
}

// المثال 5: مصفوفات ديناميكية

foreach (array(1, 2, 3, 4, 5) as $v) {
    echo "$v\n";
}
?>

تفكيك المصفوفات المتداخلة باستخدام الدالة list()‎

(PHP 5 >= 5.5.0, PHP 7)

أتاح الإصدار 5.5 من اللغة التنقل عبر مصفوفة من المصفوفات وتفكيك المصفوفات المتداخلة إلى متغيرات في الحلقة وذلك باستخدام الدالة list()‎ كقيمة في الحلقة، فعلى سبيل المثال:

<?php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a, $b)) {
// يحتوي المتغير الأول العنصر الأول من المصفوفة المتداخلة،
// أما المتغير الثاني فيضم العنصر الثاني.

    echo "A: $a; B: $b\n";
}
?>

تعطي الشيفرة السابقة المخرجات التالية:

A: 1; B: 2
A: 3; B: 4

يمكن تقديم عدد أقل من العناصر في الدالة list()‎ من تلك الموجودة في المصفوفة المتداخلة، وستهمل اللغة بقية القيم في المصفوفة:

<?php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a)) {
    // لاحظ عدم وجود متغير ثانٍ
    echo "$a\n";
}
?>

تعطي الشيفرة السابقة المخرجات التالية:

1
3

سيظهر تنبيه في حال عدم وجود عناصر كافية لملء دالة list()‎:

<?php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a, $b, $c)) {
    echo "A: $a; B: $b; C: $c\n";
}
?>

تكون مخرجات الشيفرة السابقة كالتالي:

Notice: Undefined offset: 2 in example.php on line 7
A: 1; B: 2; C: 

Notice: Undefined offset: 2 in example.php on line 7
A: 3; B: 4; C:

سجل التغييرات

الإصدار الوصف
7.0.0 لا تستخدم foreach المؤشر الداخلي للمصفوفة.
5.5.0 يمكن الإشارة إلى ‎$value في التعابير، أما في السابق فقد كانت المتغيرات وحدها هي المدعومة.
5.5.0 دعم تفكيك المصفوفات المتداخلة باستخدام الدالة list()‎.

مصادر