0

私は非常に複雑なPHPアプリケーションを持っていますが、XDebugは、PHPを理解できなくなった時点まで問題を追跡するのに役立ちました。私は、うまくいけば関連性のある問題の核心について詳しく説明しようとしています。

クラス階層ModelCore->Model->LMC->MCがあります。LMCには、次のコード行を持つinsert()メソッドがあります。

if($this->createEntry($mKey)) return $this->getEntry($mKey);

このgetEntryメソッドはLMCでも定義されています。

function getEntry($mKey){
   if(array_key_exists($mKey, $this->aItemList) || $this->createEntry($mKey)) return $this->aItemList[$mKey];
   return false;
}

createEntryLMCで抽象的であり、MCで定義されています。

function createEntry($mKey){
   if(array_key_exists($mKey, $this->aItemList) && ($this->aItemList[$mKey] instanceof LCI))
      return false;
   $this->aItemList[$mKey] = new $this->sItemClass($this,$mKey,(!array_key_exists($mKey,$this->aData))? LCI::Appended : LCI::Unread);
   return ($this->aItemList[$mKey] instanceof LCI);
}

LCIは、上記のツリーとは関係のない別のクラスです。sItemClassLCIの適切なサブクラスです。では、何が起こっているのでしょうか。

createEntryタイプLCIの同じキーのエントリがすでにあるfalse場合は、を返すことになっています。$this->aItemListそれ以外の場合は、そのようなエントリを作成します。示されている最初の行を考慮するgetEntryと、そのようなエントリが作成され、適切なタイプである場合にのみ呼び出されます。ただし、その中の条件はエントリを検出せず、エントリを新たに作成できます。これにより、もちろん、配列に2番目のエントリが作成されることはありません。

テストで使用されるキー値は、16を介して生成されfloatvalます。

そこで何が起こっているのか考えはありますか?

4

1 に答える 1

0

John Green のおかげで、データベースのキーを文字列に変更したところ、完全に機能しました。実は、私は別の問題を探していました。MC はモデルであり、ビューへの参照として渡されます。結局のところ、最初に構築されたモデルとビューに保持されている参照の MC->aItemList[16] の LCI インスタンスの値が異なっていました。実際、LCI はデータなしで作成されましたが、これは CTOR では不可能です。しかし、この問題も解消されました。

学んだ教訓:

  • PHP でフロートが等しいかどうかをチェックすることは、通常よりも面倒なようです (これまで見たことがない$a != $a、どこにもありません!)。
  • float を使用する場合、 の結果はarray_key_exists()インデックス アクセスと一致しない可能性があります[]
  • float を配列インデックスとして使用すると、単純な誤関連付けや想像を超える副作用が生じる可能性があります

コードをチェックし、真実を明らかにすることが不可能なものを除外してくれてありがとう。

于 2012-06-29T09:21:08.823 に答える