entheologist Posted August 29, 2014 Share Posted August 29, 2014 (edited) I've been wasting time reinventing the wheel with this one so I'd greatly appreciate if people here could share how they deal with this. So heres an example class: class VarDataClass { private $module = 'show_vars'; public $category = 'DEFAULT CATEGORY'; public $title = 'DEFAULT TITLE'; public $option2 = 'DEFAULT VALUE'; public $show = 'SOMETHING'; public $output = 'box'; public $_settings = array( 'category' => 'DEFAULT CATEGORY', 'title' => 'DEFAULT TITLE', 'option2' => 'DEFAULT VALUE', 'show' => 'SOMETHING', 'output' => 'box' ); public function __constructor($options = array()) { } // some functions } So the $options parameter in the constructor contains all the custom settings for the class instance, lets say in this case they're all optional. Since they're all optional I made that $_settings array have default values. And for this example, I added another way I could do it, by adding the variables individually rather than as part of the settings array. So I'm wondering whats the best way to replace the default values with any values that the user happens to input. Is a list of variables easier, or is the $_settings array the way to go? I think the settings array would be the way to do it, so I'm thinking I should make some option setter function, but whats the easiest way to do that? Should I loop through every key in the settings array, and check if that key is present in the $options variable that the user input? Or is there some kind of array_replace function I can use that will set all the options in one go without having to use a loop? Another issue is its a pain in the ass for the user to input an associative array, its much easier to just to $object = new VarDataClass('CATEGORY','TITLE'); etc. but then the problem is if they only want to set say the two last options, they'd have to do VarDataClass('','','','SHOW','OUTPUT'); Basically I'm just looking for the most evolved way to handle these optional functions so I don't have to reinvent the wheel myself. Edited August 29, 2014 by entheologist Quote Link to comment https://forums.phpfreaks.com/topic/290731-best-way-to-deal-with-optional-parameters-for-classes-and-functions/ Share on other sites More sharing options...
requinix Posted August 29, 2014 Share Posted August 29, 2014 I'd get rid of the individual public variables and use __get/set instead, with an array containing the actual values. Then it's easy: $_settings is the array and you merge the $options into it. /** * @property string $category * @property string $title * @property string $option2 * @property string $show * @property string $output */ class VarDataClass { private $settings = array( 'category' => 'DEFAULT CATEGORY', 'title' => 'DEFAULT TITLE', 'option2' => 'DEFAULT VALUE', 'show' => 'SOMETHING', 'output' => 'box' ); public function __construct(array $options = array()) { // array_intersect_key so only recognized $options get merged in $this->settings = array_merge($this->settings, array_intersect_key($options, $this->settings)); } public function __get($name) { return (isset($this->settings[$name]) ? $this->settings[$name] : null); } public function __set($name, $value) { if (isset($this->settings[$name])) { $this->settings[$name] = $value; } } } Quote Link to comment https://forums.phpfreaks.com/topic/290731-best-way-to-deal-with-optional-parameters-for-classes-and-functions/#findComment-1489288 Share on other sites More sharing options...
entheologist Posted August 29, 2014 Author Share Posted August 29, 2014 Thanks a lot. I'll try out your method. I just found out there is an array_replace function, even an array_replace recursive function which would be perfect would replacing defaults with user input options. This will work perfect for when users input associative arrays, but won't account for numeric arrays. We need to make a universal options settter function/class/trait that will take care of all these possibilities. Quote Link to comment https://forums.phpfreaks.com/topic/290731-best-way-to-deal-with-optional-parameters-for-classes-and-functions/#findComment-1489290 Share on other sites More sharing options...
requinix Posted August 29, 2014 Share Posted August 29, 2014 Numeric arrays don't make sense at the top level. If one of the options was a numeric array then that's different but you'd probably need special merging logic for it specifically. Quote Link to comment https://forums.phpfreaks.com/topic/290731-best-way-to-deal-with-optional-parameters-for-classes-and-functions/#findComment-1489293 Share on other sites More sharing options...
entheologist Posted August 29, 2014 Author Share Posted August 29, 2014 (edited) This is one of the extremely rare cases where something I tried worked first time, but it did: trait optionSetterTrait { private $_diagnose = array(); public function __construct(array $options = array()) { $this->_diagnose['options'] = $options; // show numeric values of each setting $this->_diagnose['settingsKeys'] = array_keys($this->_settings); // array_intersect_key so only recognized $options get merged in $this->_settings = array_merge($this->_settings, array_intersect_key($options, $this->_settings)); $this->_diagnose['settings'] = $this->_settings; } public function __get($name) { return (isset($this->_settings[$name]) ? $this->_settings[$name] : null); } public function __set($name, $value) { if (isset($this->_settings[$name])) { $this->_settings[$name] = $value; } } public function diagnose() { if (empty($subSection) || $subSection == 'all') { } $outputArray = print_r($this->_diagnose,true); $output = "<pre>$outputArray</pre>"; echo $output; } } class linkFinder { private $_settings = array( 'paths' => array('./'), 'extenstions' => array('php','html'), 'category' => 'blah' ); use optionSetterTrait; private function linkGenerator() { $fileList['fullPath'] = glob("./*.php"); } } $test = new linkFinder(array('category' => 'blah')); $test->diagnose(); So from now on in every class I make I can just include that optionSetter trait, that will make life so much easier. Does anyone know of a trait like this been made before? If not I should put it up on github as a gist so people can improve it over time. Edited August 29, 2014 by entheologist Quote Link to comment https://forums.phpfreaks.com/topic/290731-best-way-to-deal-with-optional-parameters-for-classes-and-functions/#findComment-1489297 Share on other sites More sharing options...
requinix Posted August 29, 2014 Share Posted August 29, 2014 Does anyone know of a trait like this been made before?I am 99% positive one has been. Quote Link to comment https://forums.phpfreaks.com/topic/290731-best-way-to-deal-with-optional-parameters-for-classes-and-functions/#findComment-1489305 Share on other sites More sharing options...
entheologist Posted August 30, 2014 Author Share Posted August 30, 2014 Same here, wish I could find it. Need to start looking into how to find these things. Quote Link to comment https://forums.phpfreaks.com/topic/290731-best-way-to-deal-with-optional-parameters-for-classes-and-functions/#findComment-1489350 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.