We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

phql resultset

I have two tables and Im using phql to join them. The resultset is Phalcon\Mvc\Model\Resultset\Complex

and I am able to set properties using

$resultset->getFirst()->tabone->setVal(2);
echo $resultset->getFirst()->tabone->getVal();

but when i use

$resultset[0]->tabone->setVal(2);
echo $resultset[0]->tabone->getVal(); //remains unchanged

the value remains unchanged, even though

get_class($aRecords[0]->tabone);

says the class is Tabone.

//these are my models
class Tabone extends \Phalcon\Mvc\Model
{
    public $id;
    public $val;
    public function columnMap() {
        return array( 'id' => 'id', 'val' => 'val' );
    }
    public function setVal($val) { $this->val = $val; }
    public function getVal() { return $this->val; }
}
class Tabtwo extends \Phalcon\Mvc\Model
{
    public $id;
    public function columnMap() {
        return array( 'id' => 'id' );
    }
}

these are the tables and values:

CREATE TABLE tabone (
    id INT(11) NOT NULL AUTO_INCREMENT,
    val INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (id)
);
CREATE TABLE tabtwo (
    id INT(11) NOT NULL,
    PRIMARY KEY (id)
);
INSERT INTO tabone (id, val) VALUES (1, 1);
INSERT INTO tabtwo (id) VALUES (1);

this is what i am doing in the controller

        $oBuilder = $this->modelsManager->createBuilder();
        $oBuilder->columns(['Tabone.*', 'Tabtwo.*']);
        $oBuilder->from(['Tabone']);
        $oBuilder->join('Tabtwo', 'Tabone.id = Tabtwo.id');
        $oBuilder->where('Tabone.id = 1');
        $aRecords = $oBuilder->getQuery()->execute();

        //this doesnt work as expected
        $aRecords[0]->tabone->setVal(2);
        echo "2 != ".$aRecords[0]->tabone->getVal()."<br>";

        echo get_class($aRecords[0]->tabone).'<br>';

        //this works as expected
        $aRecords->getFirst()->tabone->setVal(2);
        echo "2 == ".$aRecords->getFirst()->tabone->getVal()."<br>";

Why are the setters/getters no working when using [0] ? am i doing something i shouldn't ? ...



2.7k
Accepted
answer
edited Mar '14

With information found on:

https://forum.phalcon.io/discussion/945/why-properties-of-models-are-lost-

> (...) when a resultset is traversed, only just one record is kept in memory,
> if you modify  a record changes will lost, because the record is freed
> once it is not used anymore.  This scheme is very efficient if you are
> traversing big resultsets (...)

and on https://stackoverflow.com/questions/7425370/scala-what-is-the-difference-between-traversable-and-iterable-traits-in-scala-c

> (...) complying with the Traversable interface does not require keeping state

So, the reason why [0] does not set properties is because traversable means just that, it only traverses the object, any values set directly in the traversed object will be lost, because the object state is not kept.

This makes perfect sense especially when you are talking about large result sets as it will save tons of memory.