Jump to content

Parse file content to tree structure


G-son

Recommended Posts

Hello all,

 

I need some help to output a file. Let's say I have this content in the file "settings.txt":

 

server.ipaddress=192.168.50.72
server.port=80
server.name=staging
server.database.type=mysql
server.database.username=staginguser
debugmode=0
client.timeout=3600
client.autoconnect=1

 

By calling var_dump(parse_tree("settings.txt")); I want this output:

 

array(3) {
  ["server"]=>
  array(4) {
     ["ipaddress"]=>
     string(13) "192.168.50.72"
     ["port"]=>
     string(2) "80"
     ["name"]=>
     string(7) "staging"
     ["database"]=>    
     array(2) {
        ["type"]=>
        string(5) "mysql"
        ["username"]=>
        string(11) "staginguser"
     }    
  }
  ["debugmode"]=>
  string(1) "0"
  ["client"]=>    
  array(2) {
     ["timeout"]=>
     string(4) "3600"
     ["autoconnect"]=>
     string(1) "1"
  }     
}

 

The code I came up with so far is:

 

<?php

function parse_tree($file_path) {
fopen($file_path, 'r');
$content = file_get_contents($file_path);
return($content);
fclose($file_path);
}

var_dump(parse_tree("settings.txt"));

?>

 

But this just outputs everything like this:

 

string(189) "server.ipaddress=192.168.50.72 server.port=80 server.name=staging server.database.type=mysql server.database.username=staginguser debugmode=0 client.timeout=3600 client.autoconnect=1" 

 

Any help would be really appreciated!

Thanks and best regards

/Magnus

Link to comment
https://forums.phpfreaks.com/topic/198576-parse-file-content-to-tree-structure/
Share on other sites

Try using file. It will return an array, each entry containing a line from the file. Then, you can loop through it and break up the dots and assign it to the array. ;)

 

Good luck.

 

Thanks for a quick reply! I changed to file instead:

 

<?php

function parse_tree($file_path) {
// Open and get a file into an array.
   fopen($file_path, 'r');
   $content = file($file_path);

   echo '<pre>';
   return $content;
   echo '</pre>';
   fclose($file_path);
}

var_dump(parse_tree("settings.txt"));

?>

 

Now my output is like this:

 

array( {
  [0]=>
  string(32) "server.ipaddress=192.168.50.72
"
  [1]=>
  string(16) "server.port=80
"
  [2]=>
  string(21) "server.name=staging
"
  [3]=>
  string(28) "server.database.type=mysql
"
  [4]=>
  string(38) "server.database.username=staginguser
"
  [5]=>
  string(13) "debugmode=0
"
  [6]=>
  string(21) "client.timeout=3600
"
  [7]=>
  string(20) "client.autoconnect=1"
}

 

I don't really know how to proceed from this to get the desired output.

Loop through the values. Set up a temporary array. Split the strings using the dot as the delimiter up to the equal sign. Then just assign the values.

 

For example, this is how it would work. Using "server.ipaddress=192.168.50.72"

 

Let's set $a to be the array.

 

Split off the dots so you have an array like: (this may require 2 lines of code)

["server", "ipaddress"]

 

From there, just set $a['server']['ipaddress'] = "192.168.50.72";

 

Do that for each entry. Of course, I just explained how it works. Try to put it into PHP coding now. Good luck

Loop through the values. Set up a temporary array. Split the strings using the dot as the delimiter up to the equal sign. Then just assign the values.

 

For example, this is how it would work. Using "server.ipaddress=192.168.50.72"

 

Let's set $a to be the array.

 

Split off the dots so you have an array like: (this may require 2 lines of code)

["server", "ipaddress"]

 

From there, just set $a['server']['ipaddress'] = "192.168.50.72";

 

Do that for each entry. Of course, I just explained how it works. Try to put it into PHP coding now. Good luck

 

Thanks again for quick answer. Have been searching what type of split function to use and came up with explode. Got some progress with this code.

 

<?php

function parse_tree($file_path) {
// Open and get a file into an array.
fopen($file_path, 'r');
$values = file($file_path);
fclose($file_path);

//Split up strings
foreach ($values as $value) {
	$field = explode('.', $value);
	$field = explode('=', $value);
	}
	$values = $field;

echo '<pre>';	
return $values;
echo '</pre>';
}

var_dump(parse_tree("settings.txt"));

?>

 

But this only outputs the last sentence:

array(2) {
  [0]=>
  string(18) "client.autoconnect"
  [1]=>
  string(1) "1"
}

Okay, we're getting there. Step by step.

 

Just a few things to keep in mind. When you return something from a function, the function terminates on the spot, meaning your echo statement below won't be executed.

 

Before the foreach loop, specify $field = array();

 

Then inside your foreach loop, split the "=" first. That will give you an array of 2 values. The string with dots and the value after the equal sign. Take the first value and split the "."

 

Something like:

foreach ($values as $value) {
     $parts = explode("=", $value);
     $dots = explode(".", $parts[0]); // $parts[0] is the first half (value before the = sign). $parts[1] is the second half (value after the = sign)
     // Then $dots will have all the info you need to assign it to the array $field. Think you can take it from here?
}

 

Take a shot at it. It's really not so hard. ;) It's more rewarding to be able to code it up yourself than to have someone finish it for you. It's a really good start so try to finish it. Also, if you want to return something, return $field. Also, remove the echo lines. ;)

Okay, we're getting there. Step by step.

 

Just a few things to keep in mind. When you return something from a function, the function terminates on the spot, meaning your echo statement below won't be executed.

 

Before the foreach loop, specify $field = array();

 

Then inside your foreach loop, split the "=" first. That will give you an array of 2 values. The string with dots and the value after the equal sign. Take the first value and split the "."

 

Something like:

foreach ($values as $value) {
     $parts = explode("=", $value);
     $dots = explode(".", $parts[0]); // $parts[0] is the first half (value before the = sign). $parts[1] is the second half (value after the = sign)
     // Then $dots will have all the info you need to assign it to the array $field. Think you can take it from here?
}

 

Take a shot at it. It's really not so hard. ;) It's more rewarding to be able to code it up yourself than to have someone finish it for you. It's a really good start so try to finish it. Also, if you want to return something, return $field. Also, remove the echo lines. ;)

 

Oki, two missing pieces left. First the code:

 

<pre>
<?php

function parse_tree($file_path) {
$oFile = fopen($file_path, 'r');

$aReturnArray = array();

while (!feof($oFile)) {
	rtrim($oFile,"\r");
	$sLine = fgets($oFile);
//		rtrim($oFile,"\r");
	$aRowItem = explode("=", $sLine);
	$aTypeItem = explode(".", $aRowItem[0]);
//		if substr_count($aTypeItem, ".",1) {
//			$aTypeItem = explode(".", @aRowItem[0]);
//		}
	$sType = $aTypeItem[0];
	$sAttr = $aTypeItem[1];
	$sVal = $aRowItem[1];


	if($sAttr == "")
	{
		$aReturnArray[$sType] = $sVal;
	}
	else 
	{
		$aReturnArray[$sType][$sAttr] = $sVal;
	}

}
  
return $aReturnArray;
}

var_dump(parse_tree("settings.txt"));

?>
</pre>

 

This outputs almost as I want it:

array(3) {
  ["server"]=>
  array(4) {
    ["ipaddress"]=>
    string(15) "192.168.50.72
"
    ["port"]=>
    string(4) "80
"
    ["name"]=>
    string(9) "staging
"
    ["database"]=>
    string(13) "staginguser
"
  }
  ["debugmode"]=>
  string(3) "0
"
  ["client"]=>
  array(2) {
    ["timeout"]=>
    string(6) "3600
"
    ["autoconnect"]=>
    string(1) "1"
  }
}

 

For some reason there is a linefeed in the strings. I have tried to use rtrim($oFile,"\r"); but without any luck. I dubbelchecked the file and the only thing in the end of every line is a Carriage Return + Line Feed.

 

Also, the content doesn't get grouped the right way if there is two dots. Like server.database.type=mysql

server.database.username=staginguser

 

I tried substr_count(), but couldn't get it to work. I commentet out where I put rtrim() and substr_count()

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.