Hi,
I am fairly new to Phalcon so I am sure I am doing something wrong, or I have misunderstood somehting, but I have been through the available docs a few times, and I cannot quite figiure out why this is happening.
I am using Phalcon 1.3.4 on PHP 5.5.11 NTS Windows.
I have certain data that I would like to store on my entities that inherit from Model. This data is operational, and not persisted to the database. In this paticular case I noticed what I deemed as odd behaviour when lazy loading an encryption provider from an object based on model. This should be a per instance value, and this works fine on intitial creation of the objects, but after calling ::find() the instance fields behave as if statically cached, so that each subsequent object contains the instance value from the first hydrated object.
I have what I believe to be the most simple example, using an object hash.
Please consider the following simple class based on Model :
/*
* CREATE TABLE `dumbtest` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`someData` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
*/
class Simple extends \Phalcon\Mvc\Model
{
protected $_hash = null;
public function getSource()
{
return 'dumbtest'; //table based on above sql, does not contain hash
}
public function getPerInstanceHash()
{
return $this->_hash;
}
public function onConstruct()
{
$this->_hash = uniqid(true);
}
}
The hash is generated in onConstruct(), and on construction this works fine, each new object of Simple type contains a unique hash.
The trouble comes after calling ->create() and then in the same request calling ::find(). Now onConstruct() is not called, so a caching function is smart enough to recognise these objects, but the $_hash member now appears to behave as a singelton.
Please see following example test to indicate my experience :
class ObjTest extends UnitTestCase
{
public function testORMStatic()
{
$firstObj = new Simple();
$firstObj->someData = 'first object';
$firstObj->save();
$secondObj = new Simple();
$secondObj->someData = 'second object';
$secondObj->save();
//hash should be different per instance
//this test will pass
$this->assertTrue($firstObj->getPerInstanceHash() != $secondObj->getPerInstanceHash(), 'The hash should be different for each instance, it is a GUID generated in onConstruct()');
//now lets fetch the objects through the results set
$objects = Simple::find();
$this->assertTrue($objects->count() == 2); //i.e. no polluting data
$firstObj = $objects[0];
$secondObj = $objects[1];
//this time the test will fail, both hashs are identical
$this->assertTrue($firstObj->getPerInstanceHash() != $secondObj->getPerInstanceHash(), 'The hash should be different for each instance, it is a GUID generated in onConstruct()');
$firstObj->delete();
$secondObj->delete();
}
}
And the output of the tests (with the last test failing) :
Fail: D:\Source\Repos\App\app\tests\other\ObjTest.php -> ObjTest -> testORMStatic -> The hash should be different for each instance, it is a GUID generated in onConstruct() at [D:\Source\Repos\App\app\tests\other\ObjTest.php line 33]
Could someone please help me understand what the caching mechanism here is, and how I can work around this or better acheive storing a non db persisted value in a model per instance.
Many thanks.