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's 子数组行向下迭代。参考分配。

4

2 回答 2

4

&=bitwise operator(按位“和”并赋值)不是reference operator

将您的代码更改为:

$rulelvl = &$this->ParseRuleMap;    // note the = &
于 2012-08-30T10:43:36.740 回答
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);
}

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

于 2012-08-30T11:10:53.100 回答