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" 
  • s means string
  • 15 size of string
  • collateralvalue string value (and if string 15 characters long)

first property (value):

n 
  • n mean null

second property (key):

s:15:"collateralgroup" 
  • s means string
  • 15 size of string
  • collateralgroup string value (and if string 15 characters long)

second property (value):

r:15 
  • r means reference
  • 15 means 15 value. here 15 value property collateralvalue, means if change value of it changes value of collateralgroup property

for more information see: http://www.phpinternalsbook.com/classes_objects/serialization.html


Comments

Popular posts from this blog

python - No exponential form of the z-axis in matplotlib-3D-plots -

php - Best Light server (Linux + Web server + Database) for Raspberry Pi -

c# - "Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types" error when deserializing class -