Models in mvc (best practices, PHP)

2020-06-18 10:05发布

问题:

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!

回答1:

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();
}


回答2:

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/