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参照の割り当て。

4

2 に答える 2

4

&=bitwise operator(ビット単位の「and」と割り当て)ではなく、reference operator

次のようにコードを変更します。

$rulelvl = &$this->ParseRuleMap;    // note the = &
于 2012-08-30T10:43:36.740 に答える
1

単なるコメントであっても、ここに答えとして置くもう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 に答える