Tomasz Tomasz - 2 months ago 4
JSON Question

How to keep 'true' instead of '1' during conversion json_decode

I'd like to convert json file to csv. In json I have:

{
"fields": [
{
"_id": "identifier",
"required": true,
"size": 4,
"type": "text"
}
]
}


After json_encode in array I have
[required] => 1
My question is how to force keep "required" as
true
. I know that easiest method is check what is in by
if
and than assign string
"true"
but maybe is another, more effective way ?

full code looks like that:

class csvConverter {

public $fh;
public $csv_file;
public $json_file;

public function __construct() {

}

public function fileOpen($str) {
return fopen($str, 'w');
}

public function countCategories($json_obj) {
$max = 0;
foreach ($json_obj['sections'] as $section) {
foreach ($section['fields'] as $field) {
$count = count($field['categories']);
if ($max < $count) {
$max = $count;
}
}
}
return $max;
}

public function convert() {
try {
$json = file_get_contents($this->json_file);
$json_obj = json_decode($json, true);

$max = $this->countCategories($json_obj);

foreach ($json_obj['sections'] as $kk => $obj) {
foreach ($obj['fields'] as $key => $field) {

$mainArray[$kk][$key] = array(
'Section id' => !empty($obj['_id']) ? $obj['_id'] : "",
'Section name' => !empty($obj['name']) ? $obj['name'] : "",
'Field id' => !empty($field['_id']) ? $field['_id'] : "",
'Name' => !empty($field['name']) ? $field['name'] : "",
'Descriprion' => !empty($field['description']) ? $field['description'] : "",
'Help' => !empty($field['help']) ? $field['help'] : "",
'Type' => !empty($field['type']) ? $field['type'] : "",
'Required' => !empty($field['required']) ? $field['required'] : "",
'Default' => !empty($field['default']) ? $field['default'] : "",
'Size' => !empty($field['size']) ? $field['size'] : "",
);

if (!empty($field['categories'])) {
foreach ($field['categories'] as $k => $v) {
$mainArray[$kk][$key]['categories_' . $k] = $v;
}
} else {
for ($i = 0; $i < $max; $i++) {
$mainArray[$kk][$key]['categories_' . $i] = "";
}
}
}
}

$header .= implode(";", array_keys($mainArray[0][0])) . "\n";

foreach ($mainArray as $element) {
foreach ($element as $elem) {
$header .= implode(";", $elem) . "\n";
}
}
fwrite($this->fh, $header . "\n");
} catch (Exception $ex) {
echo $ex->getMessage();
die('Some problems !');
}
}

}

$csvObiect = new csvConverter();
$csvObiect->csv_file = 'file.csv';
$csvObiect->json_file = 'form.json';
$csvObiect->fh = fopen($csvObiect->csv_file, 'w');
$csvObiect->convert();


and json file:

{
"sections": [
{
"_id": "site",
"fields": [
{
"_id": "site-id",
"default": 2,
"name": "Site ID",
"required": true,
"size": 4,
"type": "number"
}
],
"name": "Site"
},
{
"_id": "study-entry-1",
"fields": [
{
"_id": "identifier",
"description": "A unique, valid \"patient identifier\".",
"help": "Enter the *patient identifier* here.\nIt should be *no longer than* four characters.",
"name": "Identifier",
"required": true,
"size": 4,
"type": "text"
},
{
"_id": "date-of-study-entry",
"default": "22/01/2012",
"help": "DD/MM/YYYY",
"name": "Date of study entry",
"required": true,
"type": "date"
},
{
"_id": "injury",
"categories": [
"Neck",
"Head",
"Back"
],
"default": "Neck",
"name": "Injury",
"type": "category"
},
{
"_id": "history",
"default": "Unknown",
"name": "History",
"type": "textarea"
}
],
"name": "Study entry"
}
]
}

Answer

This is not possible with CSV. CSV is a TEXT format. There is no way to attach metadata to that text to differentiate between 'true-is-text' and `true-is-boolean'.

If you want to store metadata in a file, then don't use CSV. Use something with a more defined and STANDARD structure, like json, XML, etc...

CSV should be considered a last resort "everything else has failed" format, because CSV is NOT a standard. There's just some basic agreements on how some of it works, and then lots of disagreements on the rest, notably: escaping metachars.

That means that, no, you can't have fgetcsv suck in a line of csv and automatically convert the word true into a boolean. That's not csv's job.

Comments