2009-04-22 6 views
2

私はこのように書きMySQLのから得られたデータセットがあります。PHPの "foreach"構造の無視またはバグ?

 
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 

(それは後処理だ、「タイムスタンプは本当に前にタイムスタンプだったが、それはとにかく問題ではありません)

配列を$resultsに保存されている、と私のコードの途中で私はこのような何かされています

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

問題:$a$b ARを両方とも異なっている。最初のものは想定されている配列を示し、2番目の配列は同じcount()ですが、4番目の要素は最後のものと重複しています。私が知る限り、私は参照によって何も渡していないので、$resultsは変更するつもりはありません(ポインタかもしれませんが、内容はありません)。私はMac OS X 10.5.2でPHP 5.2.4を使用しています。

明白な質問:これは何らかの形で意図された動作、バグ、または私はここで何か間違っていますか? (ブーリアン回答ではありません)


編集:ありがとうございます、私は投稿する必要がありますどのくらいの余分なコードを正確にはわからない、私は以前から多くのことをしないDBおよび foreachを使用してタイムスタンプを解析し、欠落した日の新しい配列( $new_days)を作成します。これはすべて正常に動作しています。

このコードは、私が早く投稿したものの後に書きます:

 
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)); 


EDIT 2(array_pluck()は、典型的なDB-ダンプデータセット内の列から配列を生成するために、カスタム関数です) :もう一度、 the full snippet$resultsアレイ $a$bからの出力(コードのコメントでも参照されています)があります。

+0

これは含まれているコードの意図された動作ではありません。 foreachのバグでもありません。 $ a = $ resultsの間に使用している_exact_コードを使用する必要があります。最終的に$ aと$ bを印刷したとき。 – Calvin

+0

私の友人は、奇妙なことに聞こえるかもしれませんが、正確なコードです。私はこのコード($ aと$ b)の変数で表された各点でexit(print_r())を使いました。 – lima

+0

$ new_daysの内容は何ですか、タイムスタンプを解析するためにどのような関数を使用しますか?タイムスタンプをforeachするために使用されるコードを見ることができますか?あなたがその出力を見る前に、あなたが配列に何をするかはどうなりますか?今まで私たちに示してきたこのセクションの後に、配列のプリントを置くことはできますか? – Louis

答えて

3

コードスニペットを調べるとすぐに(すぐにオフィスを出る)、おそらくあなたの(最初の)ループで参照渡しの何かをすることです。値の法線を使用し、すべてを新しい結果配列に格納してみてください。 (起こっている可能性のある謎を取り除く)。また、2番目の$行を2番目のforeachの別の名前にしてみることもできます。私を打ち負かしてください。

も、この行と次のコードブロックは

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

、それとは何かを持っている可能性があり、新たな日がいっぱいにすることはありませんし、マージがファンキーな何かをすることができを実行しません。

が答え、これを呼び出すことはありませんが、私は、私が間違えてる場合を除き、これはPHPのバグはしばらく前だった

+0

ありがとうございましたルー、私はあなたの提案を試し、みんなに知らせるでしょう。しかし、その間に、あなたがハイライトした行は、初めてではありません(これは明らかに無限ループを避けることを目的としています)。これは、$結果の一部となる$ new_days配列を埋める役割を果たします。 – lima

+0

2番目のforeachループのvalue変数の名前を$ rowから$ row2に変更しました。これは完全に機能しました!どうもありがとう、あなたの貢献に感謝します。私はまだこれが本当にEvertの提案のようないくつかのバグの回避策だと思っていますが、誰かがこの状況の内部の仕組みをよりよく理解すれば、私はそれを読むことをうれしく思います。私はbugs.php.netに行き、TPSレポートに記入するのに十分な冒険ではありません。 – lima

+1

これはすでに提出済みでステータスは「Bogus」 - http://bugs.php.net/bug.php?id=29992 – Calvin

0

これは意図された動作であるとは想像できません。ここに何か他のものがなければなりません。あなたはここに投稿するのに十分な大きさのコードに振る舞いを分けることができますか?おそらく、バグが明らかになるでしょう。

0

私はまた何か他のことが起こっていると言います。

私はこれを書いた:

<?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); 

をそして得た:

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

は、私はしかし、PHP 5.2.8を実行しています。

+0

テストをありがとう! – lima

0

私はあなたの問題は、結果セットは実際には配列ではなく、配列のように動作するmysqlの結果セットオブジェクトだと思います。

私はあなたが新しい行にそれを割り当てて、各行を通過し、次にマージを行うと、それは正しく動作すると思います。

+0

私はそれがCodeIgniterの関数result_array()から取り出され、マージ後には正常に見えるので、問題はforeachループの後に発生するとは思いません。 – lima

0

を推測でそのスタートが見えるように。詳細はわかりませんが、配列と参照はちょっと難解です。

+0

これはバグではありません:http://bugs.php.net/bug.php?id=29992 – Calvin

+0

ありがとうございますCalvinを参照してください! – lima

+0

はい、np。その表面には、直観に反する行動がありますが、バグレポートのコメントの最後の3番目は、何が起こっているのかをかなり良く分かります。 – Calvin

2

すでに述べたように、問題は最初のforeachループです。ここで

は推論だ...

<? 
// 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] !!!) 
?> 

私は、これは理にかなって願っています!基本的に、2番目から最後の値は、2番目のループの間に最後の値が置き換えられるため、繰り返されます。

+0

ジョシュさん、ありがとう、それは確かに意味があり、私はそこに起こっていることを理解しています。確かに誤解を招き、正しく文書化された動作ではありません。経験則:参照渡しされた変数(または2回目の使用前に設定解除された変数)に異なる名前を使用する。 – lima

+0

私は正しい答えを得ることができますか? :) –

関連する問題