Problems getting a new instance of an object with PDO
I'm adding a clearance section to a website and I'm running into an annoying small issue with PDO. I've created a ClearanceItem class to hold information on an individual item. All of the properties of the item are protected and I've created accessors and mutators for them. I've created the class this way for two reason:
- I can verify the properties as they are set. This is important for me as the database is populated on a schedule from Excel files the client maintains. Using the mutators I can verify the information in the excel files is within certain ranges.
- As the site is in both English and French the accessors can format data (such as prices) correctly depending on the language for the view.
I want to be able to loop over a PDO resultset, getting a new instance of my ClearanceItem class automatically for each row. This is easily done by setting the fetch mode or using PDOStatement::fetchObject(). I'm having problems though with the fact that the properties are protected. It seems that when PDO creates a new instance of a class it uses something called Reflection Injection to set the properties. This means the protected properties are set directly by PDO, bypassing the mutators I've created. Because of this properties that should be numbers (and which are set as such by the mutators) are set as strings. Worst of all is that I'm using MySQL GROUP_CONCAT to return info on multiple stores and inventory as a single string, which the mutator开发者_如何学JAVA should then split apart into an array. Because PDO directly sets this property it ends up as a string.
I can easily get over this problem by having a factory method to create a new instance of ClearanceItem from an array returned from a resultset row. This seems like an unnecessary extra step though. Does anyone know if it's possible to have PDO return an instance of a class for each row in a recordset while having it respect property visibility, using the mutators to set the properties?
I just verified, it WILL call the function __set() for each property set.
class test { function __construct() { print "Constructor\n"; var_dump(func_get_args()); } function __get($x) { print "In get\n"; var_dump($x); } function __set($x, $y) { print "In set\n"; var_dump($x); } } $m = getMasterPDODB(); $stm = $m->prepare("SELECT * FROM users"); if( $stm && $stm->execute() ) { while( $cls = $stm->fetchObject("test") ) { var_dump($cls); } }
gave me
Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[6] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[6] Constructor array empty In set string 'id' (length=2) In set string 'active' (length=6) In set string 'email' (length=5) In set string 'passphrase' (length=10) In set string 'details' (length=7) object(test)[5]
And since my details is a json object, i could parse it from there into the fields needed. You can just have it call the mutators that you have created from there. This seems the best way without doing crazy ninja magic.
精彩评论