Home > Software design >  Problem retrieving a list of posts for an html view in php
Problem retrieving a list of posts for an html view in php

Time:05-05

I'm trying to use php build a blog website where all the posts are publicly available, but somehow I'm having issues getting the posts to actually display on the page.

The code for the query is:

<?php
    class Blog {
        private $db;
        
        public function __construct(){
            $this->db = new Database;
        }

        public function getBlogs(){
            $this->db->query('SELECT * FROM posts');
            $results = $this->db->resultSet();

            return $results;
        }

    }

The code for generating the view is:

public function __construct(){
           
            $this->blogModel = $this->model('Blog');
        }


        public function index(){
            // Get posts

            $posts = $this->blogModel->getPosts();

            $data = [
                'posts' => $posts
            ];

            $this->view('pages/blog', $data);
        }

And the actual HTML for the view looks like this:

<?php require APPROOT . '/views/inc/header.php'; ?>
    <div >
        <div >    
            <h1>Artículos</h1>
        </div>
    </div>
    <?php foreach($data['posts'] as $post) : ?>
        <div >
            <h4 ><?php echo $post->title; ?></h4>
            <a href="<?php echo URLROOT; ?>/posts/show/<?php echo $post->postId; ?>" >More</a>
        </div>
    <?php endforeach; ?>

<?php require APPROOT . '/views/inc/footer.php'; ?>

However, when I actually try to go to pages/blog, I get a Notice: Undefined index: posts in C:\xampp\htdocs\edutechne\app\views\pages\blog.php on line 7, meaning that the array is apparently not being passed to the view.

Any idea what might be wrong with my code?

EDIT: Someone asked that I include the code for the view so here it is:

public function view($view, $data = []){
         // Check for view file
         if(file_exists('../app/views/' . $view . '.php')){
            require_once '../app/views/' . $view . '.php';
         } else {
             // View does not exist
             die('View does not exist');
         }

     }

CodePudding user response:

A workaround and maybe a cleaner way of coding would be declaring the $data array as a property:

    class Blog {
        private $db;
        private $data;
        ...

Within your construction method you may now initiate the array like that:

    public function __construct(){
        $this->db = new Database;
        $this->data = ['posts' => ['no posts']]
    }

(The actual value depends on your data structure, passing a default value is not a bad idea. I just assumed an array holding one item 'no posts')

Within your index method you pass the results to the property:

    public function index(){
        ...
        $this->data['posts'] = $posts
        ...

Now you do not need to pass the $data to the method $Blog->view(), you can address it within. Remove the argument from the method declaration:

public function view($view){
   ...

And modify your for-each-loop like that:

<?php foreach($this->data['posts'] as $post) : ?>

But heads up: This way you need to make sure to properly populate and clean up the $data-property. It's now kind of persistant within the class instance.

CodePudding user response:

I am not used to this way of coding in php, but to me it looks like your function named index is reason you can't get what you need. Try adding return $data to your code so it looks like this:

public function index(){     

            $posts = $this->blogModel->getPosts();

            $data = [
                'posts' => $posts
            ];

            $this->view('pages/blog', $data);
            return $data;
        }
  • Related