NotionCommotion Posted December 10, 2018 Share Posted December 10, 2018 I need to set a deep property if it is undefined or NULL such as shown below: function setProperty($value, stdClass $config, $p1, $p2, $p3, $p4) { if(!isset($config->$p1->$p2->$p3->$p4) || is_null($config->$p1->$p2->$p3->$p4)) { $config->$p1->$p2->$p3->$p4=$value; } } $config=json_decode(json_encode(['a'=>['b'=>['c'=>['x'=>null, 'y'=>123]], 'x'=>123],'x'=>['x'=>123], 'x'=>123])); setProperty(321, $config, 'a','b','c','x'); setProperty(321, $config, 'a','b','c','y'); But I wish the function to work regardless of property depth and came up with the following. Recommendations for a cleaner way? Maybe I should be working with arrays and array_merge_recursive()? function setProperty($value, stdClass $config, array $properties) { $property=array_shift($properties); if(!count($properties)){ if(!isset($config->$property) || is_null($config->$property)) { $config->$property=$value; } } else { if(empty($config->$property) || !is_object($config->$property)) { $config->$property=new \stdClass(); } setProperty($value, $config->$property, $properties); } } $config=json_decode(json_encode(['a'=>['b'=>['c'=>['x'=>null, 'y'=>123]], 'x'=>123],'x'=>['x'=>123], 'x'=>123])); setProperty(321, $config, ['a','b','c','x']); setProperty(321, $config, ['a','b','c','y']); Link to comment Share on other sites More sharing options...
ginerjm Posted December 10, 2018 Share Posted December 10, 2018 did you ever consider that having a structure so very deep is possibly a poor design? Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 10, 2018 Author Share Posted December 10, 2018 2 minutes ago, ginerjm said: did you ever consider that having a structure so very deep is possibly a poor design? Thanks ginerjm. Good point, however, it is not my design (the objects are the json objects used to configure Highcharts) and realistically they will only be 3 or 4 deep max . Any recommendations on the best approach? Thanks Link to comment Share on other sites More sharing options...
requinix Posted December 10, 2018 Share Posted December 10, 2018 Something cleaner? isset($config->a->b->c->x) || $config->a->b->c->x = 321; isset($config->a->b->c->y) || $config->a->b->c->y = 321; Remember that isset() also covers the case where the value exists but is null. It's cool to have something that can arbitrarily set properties, but make sure what you have to give up in return is worth it. Here, I don't think you're gaining nearly enough for the sacrifice in readability. Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 10, 2018 Author Share Posted December 10, 2018 It's not the detection which I have an issue with but how to set them. Unlike arrays, I cannot just use $config->a->b->c->x=123 if a, b, or c is not set. Ah yeah, I do remember (now) that isset() unlike array_key_exists() will return false upon null. Thanks Link to comment Share on other sites More sharing options...
requinix Posted December 10, 2018 Share Posted December 10, 2018 Oh, so the problem is that you don't know if ->a, ->b, or ->c are defined. I would deal with the data as an array and not an object, and array_replace_recursive. Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 11, 2018 Author Share Posted December 11, 2018 7 hours ago, requinix said: I would deal with the data as an array and not an object, and array_replace_recursive. I actually tried array_merge_recursive but found it did not meet my needs and ended up writing my own version. Looks like doing so was not needed and array_replace_recursive is the right solutions. Thanks! Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.