I have a file on a server that I need to parse and build a JSON object to return. I am using PHP.
The file contents look something like this:
########################################
# NOTES FILE
#
# THIS FILE IS AUTOMATICALLY GENERATED
# DO NOT MODIFY THIS FILE!
########################################
info {
created=1552596653
version=4.4.3
last_update_check=1552554585
update_available=0
last_version=4.4.3
new_version=4.4.3
}
programstatus {
modified_host_attributes=0
modified_service_attributes=0
pid=11523
daemon_mode=1
program_start=1552593834
last_log_rotation=0
...
Ideally, I would like to grab EACH segment (eg: "info", "programstatus", etc...) and add them to the JSON obj/array as I parse through it. With each attribute = value
being assigned accordingly.
So something like:
$data = array();
// Loop here for each segment
$data['info'] = array(
"created" => "1552596653",
"version" => "4.4.3",
etc...
)
// Then wrap it up with something like
return json_encode($data);
I just can't "think" to loop through the file while breaking it out into chunks.
I have the file contents via:
$statusFile = '/location/to/my/data/file';
ob_start();
include( $statusFile );
$statusFileContent = ob_get_contents();
ob_end_clean();
You need to accomplish 3 things:
Here is a rough chunk of code I threw together that illustrates the approach you could take. I tested it on PHP Fiddle, but couldn't figure out how to share a link.
<?php
// File path to load
// $file = "/path/to/file.txt";
$file = "https://pastebin.com/raw/gu2AC7qy";
// Flag indicating we are inside of a "block"
$inBlock = false;
// Name/Key of current "block"
$blockName = null;
// Container for our data
$data = [];
// Open for reading
$handle = fopen($file, 'r');
// If we opened it (you should add better error handling)
if ($handle) {
// Grab each line one at a time
while(($line = fgets($handle)) !== false) {
// Cleanup line
$line = trim($line);
// Throw away useless lines (comments, empty, etc.)
if (empty($line)) {
// Skip blank lines
continue;
}
if (substr($line, 1) == '#') {
// Skip comments
continue;
}
// Check if start of "block"
if (substr($line, -1) == '{') {
// Set the flag
$inBlock = true;
// Get the block name
$blockName = trim(str_replace('{', '', $line));
// Create new data section
$data[$blockName] = [];
// Get next line
continue;
}
// If currently inside block
if ($inBlock === true && ! empty($blockName)) {
// Get a data attribute
$dataRow = trim($line);
// Parse as key/value
$dataRowParts = explode("=", $dataRow);
$key = isset($dataRowParts[0]) ? trim($dataRowParts[0]) : null;
$value = isset($dataRowParts[1]) ? trim($dataRowParts[1]) : "";
// Store in current block's data
if ($key !== null) {
$data[$blockName][$key] = $value;
}
// Get next line
continue;
}
// Check if end of "block"
if (substr($line, -1) == '}') {
// Clear flag
$inBlock = false;
// Unset block name
$blockName = null;
// Get next line
continue;
}
}
// Close the file
fclose($handle);
}
// Output data as JSON
echo json_encode($data);
?>
Ideally you would put this logic in classes and methods so it's not a giant wall of code -- and of course add appropriate error handling. Good luck!
I made an elegant solution for you. You don't need loops, you can do it with 5 lines of code. Just use regex and transform the file you have.
$file = "Your file as a string";
//Get the titles like 'info' and put it around quotion marks
$titles_changed = preg_replace('/(.*)\{/', '"$1":{', $file, -1 );
//Get strings like created=1552596653 and transform to "created"="1552596653",
$values_changed = preg_replace('/(.*)=(.*)/', '"$1":"$2",', $titles_changed );
//Remove spaces from the string
$no_spaces = preg_replace('/\s/s', '', $values_changed);
//Fix all that became ",}" from the second replacement and transforms it into "},"
$limits_fixed = preg_replace('/\,\}/', '},', $no_spaces);
//Remove a "," that lasts on the end of the file and put all string around brakets
$json = "{". rtrim($limits_fixed, ',') . "}";
$object = json_decode($json);
You can take advantage of the fact that this is almost a .ini file.
Remove that top part and convert the bracketed groups into ini sections
$sections = preg_replace(['/#.*/', '/(\S+) \{/', '/}/'], ['', '[$1]', ''], $file_contents);
Then it's a .ini string.
$result = parse_ini_string($sections, true);
echo json_encode($result);