0

I have a collction of posts I´l like to show in a table. Each post has an id and a parent_id.

I want to loop through the table with a nested foreach, but I dont get it to work. My idea is to loop through each post, print the name and stuff, and also find all it´s children (by looping through each post and see if the childs parent id is equal to my id.)

My code is:

$allPosts = $posts;
foreach ($posts as $post) {
    if ($post->parent_id == 0){ //0 means highest level, no parent
        echo $post->name;
        $current_id = $post->id;

        foreach ($allPosts as $childPost){
            if($childPost->parent_id == $current_id){
                echo $cihldPost->name;

            }   
        }
    }
}

The problem is, the first loop does only run once. If I delete the second foreach-loop, the first one runs correctly.

Why is this happening, and how do I solve it?

ADDED: The post itself is like a blog post, it contains the following: id, title, body, compact, parent_id. Where id is the unique id, title and body as title and body to the blog post, compact as a short name used for the url, an the parent id to tell who the post is lying under, ie. Im a child to my parent.

Since the user should have all the possibility to move around the posts and put the posts in a menu, think of the top level posts as menu items, and the once that have a parent as the submenu item.

3
  • 1
    what does $childPost, $allPosts contain? what is the relation? Commented Sep 29, 2013 at 11:27
  • $allPosts = $posts, just to make the variables different even though it is the same posts. the childpost (which doesn´t have to be a childpost unless its parent_id==current_id), is just the name of the post i get in the for each. Each post contains name, id, parent_id, content, url, and other minor stuff. Think of it like a blog post. Does this makes sense? Commented Sep 29, 2013 at 11:30
  • @Malin if you post some sample content of $posts;, it will become easy for us to understand your problem Commented Sep 29, 2013 at 11:41

3 Answers 3

2

My idea is to loop through each post, print the name and stuff, and also find all it´s children (by looping through each post and see if the childs parent id is equal to my id.)

Currently, you're just trying to loop through the same object once again. The $allPosts variable isn't necessary. If you're trying to loop through each child element, then you need to use $post inside the nested foreach loop.

You're currently doing:

$obj2 = $obj;
foreach ($obj as $child) {
    foreach ($obj2 as $anotherchild) {
    # code...
    }
}

Roughly, the structure should look like:

foreach ($obj as $child) {
    foreach ($child as $secondchild) {
      # code...
    }
}

With your code:

foreach ($posts as $post) {
    if ($post->parent_id == 0){ //0 means highest level, no parent
        echo $post->name;
        $current_id = $post->id;

        foreach ($post as $childPost){
            if($childPost->parent_id == $current_id){
                echo $cihldPost->name; // <-- typo?    
            }   
        }
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

that does not work for me, since $posts is a vector containing all posts, and $post is an actual post that only contains itself
@Malin: Are you not trying to loop through all the posts? What exactly are you trying to do with the nested-foreach, then?
yes, looping through all the post first: print name of post. then print name of my childs
@Malin: I believe that's what the code in my answer does. How is the output different from what you want?
trying to do foreach($post as $childpost) generates the error: Notice: Trying to get property of non-object
0

for some reason, the foreach did not work on the $posts object itself that my Controller was passing on to my view. However, if I saved the $posts in a local array, it all worked. I still dont know why I had the problem in the first place, so please comment or provide a better answer that this.

    $mylist = array();
foreach($posts as $post) {
    $listitem = array();
    $listitem['id'] = $post->id;
    $listitem['parent_id'] = $post->parent_id;
    $listitem['title'] = $post->title;
    $listitem['compact'] = $post->compact;
    $mylist[] = $listitem;
}
foreach($mylist as $listitem){
    #code..
    foreach($mylist as $inneritem){
         #code..
    }
}

2 Comments

I tried your code and after I corrected the typo $cihldPost->name; it all worked, as it supposed to. Other than that I only added a line break to the output. I can post the code I tried if you need it.
yeah please do, I also corrected the type and did NOT get it to work other than the solution I provided above
0

Here is how I changed your code:

$posts = array(
    (object) array("parent_id" => 0, "id" =>  1, "name" => 'Outer 1'),
    (object) array("parent_id" => 0, "id" =>  2, "name" => 'Outer 2'),
    (object) array("parent_id" => 0, "id" =>  3, "name" => 'Outer 3'),
    (object) array("parent_id" => 0, "id" =>  4, "name" => 'Outer 4'),
    (object) array("parent_id" => 0, "id" =>  5, "name" => 'Outer 5'),
    (object) array("parent_id" => 1, "id" =>  6, "name" => 'Inner 1.1'),
    (object) array("parent_id" => 1, "id" =>  7, "name" => 'Inner 1.2'),
    (object) array("parent_id" => 4, "id" =>  8, "name" => 'Inner 4.1'),
    (object) array("parent_id" => 5, "id" =>  9, "name" => 'Inner 5.2'),
    (object) array("parent_id" => 5, "id" => 10, "name" => 'Inner 5.2'),
    (object) array("parent_id" => 5, "id" => 11, "name" => 'Inner 5.3'),

);

$allPosts = $posts;
foreach ($posts as $post) {
    if ($post->parent_id == 0){ //0 means highest level, no parent
        echo $post->name . ' : ';
        $current_id = $post->id;

        foreach ($allPosts as $childPost){
            if($childPost->parent_id == $current_id){
                echo $childPost->name . ', ';
            }
        }
        echo '<br>';
    }
}

Outputs the following:

Outer 1 : Inner 1.1, Inner 1.2, 
Outer 2 : 
Outer 3 : 
Outer 4 : Inner 4.1, 
Outer 5 : Inner 5.2, Inner 5.2, Inner 5.3, 

If the problem is not in your code (which looks okay to me, and also works as expected on my computer) it may be in the structure of the $posts array. Try and use var_dump on the variables to see if they contain incomplete or incorrect data.

Comments

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.