Where can I put a database query in MVC?

In the past few days, I have read books and web pages about OOP and MVC in PHP extensively so that I can become a better programmer. I understood a little problem in my understanding of MVC:

Where to place mysql_query ?

Should I put it in a controller and call a method on a model that returns data based on the provided request? Or should I put it in the model itself? Are both options that I provide complete trash?

+6
source share
5 answers

MVC Related Materials

You could list the books you read, because most (if not all) php books that deal with MVC are wrong.

If you want to become a better developer, I would recommend you start with an article by Marting Fowler - GUI Architectures . The following are books from the same author, "Enterprise Application Architecture Templates . " Then the next step is to research SOLID principles and understand how to write code that follows the Law of Demeter . This should cover the basics =]

Can I use MVC with PHP?

Not really. At least this is not a classic MVC, as it was specific to Smalltalk .

Instead, in PHP, you have 4 more templates that are aimed at the same goal: MVC Model2, MVP, MVVM, and HMVC. Again, I'm too lazy to write about the differences again, so I'll just get back to the old comment.

What is a model?

The first thing you should understand is that Model in MVC is not a class or object. This is a layer that contains many classes. Basically, a model layer is all layers combined (although the second layer should be called "Object Object Layer" because it contains "Domain Model Objects"). If you want to read a brief summary of what is contained in each part of the model layer, you can try reading this old comment (go to the "side note" section).

Model layer consists of all the 3 concentric circles
Image taken from Fowler's Service Level article.

What do controllers do?

The controller has one important responsibility in MVC (I will talk about the implementation of Model2 here):

Run commands on structures from the model level (services or domain objects) that change the state of these structures.

Usually it has a secondary responsibility: to bind (or otherwise transfer) structures from the model level to the representation, but this becomes a dubious practice if you follow the SRP

Where to put the SQL related code?

The storage and retrieval of information is processed at the data source level and is usually performed as a DataMapper (do not confuse it with ORMs that abuse this name).

Here's how to make it easier to use:

 $mapper = $this->mapperFactory->build(Model\Mappers\User::class); $user = $this->entityFactory->build(Model\Entities\User::class); $user->setId(42); $mapper->fetch($user); if ($user->isBanned() && $user->hasBannExpired()){ $user->setStatus(Model\Mappers\User::STATUS_ACTIVE); } $mapper->store($user); 

As you can see, in no case does the domain object know that the information from it has been saved. And neither one nor the other, about where you put the data. It can be stored in MySQL or PostgreSQL or some noSQL database. Or maybe clicked on the remote REST API. Or maybe the cartographer was a manner for testing. All you need to do to replace mapper provides this method with a different factory.

Also see these related posts:

+15
source

Models and classes of objects represent data and application logic, which many call business logic. Usually his responsibility for:

  • Saving, deleting, updating application data. Typically, it includes database operations, but performing the same operations that invoke external web services or APIs is not unusual.
  • encapsulation of application logic. This is the layer that should implement all the application logic.

Here is the MVC sequence diagram that shows the stream during an HTTP request:

enter image description here

In this case, the model is the best place to implement the code available to access the database.

+7
source

First, do not use mysql_query() and family; they are outdated, so consider the study of PDO and / or mysqli as well.

The model takes care of data processing; it provides an interface to the controller through which it extracts and / or stores information. Thus, this will be the main place where database actions take place.

Update

To answer the question posed by OP in the comments: "one common model for all db or a model for each table / action?"

Models are designed to abstract individual tables (although there are models that process only one table); for example, instead of requesting all the articles and then asking for usernames for authors, you will have one function:

 function getArticles() { // query article table and join with user table to get username } 

How many models you create depends largely on how big the project is and how the data is interconnected. If you can identify independent data groups, you will probably create a model for each group; but this is not a complicated and quick rule.

Data processing can be part of the same model if you do not need a clear separation between read-only and write-only models (I would not know a situation that justifies this, but who knows).

+2
source

The model contains domain objects or data structures that represent the state of the application. [wikipedia] . Thus, the model will be the place to invoke the database.

In the classic (absence of the best word atm) MVC template, the view will receive the current state from the model.

Do not make a mistake by saying that the model is designed to access the database. It is more than just access to a database.

+2
source

To go further, your model should not contain a database access code. This refers to another layer outside the Model / View / Controller: it is called a persistent layer , which can be implemented using the Object-Relational Mapper , for example, the popular Doctrine 2 for PHP.

That way you never touch any (my) SQL code. Persistence layer takes care of this for you. I really advise you to take a look at the Doctrine tutorial, this is a really professional way to build your applications.

Instead of working with raw data loaded from a database, you create objects that contain your data and the behavior associated with it.

For example, you might have a User class, for example:

 class User { protected $id; protected $name; protected $privileges; public function setName($name) { ... } public function getName() { ... } public function addPrivilege(Privilege $privilege) { ... } public function getPrivileges() { ... } } 

The controller will only interact with objects:

 class UserController { public function testAction() { // ... $user = $em->getRepository('User')->find(123); // load User with id 123 $user->setName('John'); // work with your objects, echo $user->getName(); // and don't worry about the db! $em->flush(); // persist your changes } } 

Behind the scenes, ORM does all the low-level work of issuing a SELECT query, instantiating an object, detecting changes in your object, and issuing the necessary UPDATE !

+1
source

Source: https://habr.com/ru/post/916208/


All Articles