I am using a PHP Class that is generating a nested categories tree menu in json format from a MySQL database. The problem is that the array used to fill the data doesn't do what it is supposed to
The PHP Class is:
class nestedCategories {
public $json = array();
public function generateMenu($categories,$level){
$this->json = array();
foreach($categories as $category ){
$this->json['title'] = $category->description;
$this->json['expanded'] = true;
if(isset($category->children) && count($category->children)>0){
$this->json['folder'] = true;
$this->json['children'] = $this->generateMenu($category->children,$category->category_id);
} else {
$this->json['folder'] = false;
}
}
}
public function getJSON() {
return $this->json;
}
The $json is supposed to look like:
[
{"title": "Animalia", "expanded": true, "folder": true, "children": [
{"title": "Chordate", "folder": true, "children": [
{"title": "Mammal", "children": [
{"title": "Primate", "children": [
{"title": "Primate", "children": [
]},
{"title": "Carnivora", "children": [
]}
]},
{"title": "Carnivora", "children": [
{"title": "Felidae", "lazy": true}
]}
]}
]},
{"title": "Arthropoda", "expanded": true, "folder": true, "children": [
{"title": "Insect", "children": [
{"title": "Diptera", "lazy": true}
]}
]}
]}
]
but, when I am trying to pull the data from MySQL, the $json array only gives me the last pulled data from MySQL, as if it is erasing all data behind
Could someone talk me trough?
You are overwriting the array with each loop around categories
, and wiping out the member variable with an array assignment each time round.
Plus, I suspect that it won't return the structure you're looking for unless you make it preoperly recursive (which means returning the array that you've built):
class nestedCategories {
public function generateMenu($categories,$level){
$categoriesJson = array();
foreach($categories as $category ){
$categoryJson = array();
$categoryJson['title'] = $category->description;
$categoryJson['expanded'] = true;
if(isset($category->children) && count($category->children)>0){
$categoryJson['folder'] = true;
$categoryJson['children'] = $this->generateMenu($category->children,$category->category_id);
} else {
$categoryJson['folder'] = false;
}
$categoriesJson[] = $categoryJson;
}
return $categoriesJson;
}
}
You would now just get back the data by calling generateMenu
rather than using the member variable.
You are setting $this->json = array();
at the top of your generateMenu
method. When you make the recursive call it destroys what was written to the array on the previous call.
In addition in each recursive call $this->json['title']
will over write the previous title. The same goes for expanded
, children
and folder
.
It looks like I took a little longer that I should have to make the example code. Here it is anyway.
class Foo {
public function generateMenu($categories){
$json_array = array();
foreach($categories as $category) {
$json_object = array();
$json_object['title'] = $category->description;
if(isset($category->children) && count($category->children)>0){
// it looks like expanded should only be
// in objects with > 0 children
$json_object['expanded'] = true;
$json_object['folder'] = true;
$json_object['children'] = $this->generateMenu($category->children);
} else {
// based on the json in the question it looks like
// it should always contain a children array, but no folder element
$json_object['children'] = array();
}
$json_array[] = $json_object;
}
return $json_array;
}
}
Here is the test data:
$Diptera = new stdClass();
$Diptera->description = 'Diptera';
$Insect = new stdClass();
$Insect->description = 'Insect';
$Insect->children = array($Diptera);
$Arthropoda = new stdClass();
$Arthropoda->description = 'Arthropoda';
$Arthropoda->children = array($Insect);
$Felidae = new stdClass();
$Felidae->description = 'Felidae';
$Carnivora2 = new stdClass();
$Carnivora2->description = 'Carnivora';
$Carnivora2->children = array($Felidae);
$Carnivora = new stdClass();
$Carnivora->description = 'Carnivora';
$Primate2 = new stdClass();
$Primate2->description = 'Primate';
$Primate = new stdClass();
$Primate->description = 'Primate';
$Primate->children = array($Primate2, $Carnivora);
$Mammal = new stdClass();
$Mammal->description = 'Mammal';
$Mammal->children = array($Primate, $Carnivora2);
$Chordate = new stdClass();
$Chordate->description = 'Chordate';
$Chordate->children = array($Mammal);
$Animalia = new stdClass();
$Animalia->description = 'Animalia';
$Animalia->children = array($Chordate);
$catagories = array($Animalia);
Here is how it's called:
$f = new Foo();
echo json_encode($f->generateMenu($catagories), JSON_PRETTY_PRINT);
Here is the output:
[
{"title": "Animalia", "expanded": true, "folder": true, "children":
[
{"title": "Chordate", "expanded": true, "folder": true, "children":
[
{"title": "Mammal", "expanded": true, "folder": true, "children":
[
{"title": "Primate", "expanded": true, "folder": true, "children":
[
{"title": "Primate", "children": []},
{"title": "Carnivora", "children": []}
]
},
{"title": "Carnivora", "expanded": true, "folder": true, "children":
[
{"title": "Felidae", "children": []}
]
}
]
}
]
},
{"title": "Arthropoda", "expanded": true, "folder": true, "children":
[
{"title": "Insect", "expanded": true, "folder": true, "children":
[
{"title": "Diptera", "children": []}
]
}
]
}
]
}
]
You are overwriting the array keys when you iterate over the JSON.
$array = array();
$array['foo'] = 'bar';
//$array['foo] = 'bar';
$array['foo'] = 'foo';
//$array['foo'] = 'foo';