Strange behavior update/saving two instances of same model inside foreach

edit: phalcon 1.3.2 ubuntu 12.04.4 php 5.5.16

I have some code like this:

        $matchingCards = $this->getMatches($newCard);
        foreach ($matchingCards as $card) {
            if ($newCard->damage > $card->damage) {
                $newCard->damage -= $card->damage;
                $newCard->save();
                $card->damage = 0;
                $card->save();
            }
            elseif ($newCard->damage < $card->damage) {
                $card->damage -= $newCard->damage;
                $card->save();
                $newCard->damage = 0;
                $newCard->save();
            }
            echo $card->damage;
    }

$newCard has a damage value like 250 and is inserted into the database directly before the above code The the first 3 card-id's is what $this->getMatches($newCard) would return from the db.

card-id damage
1 100
2 100
3 100
4 250

(card-id 4 is the $newCard)

after the foreach is run, the db looks like this:

card-id damage
1 0
2 100
3 100
4 0

(card-id 4 is the $newCard)

The expected value of the cards after the foreach is:

card-id damage
1 0
2 0
3 50
4 0

($newCard->damage = 250 - 100 - 100 - 50)

by replacing the $newCard->save() calls from inside the foreach with a single $newCard->save() call outside the foreach I get the proper values as like in the table above.

Its great that I've solved my own problem but I don't know why or how it happened! Am I missing something obvious here?



18.5k

Do a var_dump() of the damage of both cards at the end of the loop, so we can see what's wrong with it, 'cause your code looks excellent.



901
edited Oct '14

I think I found some interesting things. here are two pastebin's with the newCard first and matchingCards 2nd (remembering matchingCards is a resultset from Cards::find("some parameters which you can find on lines 48-52 in the second paste...")). in the first paste ($newCard), if you look at lines 225-266:

    protected $_initialized =>
        array(2) {
        'aha\models\cards' =>
        ...

        'aha\models\encounters' =>
        class Aha\Models\Encounters#1977 (18) {
        ...
        }
    }
    protected $_sources =>
    array(2) {
      'aha\models\cards' =>
      string(3) "cards"
      'aha\models\encounters' =>
      string(3) "encounters"
    }
    protected $_schemas =>
    NULL
    protected $_behaviors =>
    array(2) {
      'aha\models\cards' =>
      array(1) {
        ...
      }
      'aha\models\encounters' =>
      array(3) {
        ...
      }
    }
    protected $_lastInitialized =>
    class Aha\Models\Encounters#1977 (18) {
     public $id =>
      string(3) "541"
      public $attackerID =>
      string(3) "340"
      public $defenderID =>
      string(3) "343"
      public $dateTimeOccurred =>
      string(19) "2014-10-09 15:43:52"
      public $dateCleared =>
      NULL

I should point out that the code in my original post is incomplete as I create a new 'Encounter' (with ->create()) everytime Cards::remainingDamage is decremented. I should also point out that neither the models nor the database tables themselves have any kind of belongsTo or hasMany relationships defined. I wasn't able to find any information on the internals of Resultset, ie $lastInitialized, $schemas , or $_initialized. Not sure if some kind of weird pointer thing going on



901

Also, I ran a var_dump($matchingCards) with the $newCard->save() outside of the foreach (the one that produces the correct data) and the two dumps are no different



18.5k

It has to be something that triggers when you call save(), but I can't find what.