PHP OOP MVC Project Structure I'm a beginner in OOP and PHP frameworks.  I used slim skeleton to create a project and designed the project in this way. 

Project structure is given by the slim skeleton. Object Mappers are added by my self. I want to know whether this is a good practice. What I'm doing wrong here. Is there any better way to do this?

src
   Controllers
      PostController.php
      CommentController.php
   Models
      Post.php
      Comment.php
   ObjectMappers
      PostMapper.php
      CommentMapper.php
   Dependencies.php
   Middleware.php
   Routes.php
   Settings.php


Model files are used to include queries for relevant class. 
Mappers are the real classes that used to map query results to necessary class.
Controllers are for necessary operations before sending it to the user.

Post.php

namespace App\Models;

class Post {

   public function getPostById($id){

      $sql = "SELECT `post_id`, `post` FROM `posts` WHERE `post_id` = :id";

      try {
         $stmt = $this-&gt;db-&gt;prepare($sql);
         $stmt-&gt;execute(['id' =&gt; $id]);
         $post = $stmt-&gt;fetchObject('\App\ObjectMappers\PostMapper');
         if($post){
            return $post;
         }
         return false;
      } catch (\PDOException $e){
         return false;
      }
   }

   // Other queries
}


PostMapper.php

namespace App\ObjectMappers;

class PostObject {

    public $post_id;
    public $post;

    public function __construct(){}

    public function getPost_id()
    {
        return $this-&gt;post_id;
    }

    public function setPost_id($post_id)
    {
        $this-&gt;post_id= $post_id;
        return $this;
    }

    public function getPost()
    {
        return $this-&gt;post;
    }

    public function setPost($post)
    {
        $this-&gt;post= $post;
        return $this;
    }
}


PostController.php

namespace App\Controllers;

class PostController {

   public function ($request, $response, $args){

      $postId = $request-&gt;getAttribute("post_id");

      if(!$postId){
         return $response-&gt;withJSON("post id not found");
      }
      $post = $this-&gt;Post-&gt;getPostById($postId);

      if(!$post ){
         return $response-&gt;withJSON("post not found");
      }

      return $response-&gt;withJSON($post);
   }
}


I'll be glad if you can help me. I'm trying to avoid using existing ORMs here.
This is good in general. The main point is that you confused a model and a mapper. Your mapper must be a model (or, to avoid a confusion, better to call it an entity) whereas your model is actually a mapper. 

People often mistake  the term "model", so I had to write an article to explain it.

So

src
   Controllers
      PostController.php
      CommentController.php
   Entities
      Post.php
      Comment.php
   Mappers
      PostMapper.php
      CommentMapper.php
   Dependencies.php
   Middleware.php
   Routes.php
   Settings.php


where Post.php would be

namespace App\Entities;

class Post {

    protected $postId;
    protected $post;

    public function __construct(){}

    public function getPostId()
    {
        return $this-&gt;postId;
    }

    public function setPostId($postId)
    {
        $this-&gt;postId= $postId;
        return $this;
    }

    public function getPost()
    {
        return $this-&gt;post;
    }

    public function setPost($post)
    {
        $this-&gt;post= $post;
        return $this;
    }
}


and PostMapper would be

namespace App\Mappers;

class PostMapper {

   public function getPostById($id){

      $sql = "SELECT `post_id`, `post` FROM `posts` WHERE `post_id` = :id";
      $stmt = $this-&gt;db-&gt;prepare($sql);
      $stmt-&gt;execute(['id' =&gt; $id]);
      return $stmt-&gt;fetchObject('\App\Entity\Post');
   }
}


Please note that a lot of code has been removed from PostMapper class. First, a harmful try .. catch has been removed. A try .. catch that silently returns false is as bad as any other error suppression operator, and shouldn't be used such casually. As a programmer, you crave to know what the error was, so you'll be able to fix it. So always let errors go, unless you have a certain handling scenario. See more in my article, PHP error reporting basics.

Also, rather useless condition is removed too, as fetchObject() already returns false if a row not found, so we can return its result right away. 

Also, consider making your PHP code style to conform with the standard