Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Models in mvc (best practices, PHP)

I know there are plenty of articles and questions about MVC and best practices, but I can't find a simple example like this:

Lets say I have to develop a web application in PHP, I want to do it following the MVC pattern (without framework). The aplication should have a simple CRUD of books.

From the controller I want to get all the books in my store (that are persisted in a database).

How the model should be?

Something like this:

class Book {
    private $title;
    private $author;

    public function __construct($title, $author)
    {
        $this->title = $title;
        $this->author = $author;
    }

    public function getTitle()
    {
        return $this->title;
    }

    public function setTitle($title)
    {
        $this->title = $title;
        return this;
    }   
.
.
.


class BooksService{

    public getBooks(){
        //get data from database and return it

        //by the way, what I return here, should by an array of Books objects?
    }

    public getOneBook($title){
        //get data from database and store it into $the_title, $the_autor
        $the_book = new Book($the_title, $the_autor);
        return $the_book;
    }
.
.
.

So I call it(from the controller) like that:

$book_service = new BooksService();
$all_books = $book_service->getBooks();
$one_book = $book_service->getOneBook('title');

Or maybe should be better have everything in the Books class, something like this:

class Book 
{
    private $title;
    private $author;

    //I set default arguments in order to create an 'empty book'...
    public function __construct($title = null, $author = null)
    {
        $this->title = $title;
        $this->author = $author;
    }

    public function getTitle()
    {
        return $this->title;
    }

    public function setTitle($title)
    {
        $this->title = $title;
        return this;
    }   

    public getBooks(){
        //get data from database and return it

        //and hare, what I should return? an Array?
    }

    public getOneBook($title){
        //get data from database and store it into $the_title, $the_autor
        $the_book = new Book($the_title, $the_autor);
        return $the_book;
    }
.
.
.

So I call it(from the controller) like that:

$book_obj = new Book();
$all_books = $book_obj->getBooks();
$one_book = $book_obj->getOneBook('title');

Or maybe I'm totally wrong and should by in a very different way?

Thank you!

like image 272
jolmos Avatar asked Oct 30 '15 09:10

jolmos


2 Answers

Looking at your two solutions, ask yourself - what happens if you want to start adding more and more types of lookup (by Author, Title, Date). Should they belong in the book model? (a model being a representation of a Book). No would be my answer.

The Book class should be a representation of your Book (Title, Number of pages, Text, etc) - stored in the database in this case.

In my opinion your first approach is your best approach - separate your business logic of looking up a Book into a separate object (following your convention I would suggest something like BookLookupService), which is responsible for looking up a book instance, for example:

interface IBookLookupService {
    findBookByTitle($bookTitle);
    findBooksByAuthor($authorName);
    getAllBooks();
}
like image 154
Joseph Woodward Avatar answered Sep 29 '22 18:09

Joseph Woodward


Both ways are correct and correspond to two different patterns.

Your first idea could be associated with the Data mapper pattern. In this case your book class doesn't have to know anything about the database, and let another class worrying about database operations. This is the pattern use by projects like Doctrine2 or Hibernate (I think)

The second one is known as Active record pattern where you keep everything in a single class and your book object has to manage its own persistence. This is the pattern used by Ruby on Rails.

The first approach generally give you more flexibility but second one may look more intuitive and easy to use.

Some informations:

http://culttt.com/2014/06/18/whats-difference-active-record-data-mapper/

like image 41
Needpoule Avatar answered Sep 29 '22 19:09

Needpoule