php - Serialized object coming out with internal value references -
this far strangest thing have seen in php, there surely sort of explanation.
using serialize() storing objects. @ later point, revive them using unserialize().
today discovered problem object has been unserialized. picture scenario:
object__product_bundle object ( [collateralvalue] => [collateralgroup] => ) now imagine $obj instance of object__product_bundle shown above.
when did:
$obj->collateralvalue = 10; and checked object variables, shown:
object__product_bundle object ( [collateralvalue] => 10 [collateralgroup] => 10 ) mindboggling!
i spent hour smashing head against table, didn't make sense. when started using var_dump() on object, before making changes it, saw this:
object(object__product_bundle)#28 (15) { ["collateralvalue"] => &null ["collateralgroup"] => &null } apparently these properties/variables somehow linked. researched &null , found this question told me dealing sort of references.
but how?
my object comes serialized string.
now, taking @ serialized string found this:
s:15:"collateralvalue";n;s:15:"collateralgroup";r:15; what r:15 ?
can issue?
how can problem addressed , come from?
edit
after digging deeper, found culprit.
orientiation:
the objects (as described above) stored property of object, item of shop cart.
class shopcart { public $storage; } $cart->storage[] = new shopcart_item(); class shopcart_item { public $object; } $object products (object__product_*) stored.
upon placing order, aim of being repeated (subscription), entire shopcart stored database blob.
whenever subscription order scheduled, automated task grabs old shopcart , generates new order it.
and here found culprit - added properties (collateralvalue etc.) later during development, there had been stored orders.
now during debugging found php starts creating references, although not understand why.
simply put:
static public function generateorderfromsubscription() { [...] $order = new object__webshop_order(); var_dump($subscription->cart); // <-- no references in here @ $order->cart = serialize($subscription->cart); var_dump($order->cart); // <-- suddenly, here have references } apparantely, use __sleep() each object__product_* - returns variable names (including collateralvalue , on).
the question becomes then: why php create references, when dealing new properties objects asleep structure has changed in meantime?
very confusing!
edit #2
finally hope.
my __sleep() function returned hardcoded array of variable names, there ton of others never wanted store in database. approach apparently led current problem described in question.
i still not know why php creates references variables in objects awoken without having variables @ all, variables being returned in __sleep().
the sensible solution me, seemed to adapt __sleep(). this:
public function __sleep(){ $vars=array( 'dbid', 'title', 'articleid', 'price_per_unit', ); if(isset($this->collateralvalue)) $vars[]='collateralvalue'; if(isset($this->collateralgroup)) $vars[]='collateralgroup'; } this way, __sleep() not return (any of 2 new) variable names (collateralvalue, collateralgroup) not in use in current object.
well let's analyse serialized string:
s:15:"collateralvalue";n;s:15:"collateralgroup";r:15; first property (key):
s:15:"collateralvalue" smeans string15size of stringcollateralvaluestring value (and if string 15 characters long)
first property (value):
n nmean null
second property (key):
s:15:"collateralgroup" smeans string15size of stringcollateralgroupstring value (and if string 15 characters long)
second property (value):
r:15 rmeans reference15means 15 value. here 15 value propertycollateralvalue, means if change value of it changes value ofcollateralgroupproperty
for more information see: http://www.phpinternalsbook.com/classes_objects/serialization.html
Comments
Post a Comment