maexus Posted June 10, 2008 Share Posted June 10, 2008 So, lets say you have the following string: $string = "a__b__d__z"; $string = explode('__', $string); What I want to do is access a variable like this: $array[$string[0]][$string[1]][$string[2]][$string[3]]; I have been using a switch but this is ugly and only allows for as much levels as I put in the switch: public function get($variable){ $variable = explode('__', $variable); switch(count($variable)){ case 1: #group return (isset($this->settings[$variable[0]])) ? $this->settings[$variable[0]] : false; break; case 2: #variable return (isset($this->settings[$variable[0]][$variable[1]])) ? $this->settings[$variable[0]][$variable[1]] : false; break; case 3: #subvariable return (isset($this->settings[$variable[0]][$variable[1]][$variable[2]])) ? $this->settings[$variable[0]][$variable[1]][$variable[2]] : false; break; } } Don't worry about the reason why I need it, I just need to know if there is a leaner/cleaner way of doing this? As you can see, this only goes out to 3 but if I have 4 or 5, it won't return anything. I need it to be able to adapt to the input. Quote Link to comment Share on other sites More sharing options...
effigy Posted June 10, 2008 Share Posted June 10, 2008 Why is this marked as solved? You could create a PHP string and use eval. Quote Link to comment Share on other sites More sharing options...
maexus Posted June 10, 2008 Author Share Posted June 10, 2008 Yea, figured it out after I posted and I didn't see an option to delete post Quote Link to comment Share on other sites More sharing options...
effigy Posted June 10, 2008 Share Posted June 10, 2008 Would you please share your solution for others that may be interested? Quote Link to comment Share on other sites More sharing options...
maexus Posted June 10, 2008 Author Share Posted June 10, 2008 Thought I had it solved but running into an issue public function get($variable){ $variable = explode('__', $variable); $temp_var = '$this->settings'; for ($i=0; $i < count($variable); $i++) { $temp_var .= '[$variable['.$i.']]'; } return (isset($$temp_var)) ? $$temp_var : $$temp_var; } It outputs the following error when I try to run the function: <?php require 'loader.php'; $settings = Settings_JSON::init(); echo $settings->get('project__version'); ?> Notice: Undefined variable: $this->settings[$variable[0]][$variable[1]] If you look above, $this->settings[$variable[0]][$variable[1]] is the variable I was using in Case 2 but now it doesn't work. What am I overlooking? Quote Link to comment Share on other sites More sharing options...
Rebelrebellious Posted June 10, 2008 Share Posted June 10, 2008 Does it work if you write: $temp_var = 'this->settings'; ... $$temp_var .= '[$variable['.$i.']]'; I may not be understanding what you are indending to have happen. Another thought is to write line 5 this way: $temp_var .= $variable[$i]; Quote Link to comment Share on other sites More sharing options...
maexus Posted June 10, 2008 Author Share Posted June 10, 2008 $$temp_var .= '[$variable['.$i.']]'; That doesn't work. It outputs [$variable[0]] after the error I posted above. $temp_var .= $variable[$i]; That won't work. Take a look at this string: $string = 'a__b'; After I use __ as a delimiter in explode, I get an array like this: Array ( [0] => a [1] => b ) I want to use that array to access elements in this array stored in $array: Array ( [a] => Array ( [a] => This is aA [b] => This is aB ) [b] => Array ( [a] => This is bA [b] => This is bB ) ) This is how I am currently doing it: $array[string[0]][string[1]] and as far as I know, the only way to do this. Quote Link to comment Share on other sites More sharing options...
maexus Posted June 10, 2008 Author Share Posted June 10, 2008 $array[$string[0]][$string[1]] Quote Link to comment Share on other sites More sharing options...
Rebelrebellious Posted June 10, 2008 Share Posted June 10, 2008 I think I understand better now. I hope you don't mind another untested suggestion. change this one line: $temp_var = 'this->settings'; Quote Link to comment Share on other sites More sharing options...
maexus Posted June 10, 2008 Author Share Posted June 10, 2008 No problem. I actually did try that after rereading some material on variable variables. It outputs the following error: Notice: Undefined variable: this->settings[$variable[0]] It just baffles me. The string is being constructed with the correct variable name but still outputs the error. I know for a fact that variable exists as it works with my old method using a switch. I imagine it's has to do with how PHP is interpreting $$temp_var that I'm missing. Quote Link to comment Share on other sites More sharing options...
Rebelrebellious Posted June 10, 2008 Share Posted June 10, 2008 How about if you evauate each of those parts then as you pass them through the for() So if var[0] = 0 and var[1] = 1 etc. instead of building $tis->settings[$var[0]]... you build $this->settings[0]... Quote Link to comment Share on other sites More sharing options...
maexus Posted June 10, 2008 Author Share Posted June 10, 2008 $this->settings is an assoc array with variable key names. I'm exploding the string and using the parts as the key names. I will never know what $this->settings[0] is, it depends on what I'm loading into it. Unless I'm misinterpreting what you are saying. I may just stick with my original method as this is getting complex Quote Link to comment Share on other sites More sharing options...
Rebelrebellious Posted June 10, 2008 Share Posted June 10, 2008 So that would look like public function get($variable){ $variable = explode('__', $variable); $temp_var = 'this->settings'; // this still seems right to me for ($i=0; $i < count($variable); $i++) { $temp_var .= '['. $variable[$i] .']'; // changed this } return (isset($$temp_var)) ? $$temp_var : $$temp_var; } I would love to stick around and puzzle through this with you, but I need to go for a while. Good luck. Quote Link to comment Share on other sites More sharing options...
maexus Posted June 10, 2008 Author Share Posted June 10, 2008 Hey thanks for the help. Yea, giving me the following error: Notice: Undefined variable: this->settings[db] If anyone else has any suggestions, I would greatly appreciate it. I'm going to keep working on this. Quote Link to comment Share on other sites More sharing options...
grimmier Posted June 11, 2008 Share Posted June 11, 2008 What if you try setting them array points as you iterate through and build your string public function get($variable){ $variable = explode('__', $variable); $temp_var = '$this->settings'; for ($i=0; $i < count($variable); $i++) { $temp_var .= '['. $variable[$i] .']'; $$temp_var; //set the var before trying to set the next one } return (isset($$temp_var)) ? $$temp_var : $$temp_var; } Quote Link to comment Share on other sites More sharing options...
Rebelrebellious Posted June 11, 2008 Share Posted June 11, 2008 I just noticed that in the first post you had the function return false if the target was not set but in the second you are trying to return the contents whether it is there or not. Quote Link to comment Share on other sites More sharing options...
maexus Posted June 11, 2008 Author Share Posted June 11, 2008 @grimmier - Didn't work, get the following error: Notice: Undefined variable: $this->settings[db] Notice: Undefined variable: $this->settings[db] @Rebelrebellious - I changed it but forgot to change it back before copying and pasting it in here and I later changed it to just return $temp_var just to confirm the string is being put together correctly. I thought the issue was with the variable going into isset() but it's just an issue with $$temp_var. Just having $$temp_var in the script causes the error above. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted June 11, 2008 Share Posted June 11, 2008 That's not an error, it's a notice. You can disable them with error_reporting(E_ALL & ~E_NOTICE) as your error reporting line. Quote Link to comment Share on other sites More sharing options...
maexus Posted June 11, 2008 Author Share Posted June 11, 2008 Yes but it still doesn't work. $settings = Settings_JSON::init(); print_r($settings->get('db_host')); This should output $settings['db']['host'] but it just gives me that notice Quote Link to comment Share on other sites More sharing options...
grimmier Posted June 11, 2008 Share Posted June 11, 2008 public function get($variable){ $varArray = explode('__', $variable); $temp_var = '$this->settings'; foreach($varArray as $key->$value { $temp_var .= '['. $value .']'; } return (isset($$temp_var)) ? $$temp_var : $$temp_var; } Quote Link to comment Share on other sites More sharing options...
Rebelrebellious Posted June 11, 2008 Share Posted June 11, 2008 And in addition to grimmiers method if the array key is textual then I suppose line 5 should be: $temp_var .= "['$value']"; so you get the single quotes. Quote Link to comment Share on other sites More sharing options...
maexus Posted June 11, 2008 Author Share Posted June 11, 2008 I've tried using a foreach loop as well but I tried your example, even with Rebelrebellious change and I'm getting the same Notice. I've tried and rewritten this over and over and it's coming out the same. I do think you were right though Rebel that it does need to be: $temp_var = 'this->settings'; But still doesn't work. I really appreciate your guys input. If I find a solution, I'll post it Quote Link to comment Share on other sites More sharing options...
Rebelrebellious Posted June 11, 2008 Share Posted June 11, 2008 any chance that we could get our hands on $settings or something that will approximate it so that I could test the code myself? Quote Link to comment Share on other sites More sharing options...
maexus Posted June 11, 2008 Author Share Posted June 11, 2008 Yea, here is settings.class.php <?php abstract class Settings { protected $settings = array(); protected static $instance = NULL; private function __clone(){} private function __construct(){ $this->load_and_map('jawa'); $this->load_and_map('project'); $this->load_and_map('db'); } static public function init(){ if(is_null(self::$instance)){ self::$instance = new self(); } return self::$instance; } abstract function load_and_map($file); public function get($variable){ $variable = explode('__', $variable); switch(count($variable)){ case 1: #group return (isset($this->settings[$variable[0]])) ? $this->settings[$variable[0]] : false; break; case 2: #variable return (isset($this->settings[$variable[0]][$variable[1]])) ? $this->settings[$variable[0]][$variable[1]] : false; break; case 3: #subvariable return (isset($this->settings[$variable[0]][$variable[1]][$variable[2]])) ? $this->settings[$variable[0]][$variable[1]][$variable[2]] : false; break; } } public function __get($variable){ $variable = explode('__', $variable); switch(count($variable)){ case 1: #group return (isset($this->settings[$variable[0]])) ? $this->settings[$variable[0]] : false; break; case 2: #variable return (isset($this->settings[$variable[0]][$variable[1]])) ? $this->settings[$variable[0]][$variable[1]] : false; break; case 3: #subvariable return (isset($this->settings[$variable[0]][$variable[1]][$variable[2]])) ? $this->settings[$variable[0]][$variable[1]][$variable[2]] : false; break; } } public function get_prototype($variable){ $varArray = explode('__', $variable); $temp_var = 'this->settings'; foreach($varArray as $key => $value) { $temp_var .= "['$value']"; } return (isset($$temp_var)) ? "{$temp_var} worked" : "{$temp_var} doesn't work"; } } ?> <?php class Settings_JSON extends Settings { static public function init(){ if(is_null(self::$instance)){ self::$instance = new self(); } return self::$instance; } public function load_and_map($file){ if(file_exists("settings/{$file}.json")){ $handle = fopen("settings/{$file}.json", "r"); $contents = fread($handle, filesize("settings/{$file}.json")); fclose($handle); $this->settings[$file] = json_decode($contents, TRUE); }else{ return false; } } } ?> map_and_load() is what parses the json file and maps it to $obj->settings. Quote Link to comment Share on other sites More sharing options...
grimmier Posted June 11, 2008 Share Posted June 11, 2008 OK I think this should do it for yah. function get($variable){ $varArray = explode('__', $variable); $temp_var = 'this->settings'; $newArray = $$temp_var; foreach($varArray as $key=>$value) { $newArray[$value] = array(); } return $newArray; } Quote Link to comment 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.