2010-12-16 54 views
1

編輯:
問題通過在函數調用中使用$ i + 1解決。PHP:多個foreach中的變量範圍

我無法在多個foreaches中使用變量。當我嘗試在foreach中調用一個函數時,問題就出現了。每當我這樣做時,主循環的迭代器值突然變爲零(無論它在哪一圈),但是當我註釋掉函數調用時,迭代器值會再次顯示。

可能有人點我的方向是正確的,在下面的例子中變量的訪問:

這工作,因爲它不宜

for($i=0; $i<3; $i++) 
{ 
    echo $i; // 1, 2, 3 
    foreach($something as $value) 
    { 
     echo $i; // main loop's iterator value 
     foreach($value as $moreSomething) 
     { 
      echo $i; // main loop's iterator value 
     } 
    } 
} 

但是,這並不工作,迭代器顯示爲0。

for($i=0; $i<3; $i++) 
{ 
    echo $i; // 1, 2, 3 
    foreach($something as $value) 
    { 
     echo $i; // 0 
     foreach($value as $moreSomething) 
     { 
      echo $i; // 0 
      $object->addStuff($i, $moreSomething); // i = 0, moreSomething is correct 
     } 
    } 
} 

編輯: 我添加示例代碼來重現問題。請注意,這是關於$ i值的行爲,而不是名稱的正確順序或類似的。 我只關心爲什麼$ i的價值突然變化。可能是我的邏輯,但看到自己

(在addName(使用$ i或$ B時)函數$ I的輸出爲000000000012,使用$一則$ I的輸出突然改變爲00000000001111111222時)

class RockPaperScissors 
{ 
    private $nameArray; 

    // constructor 
    function RockPaperScissors() 
    { 
    $this->nameArray = array(); 
    } 

    function addName($level, $name) 
    { 
    $this->nameArray[$level][] = $name; 
    } 

    function getNames($level) 
    { 
    $array = array(); 
    foreach ($this->nameArray as $key => $value) 
    { 
     if ($key == $level) 
     { 
      foreach ($value as $name) 
      { 
       $array[] = $name; 
      } 
     } 
    } 
    return $array; 
    } 

    function printArray() 
    { 
    print_r($this->nameArray); 
    } 
} 

function getNewNames($name) 
{ 
    $array = array(); 
    switch ($name) 
    { 
     case "Mickey": 
      $array[] = "Morty"; 
      $array[] = "Ferdie"; 
      break; 

     case "Donald": 
      $array[] = "Houie"; 
      $array[] = "Dewey"; 
      $array[] = "Louie"; 
      break; 

     case "Goofy": 
      $array[] = "Gilbert"; 
      break; 

     case "Morty": 
      $array[] = "Morty-B"; 
      break; 

     case "Ferdie": 
      $array[] = "Ferdie-B"; 
      break; 

     case "Houie": 
      $array[] = "Houie-B"; 
      break; 

     case "Dewey": 
      $array[] = "Dewey-B"; 
      break; 

     case "Louie": 
      $array[] = "Louie-B"; 
      break; 

     case "Gilbert": 
      $array[] = "Gilbert-B"; 
      break; 
    } 

    return $array; 
} 

$MAX_LEVELS = 3; 
$RPS = new RockPaperScissors(); 
$RPS->addName(0, "Mickey"); 
$RPS->addName(0, "Donald"); 
$RPS->addName(0, "Goofy"); 

$a = 0; 
$b = 0; 
for ($i=0; $i<$MAX_LEVELS; $i++) 
{ 
    $namesFromRPS = $RPS->getNames($i); 
    echo $i; 
    foreach($namesFromRPS as $name) 
    { 
     echo $i; 
     $newNames = getNewNames($name); 
     foreach($newNames as $newName) 
     {   
      echo $i; 
      // try switching $i to $a or $b and notice the behaviour change of $i 
      $RPS->addName($i, $newName); 
     } 
     $a++; 
    } 
    $b++; 
} 

//$RPS->printArray(); 
+0

所以,你得到的'1,2,3,0,0'輸出?那會很奇怪,很難相信。 – 2010-12-16 10:37:41

+0

您有效地爲每個'$ moreSomehting'調用'$ object-> addStuff($ i,$ moreSomething);'三次,每次使用不同的'$ i'。也許你的邏輯錯了。你想實現什麼? – 2010-12-16 10:47:25

+0

你能展示一下'addStuff'在做什麼嗎? – 2010-12-16 11:02:32

回答

5

foreach循環沒有自己的範圍。

這種預期的工作方式是:

Set $i to 0 
Enter the first foreach loop with `$i = 0` 
    Enter the second foreach loop with `$i = 0` 

Set $i to 1 
Enter the first foreach loop with `$i = 1` 
    Enter the second foreach loop with `$i = 1` 

etc. 

我敢打賭啤酒的循環工作,符合市場預期,但並沒有什麼的內部循環時做$i達到1

+0

哦,這可能是真的 – Seerumi 2010-12-16 12:33:41

+0

我的頭仍然有點模糊所有的循環旋轉,但我'我相當肯定這是事實。感謝:P – Seerumi 2010-12-16 12:47:04

+0

指向foreach的+1沒有自己的範圍。 – 2013-07-16 16:06:57

0

我不確定,但它可能與$ifor()循環內定義的事實有關。我想在定義for()循環之前嘗試定義$i

詹姆斯

+0

沒有,這將不起作用。 $ i在for循環中定義,這已經足夠了 – 2010-12-16 10:52:41

+0

這沒有幫助。我試過使用$ a = 0;在基礎for循環之前,++在基礎循環結束時++,但它也顯示爲0 – Seerumi 2010-12-16 10:57:38

0

在你的第二個例子中,$i爲0,用於基本循環的第一次迭代。

對於所有的$something s和所有$value s它將保持爲0,然後它將轉到下一個基本迭代,將$i設置爲1等等......

+0

是的,這是它應該做的,但無論基循環的迭代是什麼,它都會保持爲0。當基本迭代的計數變爲1時,在foreach中的迭代器仍然保持爲0,這就是問題所在。這隻會在我嘗試在函數中使用它時發生。 – Seerumi 2010-12-16 10:55:51

0

我加入您的變量$something作爲一個二維數組

$something = Array(1 => Array(1 => "1", 2 => "2"), 2 => Array(3 => "3", 4 => "4"))

利用這一點,您的foreach顯示就好了:

000000011111112222222 
1

不是一個真正的答案,但你的代碼實際上是相同的作爲:

foreach($something as $value) 
{ 
    foreach($value as $moreSomething) 
    { 
     for($i=0; $i<3; $i++) 
     { 
      $object->addStuff($i, $moreSomething); // i = 0, moreSomething is correct 
     } 
    } 
} 

你確定這個邏輯 是正確的?您想做什麼?不知道addStuff正在做什麼,將三個相同的值與另一個索引相加可能有點奇怪。

這裏是一個方法調用的例子:

$something = array(array(1,2), array(1,2)); 

class F { 
    public function b($i, $value) { 
     echo 'In function: i: ' . $i . ' value: ' . $value . PHP_EOL; 
    } 
} 

$f = new F(); 

for($i=0; $i<3; $i++) 
{ 
    echo "in for: " . $i . PHP_EOL; // 1, 2, 3 
    foreach($something as $value) 
    { 
     echo "in 1. foreach: " . $i . PHP_EOL; 
     foreach($value as $moreSomething) 
     { 
      echo "in 2. foreach: " . $i . PHP_EOL; 
      $f->b($i, $moreSomething); 

     } 
    } 
} 

其打印(如預期):

in for: 0 
in 1. foreach: 0 
in 2. foreach: 0 
In function: i: 0 value: 1 
in 2. foreach: 0 
In function: i: 0 value: 2 
in 1. foreach: 0 
in 2. foreach: 0 
In function: i: 0 value: 1 
in 2. foreach: 0 
In function: i: 0 value: 2 
in for: 1 
in 1. foreach: 1 
in 2. foreach: 1 
In function: i: 1 value: 1 
in 2. foreach: 1 
In function: i: 1 value: 2 
in 1. foreach: 1 
in 2. foreach: 1 
In function: i: 1 value: 1 
in 2. foreach: 1 
In function: i: 1 value: 2 
in for: 2 
in 1. foreach: 2 
in 2. foreach: 2 
In function: i: 2 value: 1 
in 2. foreach: 2 
In function: i: 2 value: 2 
in 1. foreach: 2 
in 2. foreach: 2 
In function: i: 2 value: 1 
in 2. foreach: 2 
In function: i: 2 value: 2 

所以錯誤一定在別的地方

0
<?php 

$something = array(
    "one" => array("oneMore1", "oneMore2", "oneMore3"), 
    "two" => array("twoMore1", "twoMore2", "twoMore3"), 
    "three" => array("thrMore1", "thrMore2", "thrMore3")); 

for($i = 0; $i < 3; $i++) 
{ 
    echo "FIRST LOOP: " . $i; 
    echo "\n"; 
    foreach($something as $value) 
    { 
     echo "SECOND LOOP: " . $i; 
     echo "\n"; 
     foreach($value as $moreSomething) 
     { 
      echo "THIRD LOOP: " . $i; 
      echo "\n"; 
      //$object->addStuff($i, $moreSomething); 
     } 
    } 
} 

我看到這裏沒問題執行此代碼:http://www.ideone.com/HsVDj