لماذا تقوم PHP بالكتابة فوقها عندما أتكرر من خلال هذه الصفيف مرتين (بالرجوع إليها ، بالقيمة)
سؤال
إذا قمت بالتكرار من خلال صفيف مرتين ، مرة واحدة بالرجوع إليها ، ثم بالقيمة ، ستقوم PHP بكتابة القيمة الأخيرة في الصفيف إذا استخدمت نفس الاسم المتغير لكل حلقة. من الأفضل توضيح هذا من خلال مثال:
$array = range(1,5);
foreach($array as &$element)
{
$element *= 2;
}
print_r($array);
foreach($array as $element) { }
print_r($array);
انتاج:
صفيف ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )
صفيف ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8 )
لاحظ أنني لا أبحث عن إصلاح ، أتطلع إلى فهم سبب حدوث ذلك. لاحظ أيضًا أنه لا يحدث إذا لم يتم استدعاء الأسماء المتغيرة في كل حلقة $element
, ، لذلك أعتقد أن الأمر يتعلق $element
لا يزال يجري في نطاق ومرجع بعد نهاية الحلقة الأولى.
المحلول
بعد أول عنصر حلقة $ لا يزال إشارة إلى العنصر/القيمة الأخيرة من صفيف $.
يمكنك أن ترى أنه عند استخدام var_dump () بدلاً من print_r ()
array(5) {
[0]=>
int(2)
...
[4]=>
&int(2)
}
لاحظ ذلك & في &int(2)
.
مع الحلقة الثانية ، تقوم بتعيين القيم لعنصر $. ولأنه لا يزال مرجعًا ، يتم تغيير القيمة في الصفيف أيضًا. جربه مع
foreach($array as $element)
{
var_dump($array);
}
كحلقة ثانية وسترى.
لذلك فهو نفس الشيء أو أقل مثل
$array = range(1,5);
$element = &$array[4];
$element = $array[3];
// and $element = $array[4];
echo $array[4];
(فقط مع الحلقات والضرب ... مهلا ، قلت "أكثر أو أقل" ؛-))
نصائح أخرى
هنا شرح من الرجل نفسه:
$y = "some test"; foreach ($myarray as $y) { print "$y\n"; }
هنا
$y
هو إدخال جدول الرموز يشير إلى سلسلة تحتوي على "بعض الاختبار". في التكرار الأول الذي تقوم به بشكل أساسي:$y = $myarray[0]; // Not necessarily 0, just the 1st element
حتى الآن التخزين المرتبط بـ
$y
يكتب من القيمة من القيمة من$myarray
. إذا$y
يرتبط ببعض التخزين الآخر من خلال مرجع ، وسيتم تغيير هذا التخزين.الآن دعنا نقول أنك تفعل هذا:
$myarray = array("Test"); $a = "A string"; $y = &$a; foreach ($myarray as $y) { print "$y\n"; }
هنا
$y
يرتبط بنفس التخزين كما$a
من خلال مرجع لذلك عندما يكون التكرار الأول:$y = $myarray[0];
المكان الوحيد الذي يمكن أن يذهب إليه سلسلة "الاختبار" في التخزين المرتبط بـ
$y
.
هذه هي الطريقة التي ستصلح بها هذه المشكلة:
foreach($array as &$element)
{
$element *= 2;
}
unset($element); #gets rid of the reference and cleans the var for re-use.
foreach($array as $element) { }