2012-08-30 28 views
1

它更容易只是爲了給一個代碼示例:通過引用挖掘數組不工作?

private $ParseRuleMap = array(); 

public function __construct($rules) { 
    foreach($rules as $which=>$rule) { 
     $mapping = $rule->getMinimumMatchables(); 

     foreach($mapping as $match) { 
      $rulelvl &= $this->ParseRuleMap; // Fun begins here 

      $len = strlen($match); 
      for($i=0; $i<$len; $i++) { 
       if(!isset($rulelvl[ $match[$i] ])) { 
        $rulelvl[ $match[$i] ] = array(); 
       } 
       $rulelvl &= $rulelvl[ $match[$i] ]; // Here too! 
      } 

      // ... other code here ... 
     } 
    } 
} 

我收到以下錯誤垃圾郵件經常(爲上述註釋行):

PHP的警告:無法使用標量值作爲數組在線35 parser.php

我的誤解如何參考作品在這裏工作?爲了(嘗試)清楚起見,$rulelvl應該通過給定的$this->ParseRuleMap的子行迭代。引用賦值。

+0

不是解決方法,而是:通過參考? __construct(&$ rules)允許更改規則,因爲你不會返回任何東西 – Waygood

+0

啊!你改變$ this-> ParseRuleMap。爲什麼不用$ this-> ParseRuleMap替換$ rulelvl,而不是一遍又一遍地創建一個引用 – Waygood

回答

4

&=bitwise operator(按位「與」和分配)不是reference operator

更改您的代碼如下:

$rulelvl = &$this->ParseRuleMap; // note the = & 
+0

我討厭我的生活。 * facepalm * – Hamster

+0

我一直在我的代碼中做這件事情;) –

+1

認爲它看起來很奇怪,但你去了。 – Waygood

1

我把這裏作爲一個答案另一個技巧,即使它僅僅是一條評論。

你已經知道你做錯了什麼,但可能不清楚爲什麼。當然你輸錯了一些東西,但只是一個小頭:

1.)你的構造函數做得太多了。把這裏做的事情放到它自己的功能中。

public function __construct($rules) { 
    $this->processRules($rules); 
} 

private function processRules($rules) { 
    foreach ($rules as $which => $rule) { 
     ... 
    } 
} 

這降低了構造的複雜性。此後,您可能已經想要將正確的對象傳遞給構造函數,以便您可以從整個類中移除該預處理。但現在這不是必要的,甚至可能永遠不會變得必要,所以只是給予一些觀點。

2.)處理本身是嵌套和複雜的。將大問題分成較小的部分來降低複雜性。

當然,這是關係到你所需要的,希望下面的代碼提供了一些有用的例子,你如何可以通過拆分跨多個功能降低複雜性:

private function processRules($rules) { 
    foreach ($this->rulesGetMappingsMatches($rules) as $match) { 
     $this->parseRuleMapMatch($this->parseRuleMap, $match); 
    } 
} 

private function parseRuleMapMatch(&$parseRuleMap, $match) { 
    $len = strlen($match); 
    foreach(str_split($match) as $char) { 
     isset($parseRuleMap[$char])) || $parseRuleMap[$char] = array(); 
     $parseRuleMap = &$parseRuleMap[$char]; 
    } 
    ... 
} 

private function rulesGetMappingsMatches($rules) { 
    $matches = array(); 
    foreach ($rules as $rule) { 
     foreach ($rule->getMinimumMatchables() as $match) { 
      $matches[] = $match; 
     } 
    } 
    return $matches; 
} 

3)不要使用引用你不需要它們。

我不知道爲什麼在你的情況下你使用的引用。要獲得更好的變量名稱?那麼它可能會沒事。爲了提高速度?那麼除非你真的知道你在做什麼,否則你不應該這樣做,因爲PHP在優化速度和內存方面非常出色。通常最好有一個函數返回一個值,而不是通過引用傳遞並修改該值。這也有助於代碼重用和調試。

private function processRules($rules) { 
    foreach ($this->rulesGetMappingsMatches($rules) as $match) { 
     $this->parseRuleMap = $this->parseRuleMapMatch($this->parseRuleMap, $match); 
    } 
} 

private function parseRuleMapMatch($parseRuleMap, $match) { 
    ... 
    return $parseRuleMap; 
} 

4)最簡單的解決方案是最常見的解決方案。

嘛,只是一個例子:

public function __construct($rules) { 
    $this->importRulesMapFromArray($rules); 
} 

應該是自我演講。分而治之。也給好名字。在編寫代碼時你會減少錯誤。