0

I start to understand about the Model-View-Controller pattern by now except one thing that I think I am stuck, the Model part of the pattern.

I now have successfully made the Controller and the View work by simply routing the request, grab the parameters and parse them to the proper controller that extends the core functions and generates the view.

Now I don't really know how to make the Model work. As far as I know, Model is just the structure of the data so here I have the file called Article.php which is the model for blog content

Article.php

<?php
class Article extends Database {
    public $id;
    public $topic;
    public $content;
}
?>

This class extends the Database class as shown down here

Database.php

<?php
    class Database {

    // Current connection which only one connection is allowed in this version
    protected $connection;

    // MySql Setting Array
    protected $dbsettings = array();

    public function __construct() {
        require_once 'bin/config/db.php';
        foreach($db_setting_array as $k => $v) {
            $this->dbsettings[$k] = $v;
        }

        $this->connection = new mysqli(
            $this->dbsettings['server'],
            $this->dbsettings['username'],
            $this->dbsettings['password'],
            $this->dbsettings['database']
        );
    }

    public function inject($qr) {
        $result = $this->connection->query($qr);
    }

    public function call($qr) {
        $result = $this->connection->query($qr);
        return $result;
    }
}
?>

and the Article class is loaded by the buildData method from blog.php with Blog class that extends the core Controller

Blog.php

<?php
 class blog extends Controller {

    protected $article;

    public function __construct() {
        /* Load data structure of Entry.php */
        $this->article = $this->BuildData('Entry');
    }

    public function all($linkname='LINK BACK HOME') {
        $this->loadtemplate('blog/blog', array('linkname'=>$linkname));
    }

    public function each($blogid = '') {
        // Query the database here
        $result = $this->article->call('select * from articles where id='.$blogid);
        while($rows = $result->fetch_assoc()) {
            $data['id'] = $rows['id'];
            $data['title'] = $rows['title'];
            $data['content'] = $rows['content'];
        }
    $this->loadtemplate('blog/each', $data);
       $query = 'insert into articles(title, content) values (\'test2\', \'test2\')';
       $this->article->inject($query);
    }
};
?>

You can see that inside the Database.php I declared two methods which are inject and call which are used to query the database and I use this in the Blog.php which extends the core controller.

With all of these codes, I don't have to do anything with the model. I can just use the "inject" and "call" method that I declared to query the database and parse the array of the result to the view as seen in the Blog.php.

So how Model really works and if I want to use it? Or how should it be updated at, the controller or inside the Model class itself?

halfer
  • 19,824
  • 17
  • 99
  • 186
H.J. Frost
  • 303
  • 1
  • 3
  • 14
  • "Model is just the structure of the data" - it is generally the way in which you read/write the data itself too. You may find the best way to understand models is to run through some tutorials on MVC-like frameworks, such as Laravel or Symfony/Doctrine. – halfer Dec 26 '14 at 17:49
  • In your `each()` method, you have a query that needs to be _parameterised_ - as it stands it appears vulnerable to _SQL injection_. – halfer Dec 26 '14 at 17:52
  • Since your `$result` will only ever return one row (assuming `id` is a primary key) there is no need for a `while` loop - just use an `if` here instead. Personally I would move some of this code to the model - whose purpose is to abstract away some of the details of reading/writing to that table. – halfer Dec 26 '14 at 17:54
  • My jaws have just hit the ground just now. I think I have to get back home and study about MVC frameworks over and over. Thank you very much for this helpful comment. – H.J. Frost Dec 26 '14 at 18:25
  • @H.J.Frost are you looking for something like this ? http://stackoverflow.com/a/5864000/727208 – tereško Dec 27 '14 at 02:18

1 Answers1

0

The Model is supposed to interact with the Database class since in an MVC model Model is responsible for fetching the data, process it and pass to the view. In your case the blog class (which derives from Controller) which does not follow MVC model. Instead it should instantiate an "article" class instance and pass the control to "article" class to fetch the data from database.

You article.php should look like

<?php
class Article extends Database {
    public $id;
    public $topic;
    public $content;
    public $database; //Dependency injection

    //This method has been moved from the blog class
    public function each(&$data, $blogid = '') {
        // Query the database here
        $result = $this->database->call('select * from articles where id='.$blogid);
        while($rows = $result->fetch_assoc()) {
            $data['id'] = $rows['id'];
            $data['title'] = $rows['title'];
            $data['content'] = $rows['content'];
        }
    }

    public function inject() {
        $query = 'insert into articles(title, content) values (\'test2\', \'test2\')';
        $this->database->inject($query);
    }
}
?>

and the blog.php should be

<?php
class Blog extends Controller {

    protected $article;

    public function __construct() {
        /* Load data structure of Entry.php */
        $this->article = $this->BuildData('Entry');
    }

    public function all($linkname='LINK BACK HOME') {
        $this->loadtemplate('blog/blog', array('linkname'=>$linkname));
    }

    public function getData($blogid = '') {
       $data = array();
       $this->article->each($data, $blogid);
       $this->loadtemplate('blog/each', $data);
       $this->article->inject();
    }
}
?>

Couple of things to notice:

  1. The model only interacts with data. In future if you change the datastore (move to cloud from the database) you need to change only the model.
  2. The controller has all the business logic to construct the view based on the data. When your application gets complicated the controller will change. This design principle is called "separation of concerns" where the controller and the model are responsible for completely separate functionalities now.
halfer
  • 19,824
  • 17
  • 99
  • 186
Diptendu
  • 2,120
  • 1
  • 15
  • 28