Jump to content

Do I understand MVC correctly now?


Go to solution Solved by ignace,

Recommended Posts

I've been working with what I thought was MVC for quite a while but now after researching it some more, it appears I may have been wrong all along. I think I have been using the model incorrectly. Is my new way of thinking now correct?

 

Model: These are like objects that hold data during the session (page load). It can also dump the data to the database but is mainly used to hold data related to a specific object for use throughout the current page load.

 

Controller: There will usually only be one as it is like a gatekeeper that directs requests to the proper model.

 

View: These will usually be the .php pages themselves but for views that are reused, it can be an isolated class which generates HTML code (like loading a select element with user names).

 

I have built a program where a quote is requested by the user and the program has to go to the database in order to get the details of the quote to display them on screen. Right now my view is making the request through the controller to the model and the model is fetching each piece of requested information from the database, then passing it back through to the view as needed. Because the page can show the same information in various places, the same database call by the model can be made more than once for that specific information. Should I be making a request for the entire quote, building a quote object with the model and then passing that entire object back to the view to be used instead? This will introduce a lot of getter/setts methods of which I currently have none.

 

I'm assuming I would have a customer model which would build a customer object and return that. Then a quote model would build a quote object and return that. Same for purchase orders and users, all which will have information appearing on the quote or purchase order.

 

Thanks a lot, I'm really trying to research this as much as I can and get it correct.

Link to comment
https://forums.phpfreaks.com/topic/301664-do-i-understand-mvc-correctly-now/
Share on other sites

it's hard to build a good framework in my opinion...i'm currently re-designing mine which i made 3 years ago....but with mine you have the view, modlel, controller but also the module which i get quite confused at and have yet to understand fully what's used for...that aside as you questions are not too specific and i'd suggest to download a framework such as zend (like i did) and spending time reading the manuel and stripping apart the code to understand the logic and the design of a framework

 

first of all i have a router class which matches routes to a specific uri, then the controller, action and parameters are dispatched and load the contoller... the controller i'm able to access the view and the model 

 

i think if your trying to build a mvc, which is good in my optioin, cause i hate to use code i haven't written myself, then you you need to break down what each element does and how it's going to perform, plus cut out all the BS! inbetween.

 

posting some code would be useful and maybe we could give you some points.

Edited by Destramic

To answer the question: No, you should not write model classes by hand, because then you'll spend an enormous amount of time and code on a trivial problem (passing data to different views). I see two possible approaches:

  • Forget about trying to implement a “pure” version of MVC and simply write data classes which fetch the required information. The methods can return plain associative arrays, they don't have to do anything fancy.
  • Integrate a full-blown library which has already solved the model problem (e. g. an object-relational mapper like Doctrine).

The first solution is obviously the quickest and doesn't require you to learn anything new. It makes sense if your application is simple. An ORM is suitable for complex applications.

 

In general, there are no fixed laws for how MVC must be implemented. You'll find different competing approaches, and it's ultimately up to you to choose the right one for your specific project

 

 

 

View: These will usually be the .php pages themselves but for views that are reused, it can be an isolated class which generates HTML code (like loading a select element with user names).

 

A view should be a template written in a specialized template language like Twig or Smarty. I understand that some programmers think PHP itself is a template engine, but that's hardly true. PHP sucks at templating. It's verbose, it doesn't have any modern features (inheritance, auto-escaping, custom syntax), and it's insecure by design.

Edited by Jacques1

Guru is correct stating that there is no fixed laws for how MVC must be implemented. There are three or four different “core” MVC implementations and unnumbered parallaxes. For example in the MVC implementation that I am programming more often the statement of Guru:

No, you should not write model classes by hand, because then you'll spend an enormous amount of time and code on a trivial problem (passing data to different views).

 

doesn't make any sense , (I really can't understand what is the “model” in this implementation if not classes that you write by your hand , of course there are tools that helps you writing plain objects / data workers e.t.c. but code generators are irrelevant to the MVC pattern , in my point of view).

 

Back to the question. First of all I understood what you meant by “session” but it will easier for you to adopt some other term (e.g. the life cycle of the request) because in web programming “session” has a completely different meaning. Having said that there is nothing terrible wrong with your approach. Let me just make some comments in my perspective , and having in mind the MVC implementation I write more comfortable at:

 

Model: These are like objects that hold data during the session (page load). It can also dump the data to the database but is mainly used to hold data related to a specific object for use throughout the current page load.

 

Yes model also updates / creates / inserts in the data layer (that layer might be also an external web service , but yes most common it is a db). I have a question in “a specific object for use throughout the current page”. Even in active record pattern , model is not used for a specific object exclusive. Model will create any objects (or lists of them) that the controller needs.

 

I have more minor comments but MVC is a very old way (even before we call it MVC) of separating the logic of a program in layers upon their functionality and if your implementation doesn't do something awfully weird than its ok. 

My name is Jacques1.

 

You don't seem to understand the problem at hand. DeX currently doesn't have any infrastructure for handling object-relational mapping, data persistence etc. His idea is to build an ad-hoc ORM with dozens of hand-written getters and setters for the different attributes.

 

This is terrible and plain nonsense, because clearly this task can and should be automated. So the two sensible alternatives are to either forget about ORM altogether or use an established library which provides an actual ORM infrastructure.

Hello Jacques1 , sorry for calling you Guru (the Guru was really large and I was confused that this is your nick). I also use a type of code generator for plain objects that comes directly out of a DB table , of course in several occasions I have to add some properties and getters and setters to them because the business logic might need those. Also I use code generators for data workers and instantiators , but I don't find this crucial , in fact I would never advise anyone that is just beginning understating OOP and MVC to use code generators before fully understands what she or he is doing. 

So you're saying he should literally write getters and setters for every single attribute of every single table, plus all the code for loading and saving the data? Are you kidding?

 

If this is your “solution”, I suggest you write the classes for DeX and maintain them for the entire lifetime of the application. Good luck.

I wasn't necessarily going to build setters and getters for every single database column. For example, if I have a quote I need to display on the page, I would build a customer object and set all the customer details in that so the getters can retrieve it to display on the page, it's only name, address and phone number. Then I would have a quote object which would set things like the quote price, the quote expiry date and a list of all the upgrade options to show on the quote, along with their attributes like width, height and quantity.

 

Then when doing purchase orders, I would build a bill of materials (BOM) object that would contain all individual building products and their attributes. Is this wrong? I'm mostly wondering how to separate the model into multiple models because I mainly just have one right now with all the methods in it.

The question is: Why would you want to write all those model classes by hand?

 

It makes perfect sense to use an ORM library which creates the classes automatically. It also makes perfect sense to avoid ORM and just go with classical queries. But your approach sounds like a weird typing exercise.

 

If this is exactly what you want, I won't stop you.

The question is: Why would you want to write all those model classes by hand?

 

It makes perfect sense to use an ORM library which creates the classes automatically. It also makes perfect sense to avoid ORM and just go with classical queries. But your approach sounds like a weird typing exercise.

 

If this is exactly what you want, I won't stop you.

No not at all, I very much appreciate the guidance. If using an ORM library is the proper way to go for medium scaled PHP implementations, then that's what I will use. Just as long as it's better long term and not just short term. I want the best long term solution.

I wasn't necessarily going to build setters and getters for every single database column. For example, if I have a quote I need to display on the page, I would build a customer object and set all the customer details in that so the getters can retrieve it to display on the page, it's only name, address and phone number. Then I would have a quote object which would set things like the quote price, the quote expiry date and a list of all the upgrade options to show on the quote, along with their attributes like width, height and quantity.

 

Then when doing purchase orders, I would build a bill of materials (BOM) object that would contain all individual building products and their attributes. Is this wrong? I'm mostly wondering how to separate the model into multiple models because I mainly just have one right now with all the methods in it.

No, that is correct DeX. Though like Jacques1 mentioned an ORM like Doctrine allows you to generate most of your code. If you use a decent IDE you might have that option too.

 

No not at all, I very much appreciate the guidance. If using an ORM library is the proper way to go for medium scaled PHP implementations, then that's what I will use. Just as long as it's better long term and not just short term. I want the best long term solution.

You'll have an ORM whatever way you turn it. If you use OO then you need an ORM in one form or another. You either use Doctrine or write your own Mapper. Doctrine might be even more efficient then your own Mapper code as the project grows. Experience teaches you if a project is small or medium and will remain this way.

Edited by ignace

Thank  you. One more question, if I'm getting the price of the quote, how do I know if that's already in the model object or if I need to get it from the database? For example, the first time I need to fetch the price, I would go to the database, get it, then set it in the quote model. The next 10 times I need to get that price while displaying the same page (in various places), I don't want to keep going back to the database for the price, how do I know if I can retrieve it from the model object using the getter? Do I have a piece of code in the getter that checks to see if the local variable is set and return if so?

  • 5 months later...

You would construct full objects at all times. Only load (objects) what you need for each request.

If you are going to display a qoute to the user, load all quote data.

 

So that makes sense, are you saying I would build a quote object that contains all information I could want about the quote and then just specify what I want from that object in various places on the page? So for instance I would show $quote['id'] in a few places, then show the $quote['price'] where it needs to go and keep using it that way?

  • Solution

Kinda, it would be something like:

 

class Quote {
  private $id;
  // .. other fields
  private $price;
  
  public function setId($id) { $this->id = $id; }
  public function getId() { return $this->id; }
  
  // get*, set* for the other fields

  public function setPrice($price) { $this->price = $price; }
  public function getPrice() { return $this->price; }
}
Then you would create a query and populate this object:

 

$sql = 'SELECT id, .., price FROM quotes';
$stmt = $this->db->prepare($sql);
foreach ($stmt->fetchAll() as $row) {
  $quotes[] = $quote = new Quote;
  $quote->setId($row['id']);
  $quote->setPrice($row['price']);
}

return $quotes;
At this point you can work with this object as:

 

$quote->getId();
$quote->getPrice();
Now before you start writing all of this yourself, there are frameworks available online that do this sort of thing for you. A list can be found here:

https://github.com/ziadoz/awesome-php#database

or just fetch them as "quote" objects

$sql = "SELECT 
            id
          , price
        FROM quote";
$res = $db->query($sql);
$quotes = [];
while ($obj = $res->fetchObject('quote')) {     // fetch as class 'quote'
    $quotes[] = $obj;
}

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.