PHP'nin "foreach" konulu Cehalet VEYA bug

7 Cevap php

Ben böyle gider MySQL elde edilen bir veri kümesi var:

Array
(
    [0] => Array
        (
            [views] => 14
            [timestamp] => 06/04
            [views_scaled] => 4.9295774647887
            [unix_time] => 1239022177
        )

    [1] => Array
        (
            [views] => 1
            [timestamp] => 19/04
            [views_scaled] => 0.35211267605634
            [unix_time] => 1240194544
        )

        ...
        ...
        ...

) 1

(O sonrası işlenmiş, 'damgası' önce gerçekten bir zaman damgası, ama bu zaten önemli değil)

Dizisi $results saklanan ve benim kod ortasında böyle bir şey yapmaktır:

$results = array_merge($results, $new_days);
$a = $results;
foreach ($results as $row)
{
    $unix_time[] = $row['unix_time'];
}
$b = $results;

The problem: $a ve $b hem de farklıdır. Bu gerekiyordu gibi ilk dizi gösterir ve ikinci bir aynı count() vardır, ama dördüncü unsur geçen biri yineleniyor bulunuyor. Bildiğim kadarıyla, ben referans şey geçirerek değilim, bu yüzden $results değiştirmek anlamına gelmez mi (belki işaretçi, ama içerik değil). Mac OS X 10.5.2 üzerinde PHP 5.2.4 kullanıyorum.

The obvious question: Is this somehow the intended behavior, a bug or I'm doing something wrong here? (not a boolean answer please ;)


EDIT: Thank you all for the interest, I don't know exactly how much extra code should I post, I don't do much before except for retrieving the data from the DB and a foreach to parse the timestamp and build a new array ($new_days) for the missing days. This is all working fine.

Bu kod erken gönderdiniz birinin peşinden gider:

array_multisort($unix_time, SORT_ASC, $results);
$days = implode('|', array_pluck('timestamp', $results));
$views = implode('|',  array_pluck('views', $results));
$views_scaled = implode(',', array_pluck('views_scaled', $results));

(array_pluck() is a custom function to generate an array from a column in a typical DB-dumped dataset)


EDIT 2: Thanks again, here's the full snippet and the output from the $results array $a and $b (also referenced in the code's comments).

7 Cevap

Senin kod parçacığını teftiş, gerçekten hızlı (gün için ofis ayrılmak üzereydim), bu (ilk) döngü referans geçirerek bir şey yapmak muhtemelen. Değere göre normal kullanım ve sadece taze bir sonuç diziye herşeyi kaydetmeyi deneyin. (Devam olabilecek herhangi gizemleri kaldıracaktır). Gerçekten bu daha bakarak size söyleyemem - Ayrıca farklı bir isim .. beni yendi, ikinci foreachta ikinci $ satır yaparak deneyebilirsiniz.

Ayrıca bu hat ve kod aşağıdaki blok yürütmek olmaz

if ($last_day != $day_before_this_one AND $last_day)

onunla ilgisi olabilir, yeni bir gün doldurmak asla ve birleştirme korkak bir şey yapıyor olabilir.

Sanırım bakmak için bir cevap ama onun bir başlangıç ​​bu demezdim

Zaten belirtildiği gibi sorun, ilk foreach döngü.

İşte muhakeme ...

<?
// set up an example array and loop through it using references (&)
$my_array = array(1,2,3,4);
foreach($my_array as &$item)
{
  $item = $item+.1;
}
// 1st loop, $item points to: $my_array[0], which is now 1.1
// 2nd, $item -> $my_array[1], which is now 2.1
// 3rd, $item -> $my_array[2], which is now 3.1
// 4th, $item -> $my_array[3], which is now 4.1
// looping done, but $item is still pointing to $my_array[3]

// next foreach loop
foreach($my_array as $item)
{
  var_dump($my_array);
  print $item."<br>";
}
// notice the & in the output of the var_dump, if you actually run this code.
// 1st loop: the value of $my_array[0] is assigned to $item, which is still a pointer/reference to $my_array[3]
// first loop.. array(1.1,2.1,3.1,1.1) // grabbing [0] and putting into [3] 
// next loop... array(1.1,2.1,3.1,2.1) // grabbing [1] and putting into [3]
// next loop... array(1.1,2.1,3.1,3.1) // grabbing [2] and putting into [3] (here's where the magic happens!)
// last loop... array(1.1,2.1,3.1,3.1) // grabbing [3] and putting into [3] (but [3] is the same as [2] !!!)
?>

Bu mantıklı umut! Son değer ikinci döngü sırasında değiştirilir, çünkü temelde son değere ikinci tekrarlanır.

Ben amaçlanan davranıştır nasıl hayal bile edemiyorum. Burada olacak başka bir şey olmalı. Burada göndermek için yeterince küçük bir kod parçasına davranışı izole miyim? Bunu yaparsanız muhtemelen bug açık olacak.

Ben de oluyor başka bir şey olduğunu söyleyebilirim.

Ben bu yazdı:

<?php

$a = array('bob','sam','tom','harry');
$b = array();
$c = array();

foreach($a as $item) {
        $c[] = $item;
}
$b = $a;

print_r($a);
print_r($b);

Ve var:

php ./test.php
Array
(
    [0] => bob
    [1] => sam
    [2] => tom
    [3] => harry
)
Array
(
    [0] => bob
    [1] => sam
    [2] => tom
    [3] => harry
)

Gerçi, PHP 5.2.8 kullanıyorum.

Ben bir dizi gibi davranan bir mysql resultset bir nesne, senin sorunun sonuç set gerçekten bir dizi değil olduğunu düşünüyorum.

Ben düzgün hareket edeceğiz, taze bir diziye atayarak, her satırda geçmesi halinde, daha sonra birleştirme yapmak düşünüyorum.

Yanılmıyorsam, bu bir süre önce bir PHP hata oldu. Ben ayrıntılarını bilmiyorum, ama diziler ve referanslar biraz için berbat olmuştur.