Static model in the view

Hi,
What do you think about putting static models
directly in the view ?
For instance using Doctrine you can
go through this way.
I found it very handy.

Bye

Static has gazillions of disadvantages. It should be doomed.

Imagine you need to manually assemble the data of 3 or more models. You will need some code to process them to conveniently generate an HTML output. Later you have to add output for JSON or RSS. You are screwed because all the logic to preprocess the models is in you view. You can do similar mistakes with ‘vanilla’ models, so - imo - the best bet is to throw pure data at your views.

In the end it’s a matter of your needs. Spaghetti code can work pretty well if you only need to develop/maintain it for 3 days.

Static methods should almost always be avoided. Static by very definition goes against PHP’s dynamic nature.

Cheers,
Alex

I don’t see a lot of difference between


// in controller/action
$model = new Model();
$this->view->data = $model->fetchAll();
// in the view
foreach($this->data as $row)//html

//AND
foreach(Model::fetchAll() as $row)//html



Here for me the model could be
just a wrapper (to call it statically)
for the really mapper.

Well you’re right in so far as the view should read directly from the model (rather than being fed data by the controller). But static methods break polymorphism and encapsulation. It ties your view to a specific model implementation and removes any possibility of reusability and creates a testing/maintainability nightmare. The model could potentially have its state changed from anywhere within the system at any time and you have no way of knowing.

Instead, do:


$view->model = new Model();

//Or better, a proper DI approach
new View(new Model);

The problem with your above code is that, because fetchAll is a static function, it cannot access any of the non static object variables.

Suppose you had the following:


class my_model extends model {
 $table = 'tablename';

 public function fetchAll() {
  $results = db_query($this->table);
  return $results;
 }
}

You can call the fetchAll method and it can access the object variable $table.

However, if the function was static, it could not access any object variables i.e. $table, and therefore the table name would have to be declared explicitly inside the function.

Static functions should be used in situations where they

  1. do not depend on any dynamic data associated with the object and
  2. do not change any data associated with the object.

For example, a validation function in your model could be declared as static:


class my_model extends model {
 $table = 'tablename';

 public function fetchAll() {
  $results = db_query($this->table);
  return $results;
 }
 
 public static function isValid($data) {
  if ($data == 'thisisvalidata') {
   return true;
  } else {
   return false;
  }
 }
}

Now you can check the validity of some data without having to initialise an object


if (my_model::isValid($data)) {
 // ....
}

@mrwooster
[The problem with your above code is that, because fetchAll is a static function, it cannot access any of the non static object variables.]

In my reply


the model could be 
just a wrapper (to call it statically)
for the really mapper

so I can do without trouble


public static function fetchAll()
{
    $mapper = new Mapper();
    return $mapper->fetchAll();
}

@TomB
It could be a point pass the class
instead of data.

Indeed, you could use a static method to initialise the object, but surly it is easier just to create the object and call the non static function rather than building a static function around it.