Reputation: 137
I have table with categories (4 levels) like:
+-------+---------------+---------------------------+
| id | sub_for | level |
+-------+---------------+---------------------------+
| 1 | 0 | 1 | - main category
| 2 | 1 | 2 | - first level
| 3 | 2 | 3 | - second level
| 4 | 3 | 4 | - third level
+-------+---------------+---------------------------+
and I'll have multiple categories and subcategories.
So, when I choose main category (level 1), I need to select all subcategories.
I can reach to second level like:
$findInIds = array();
$data['category'] = '1';
$query = $this->db->query('SELECT id FROM shop_categories WHERE sub_for = ' . $data['category']);
foreach ($query->result() as $row) {
$findInIds[] = $row->id;
}
and I'm getting array of all subcategories level 2 related to chosen main category.
Array
(
[0] => 2
)
I guess I should use some recursive function to loop till 4th level but I've got lost here...
Upvotes: 1
Views: 678
Reputation: 1642
So, you are on the right path, you need to follow it through. You got the result for the first category checked, you need to check for it's children, and children's children.
The below uses a while loop instead of recursion. We add each subcategory found to a list of sub-categories we need to look at next. Then we check each subcategory, adding any new sub-sub-categories to the list as well. The while loop will end once we checked the last leaf category. (A category that does not have any children).
Also, since array_pop removes elements from the end of the array and [] adds to the end, this is in effect a Depth First Search, where we check down the tree before checking across the same level of the tree.
// Initialize arrays
$findInIds = [];
$idsToCheck = [];
// Load up First Category
$idsToCheck[] = '1';
while(count($idsToCheck)){
// Grab a new category to check
$idToCheck = array_pop($idsToCheck);
// Make the query
$query = $this->db->query('SELECT id FROM shop_categories WHERE sub_for = ' . $idToCheck); // TODO: use query sanitization or parameterized queries
foreach ($query->result() as $row) {
// Foreach Result ...
// - Add to find in ids (This is a subcategory of the category we are checking)
// - Add to ids to check (This subcategory may have subcategories itself)
$findInIds[] = $row->id;
$idsToCheck[] = $row->id;
}
}
Upvotes: 2