Is my design achieving Separation of Concerns in this MVC implementation?
Summary with answers below


MVC gone bad

I allready wrote an article on how MVC is abused, so I'm not going to repeat myself here.

So what is MVC?

MVC is a design pattern (or architectual pattern or even cake) that seperates our code into 3 distinct functionalities: Model, View and a Controller.

Model

The Model represents the Data. For instance a Student.

View

A view presents those Models. For instance in a table. It thus acts purely as representation layer.

Controller

The controller is the part that gets a command from the user/client and translates it to the correct internal command. e.g. "show user with id 4" => "pas the User Model with id 4 to the correct view"

Implementation

What MVC doesn't do is tell you anything about how you implement it. It also doesn't tell you how these different components interact.

MVC doesn't say anything about using other code. A lot people cram everything into MVC. So are you. Your Model is not a Model but a Repository (or Mapper or whatever you call it). Your Model acts as a layer to query your MySQL database that returns an object that represents your data.

Implementing the model:

the Student model will have method that will help you get information about the Model. For instance:

function getFullName() {
    return $this-&gt;firstName . ' ' . $this-&gt;lastName;
}


Retrieving the model

We ofcourse need a way of retrieving a Model. This could be done for instance using a Repository:

interface UserRepository
{
    public function find($id)

    public function getBy($key,$value)
}


and because we use Mysql, lets implement a repository that does all the fetching:

class MysqlUserRepository implements UserRepository
{
    public function find($id)
    {
        $result = $this-&gt;db-&gt;query('SELECT FROM users WHERE id = '.$id;
        return new User($result[0]);
    }

    public function getBy($key,$value) { ... }
}


This UserRepository could for instance be injected into the controller:

Implementing the controller

class UserController
{
    public function find($id)
    {
        $user = $this-&gt;repository-&gt;find($id);

        return ViewFactory::make('show.user', array('user'=&gt;$user)));
    }
}


Here the UserController returns a View object. I opted for a Factory pattern approach here:

ViewFactory &amp; view

class ViewFactory
{
    public static function make($viewName, $data) {
        $view = new View(VIEW_DIR . $viewName);
        $view-&gt;addData($data);
    }
}


And our view will look someting like this:

class View
{
    public function __construct($viewFile)
    {
        $this-&gt;viewFile = $viewFile;
    }

    public function addData($data)
    {
        $this-&gt;data = array_merge($data, $this-&gt;data);
    }

    public function render()
    {
        extract($this-&gt;data);
        include $this-&gt;viewFile;
    }
}


Implementing our view


  Because I don't like writing $this->data->.. stuff in my templates, I use the extract function in the render function.


views/dir/show.user.tpl.php

&lt;h1&gt;&lt;?php echo $user-&gt;getFullName(); ?&gt;
&lt;p&gt;Age: &lt;?php print $user-&gt;getAge(); ?&gt;


Just an Example.

Now this is just an example - and it should be treated as one.

Summary

to answer your questions


  Do I require a getter or a setter, say $searchCritera, here so I can maintain Separation of Concerns?


No, why should searchCriteria be seperated? A searchCriteria needs context:

UserRepository::getById(4);


returns something completly different as

UserRepository::getOlderThenYears(4);



  Would it be wrong to simply query the model from the view with
  findStudentsByID(4);? Wouldn't that bind the two too much?


YES, very wrong. A view is a presentational piece of software. It is stupid an knows nothing. Only how to present a certain object to the screen. Nothing more.

Models

Instead of using getters/setters on a Model. One could simply use public variables (or emulate them using the magic methods (PHP)). Since a Model is a representation of data, you could simply change it's values. After changes are made one could pass it back to the repository:

$user = Repository::find(4);
$user-&gt;name = 'foobar';
Repository::save($user);