PHP dizi işaretçi craziness

1 Cevap

Ben bir girdi olarak bir nokta değeri alır ve karşılık ne "Seviye" döndüren bir "GetCurrentLevel" yöntemi oluşturmak için çalışıyorum. Ben bir dizide Seviye => Nokta eşleme depolamak, ama ben bunu bir foreach döngüsü kullandığınızda dizi işaretçi mantıklı hareket değildir. Ben hata ayıklama için echo ifadeleri ekledik. İşte benim sınıf tanımı bulunuyor:

class Levels extends Model
{
    protected $_map = array (
                           'None'   => 0,
                           'Bronze' => 50,
                           'Silver' => 200,
                           'Gold'   => 500
                           );

    public function __construct()
    {
        parent::__construct();
    }


    public function GetCurrentLevel($points)
    {
        foreach ($this->_map as $name => $threshold)
        {
            echo "Level Name: $name<br/>";
            echo "Level Threshold: $threshold<br/>";
            echo "Current Level: " . key($this->_map) . "<br/>";
            echo "Current Threshold: " . current($this->_map) . "<br/>";

            if ($points < $threshold)       /* Threshold is now above the points, so need to go back one level */
            {
                $previousThreshold = prev($this->_map);
                echo "Previous Threshold: $previousThreshold<br/>";
                echo "Final Level: " . key($this->_map) . "<br/>";
                return key($this->_map);
            }

            echo "Go to next level <br/>";

        }
    }
}

Ve burada GetCurrentLevel(60) çağırdığınızda ne görüyorum:

Level Name: None
Level Threshold: 0
Current Level: Bronze // Looks like foreach immediately moves the array pointer
Current Threshold: 50
Go to next level
Level Name: Bronze
Level Threshold: 50
Current Level: Bronze // WTF? Why hasn't the array pointer moved?
Current Threshold: 50
Go to next level
Level Name: Silver
Level Threshold: 200
Current Level: Bronze //* WTF? Why hasn't the array pointer moved? *//
Current Threshold: 50
Previous Threshold: 0
Final Level: None

Ama "Final Düzey" 60 puan, bir bronz madalya için gerekli 50 puan üzerinde olduğu 'Bronz' olabilir, ama bir gümüş madalya için gerekli 200 puan altında olmalıdır.

Uzun yazı için özür dilerim. Yardımlarınız için teşekkürler!

1 Cevap

Sen ilk iki notları okumalısınız foreach documentation page:

Not: foreach ilk çalışmaya başladığında, dizi göstericisi otomatik olarak dizinin ilk elemanı sıfırlanır. Bu bir foreach döngüsünde önce reset () aramak gerekmez anlamına gelir.

Not: Dizi başvurulan olmadıkça, foreach değil dizinin kendisi belirtilen dizinin bir kopyası üzerinde çalışır. foreach dizi işaretçisi üzerinde bazı yan etkileri vardır. Sıfırlayarak olmadan foreach sırasında veya sonrasında dizi işaretçisi güvenmeyin.

Dizi bir referans yapma ben senin sorunu çözmek inanıyorum, ama sadece prev() kullanmak yerine başka bir değişkenin son değeri hatırlamak Muhtemelen daha temiz olacak