Hi everyone,

I'm a lazy programmer and when I want to create an array that I can store serialized in a database I don't feel like typing out all the array stuff rather I want to use a delimited string something like this:

access.read=1,2,3::
access.write=1,2::
access.modify=1,2::
access.manage=1::
somethingelse=10101

So I came up with this function that takes just that type of text information and converts it into a multi-dimensional array that I can later serialized and store into the database. The code looks like this:

function readConfigString($cnf){
		// is the input valid
		$out = array();
		if(!is_null($cnf) && is_string($cnf)){
			// clean up the input 
			$cnf = trim($cnf);
			if(substr($cnf,-2) == '::'){
				$cnf = substr($cnf,0,(strlen($cnf) - 2));
			}
			// breakdown the lines
			$lines = split('::',$cnf);
			foreach($lines as $line=>$data){
				$valSets = split('=',$data);
				if(strpos($valSets[0],".") > 1){
					$names = split("\.",$valSets[0]);
					$fname = trim(strtolower($names[0]));
					foreach($names as $id=>$name){
						$name = trim(strtolower($name));
						if($name != $fname){
							if(strpos($valSets[1],",") > 0){
								$out[$fname][$name] = split(",",$valSets[1]);
							}else{
								$out[$fname][$name] = $valSets[1];
							}
						}
					}	
				}else{
					$name = trim($valSets[0]);
					if(strpos($valSets[1],",") > 0){
						$out[$name] = split(",",$valSets[1]);
					}else{
						$out[$name] = trim($valSets[1]);
					}
				}
			}
		}
		return $out;
	}

The problem I've got is that it is really limited to only two associated array elements deep. For example if I would input a string like this:

level1.level2a.level3=10::
level1.level2b=20

The output array would look like this:

Array(
         [level1] => Array(
                                    [level2a] => 10
                                    [level3] => 10
                                    [level2b] =>20
                                    )
         )

I'm wondering if anyone out there could help me make this a little more flexible in how it handles the associated names so that there could be more than two levels?

Recommended Answers

All 4 Replies

Hi JRSofty,
before I think about a solution to what you want, let me cast some doubts on it first:
Is it really so time saving to have your config code instead of good ol' php?

$config = array(
  "access" => array(
    'read' => array(1,2,3),
    'write' => array(1,2),
    'modify' => array(1,2)
    'manage' => 1
  ),
  "somethingelse" => 10101
);

With your method you have all strings. No NULL, boolean or other types.

Ah well you see the config array needs to be read from the database. This is because that each module will have its own configuration. I could very well write things like

$config = array(
      "access" => array(
      'read' => array(1,2,3),
      'write' => array(1,2),
      'modify' => array(1,2)
      'manage' => 1
      ),
      "somethingelse" => 10101
      );

quickly but if I want to store it in the database I would need to serialize it. Right now I'm writing the configuration directly into the database because I'm still developing and haven't a way to enter configuration from the application as yet. This code is basically to assist me when I'm setting up the starting point of configuration array. So in the overall yes it does save me a bit of time especially when I want to make changes. As it is right now if I want to store the array in the database without my code above I would have to first write the array out like you have done, then I have to serialize it and output it. I then copy and paste it to the correct field of the database. This is where the time gets added.

I will later design and build an installer for modules where if I write the configuration as in the plaintext I can place it between a couple of XML tags. During the install process it takes the text and makes it into an array and then serializes the array, which of course is the preferred way of storing an array to the database.

At this point two text elements deep is working ok. I'm just wondering if there is a way of making my code work with more than just two named elements with the expressed syntax of my original example.

All right, I can see that you know what you're doing :-)

Since your hacking it anyway, we won't mind using eval(), will we? (yuck!)

$string = "level1.level2a.level3=10";

list($combinedKey, $value) = split('=', $string);
$keys = split('\.', $combinedKey);

$command = '$config["'.join('"]["', $keys).'"] = $value;';
eval($command);

var_dump($config);
commented: Very helpful. +1

Hmm yes that is much more efficient than the way I'm doing it.

I'll give it a shot thanks for the help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.