لماذا تقوم PHP بالكتابة فوقها عندما أتكرر من خلال هذه الصفيف مرتين (بالرجوع إليها ، بالقيمة)

StackOverflow https://stackoverflow.com/questions/2645499

  •  27-09-2019
  •  | 
  •  

سؤال

إذا قمت بالتكرار من خلال صفيف مرتين ، مرة واحدة بالرجوع إليها ، ثم بالقيمة ، ستقوم 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) { }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top