0

I'm stuck with a small PHP loop.

My query returns 10 rows, with columns 'id' and 'parentId'. I'm trying to create an array of parent ids to use for breadcrumbs on a site.

Current page ID is '6'. It's parent is '5', which again has page '3' as parent. Page '3' has '0' as parent... Array should then be 5, 3, 0.

$stmt = $db->query("
    SELECT id, parentId
    FROM cat
");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

function crumbs($rows, $id = '6') {
    $crumbs = array();
    foreach ($rows as $row) {
        if ($row['id'] == $id) {
            if ($row['parentId'] != 0) {
                crumbs($rows, $row['parentId']);
            }
            $crumbs[] = $row['parentId'];
        }
    }
    // echo $crumbs returns Array, Array, Array...
    return $crumbs;
}

$json['crumbs'][] = crumbs($rows);
// ...but $json['crumbs'] return only one Array (5).

echo json_encode($json);

Edit: MySql Rows:

0   0
1   0
2   0
3   0
4   3
5   3
6   5
7   7
9   2
12  3

And a SQLFiddle

8
  • The better solution would actually be to get MySQL to return exactly what you want. Commented Sep 10, 2016 at 16:45
  • Can you please provide 10 rows of data, and desired results. This looks like it could be a very simple MySQL query without the whole loop. Commented Sep 10, 2016 at 16:46
  • Also, do you have a maximum depth in mind? Commented Sep 10, 2016 at 16:50
  • Create a sqlfiddle and perhaps @Pachonk is up for doing a self-join. Right now you could support your question better with a fiddle. Otherwise apathy can set in for the answer people Commented Sep 10, 2016 at 16:55
  • sqlfiddle.com you can use text-to-ddl to really speed up creation time. Commented Sep 10, 2016 at 16:57

1 Answer 1

1

Here is a solution that will use pure MySQL to get you all parent child relationships off of 1 parent:

Query:

SELECT  @r AS _id,
         (
         SELECT  @r := parent
         FROM    nav
         WHERE   id = _id
         ) AS parent,
         @l := @l + 1 AS level
 FROM    (
         SELECT  @r := 6,
                 @l := 0
         ) vars,
         nav h
WHERE    @r <> 0

Results:

| _id | parent | level |
|-----|--------|-------|
|   6 |      5 |     1 |
|   5 |      3 |     2 |
|   3 |      0 |     3 |

http://sqlfiddle.com/#!9/89845a/8

Sign up to request clarification or add additional context in comments.

3 Comments

Amazing. Screw php :) Thank you!
For the record, most of that type of messing around can be saved on the mysql side, but there is a line that must be drawn when it comes to time and effort.
The one thing you want to be careful with is using too many variables and using loops. When queries get complex, make them stored procs (they're like functions that php can call and pass in args)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.