通过引用挖掘数组并不是一件容易的事;t工作


Digging into an array by reference isn't working?

只给出一个代码示例更容易:

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的子数组的给定行。参考分配。

&=bitwise operator(按位"and"和assign),而不是reference operator

将您的代码更改为:

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

我在这里提出的另一个建议是作为一个答案,即使它只是一个评论。

你已经知道自己做错了什么,但可能不清楚为什么。当然你打错了什么,但只是提醒一下:

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

应该很会说话。分而治之。也要起好名字。你在编写代码时会犯更少的错误。