Jump to content

MVC, how to approach a problem


simon_w

Recommended Posts

Hi everyone,

 

So I'm relatively new to OO PHP and moreover, OO PHP with MVC design pattern.

 

This may be a largeish post so please bear with me on this one!

 

So here is a scenario that I'd like to understand. There are likely multiple ways to go about this, but it'd be nice to see what is said.

I'll include what I think should be the solution here and hopefully i'll get some feedback about it.

 

Scenario:

A page needs to display a list of "parts" for a car. A database table already exists with these parts. The list of parts on the page need to be ordered by name on first load, but then can be re-ordered by users using a drop down list. They can also be filtered, and searched.

 

A page also exists to display a single car part. 

 

What I think should be, and what i'm struggling with:

 

Model:

  • I will have a "part" object which represents an individual car part.

  • The part object will use a database abstraction layer. On "new Part()" will generate an empty object. ->Load( id ) will load an individual part.

 

Controller:

 

I do not know how I would implement this. I know it would contain methods to Filter(), Search() and Order() and that would directly access the Model.

 

View:

 

I am lost here too, I need to display a list of car parts, and on another page, a single car part. I understand I should use the same Model for both. However I do not see how I would list the parts. 

 

 

Some Questions:

 

  • Should I have another "model" that is a list of the "Part" model called PaetListModel, or should "Part" be able to generate that list?
  • I clearly should have 2 views, one for singular part, one for list of parts. Should the view access the model to generate the list before using the data for output?
  • Should the controller be used in the view instead of the model to generate the initial list (or singular) on page load?
  • Should the filter functions in the controller reload the "PartsList" from wherever our list is stored? 

 

I think the most important question for me though is: 

 

How would YOU implement the above green scenario? 

 

I would like to learn from peoples examples so I get an idea of what road to follow

Link to comment
Share on other sites

You have a few questions rolled into a single post here. I'll try to answer as many of them as i can inline then maybe provide an example of sorts.

 

Model:

I will have a "part" object which represents an individual car part.

The part object will use a database abstraction layer. On "new Part()" will generate an empty object. ->Load( id ) will load an individual part.

This is pretty much spot on. You would "model" your part using a class.

 

Controller:

 

I do not know how I would implement this. I know it would contain methods to Filter(), Search() and Order() and that would directly access the Model.

You should try and keep the methods in your controllers as small as possible. Most of the logic should be abstracted out into other objects. Avoid interacting with "models" within your controllers. While it may seem like the easiest option, it is also the route that leads to code duplication.

 

At minimum there should be a "repository" between your controllers and the models. You can then ask the repository to get whatever data you need.

 

View:

 

I am lost here too, I need to display a list of car parts, and on another page, a single car part. I understand I should use the same Model for both. However I do not see how I would list the parts.

You need multiple views. You are displaying multiple types of data.

 

Some Questions:

 

Should I have another "model" that is a list of the "Part" model called PaetListModel, or should "Part" be able to generate that list?

I clearly should have 2 views, one for singular part, one for list of parts. Should the view access the model to generate the list before using the data for output?

Should the controller be used in the view instead of the model to generate the initial list (or singular) on page load?

Should the filter functions in the controller reload the "PartsList" from wherever our list is stored?

I've already answer the first two of these and the second two don't really apply/make a lot of sense.

 

I'm going to try and build a very simple example, using mostly pseudo type code. How this the controllers are called and that sort of thing would really depend on the framework you are using. If you're not using a framework, you're doing it wrong. Find one and learn it.

 

Model

<?php

class Part
{
  protected $id;
  protected $name;
  protected $description;

  public function setId($id)
  {
    $this->id = $id;
  }

  public function getId($id)
  {
    return $this->id;
  }

  public function setName($name)
  {
    $this->name = $name;
  }

  public function getName($name)
  {
    return $this->name;
  }

  public function setDescription($description)
  {
    $this->description = $description;
  }

  public function getDescription($description)
  {
    return $this->description;
  }
}
Repository

<?php

class PartRepository
{
  public function findById($name)
  {
    // some logic to find a Part by id and return it
  }

  public function findByName($name)
  {
    // some logic to find a Part by name and return it
  }

  public function all()
  {
    // some logic to get all parts
    // returns a collection of Part objects
  }

  public function findLike($name)
  {
    // some logic to find Parts where name like $name
    // returns a collection of Part objects
  }

  public function persist(Part)
  {
    // some logic to save a Part to the database
  }
}
The Controller

<?php

class PartsController
{
  protected $view;
  protected $repo;

  public function __construct(View $view, PartRepository $repo)
  {
    $this->view = $view;
    $this->repo = $repo;

    $this->view->setLayout('layout.html.php');
  }

  /**
   * Used to display a list of all parts
   */
  public function index()
  {
    $parts = $this->repo->all();
    return $this->view('list.html.php', $parts);
  }

  /**
   * Used to display a single part
   */
  public function show($id)
  {
    $part = $this->repo->findById($id);
    return $this->view('show.html.php', $part);
  }

  /**
   * Used to search for a list of parts
   */
  public function search($name)
  {
    $parts = $this->repo->findLike($name);
    return $this->view('list.html.php', $part);
  }
}
layout.html.php

<html>
  <head>
  </head>
  <body>
    <?php echo $content; ?>
  </body>
</html>
list.html.php

<ul>
<?php foreach ($parts as $part): ?>
  <li><a href="/<?php echo $part->getId(); ?>"><?php echo $part->getName(); ?></a></li>
<?php endforeach; ?>
</ul>
show.html.php

<h2><?php echo $part->getName(); ?></h2>
<p><?php echo $part->getDescription(); ?></p>
Like I said, a VERY simple example. But hopefully it's enough to let you easily see the different layers, and to get an idea about how they might interact. I didn't implement any search or filter, I'm hoping that shouldn't be too hard to see how that would simply be another method on the controller though.
  • Like 1
Link to comment
Share on other sites

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.