Php – Is it wrong to have HTML strings within PHP objects, or is it only wrong in controllers

design-patternsmvcPHP

I've always thought that in typical MVC design it is bad practice to build & concatenate HTML strings in any PHP file or class that isn't strictly a template.

I'm working on a large project with strict guidelines in place, and while it is forbidden to put any HTML code in the PHP controller, it is fair game to have PHP sub-objects that might generate lots of HTML code strings which then get passed into the template.

These "sub-objects" contain additional logic that could change the HTML depending on conditions.

Thus my 2 main questions are:

  1. Is this considered MVC?
  2. Are these objects considered part of the View, or are they a frankenstein of the Model and the View?

Example:

<?php
/* controller.php */
class KittenController {

    protected $view = 'view.html';

    public function render (Request $request) {
        $data = $this->getDynamicData(); // get some data
        $object = $this->getObject();  // get a PHP object
        $this->setField('foo', $data['bar']);
        $this->setField('baz', $object->render());
    }
}

 

<?php
/* object.php */

class Object {
    public function render () {
        $html = '';
        $html .= '<div class="my-cool-html">';
        if ($this->hasDuck()) {
            $html .= '<p>I have a duck...</p>';
        }
        else {
            $html .= '<p>No duck here...</p>';
        }
        $html .= '</div>';

        return $html;
    }
}

 

<!-- an html template -->
<html>
<body>
<div class="blah">
    [[foo]]
</div>
<footer>
    [[baz]]
</footer>
</body>
</html>

Best Answer

The whole idea of MVC is Separation of Concern and by introducing any method that builds/generates any form of mark-up like what you are doing in your example, even without directly outputting them, you're violating that. So this is not MVC anymore.

In your example changing the desing/mark-up by a designer needs modification in your object.php by a programmer. Also you might end up with a mess like mark-up is everywhere in your project classes and your actual Views are just the general layout.

If you are not building anything on top of MVC, then of course you can build different layers, structure you application differently and also have some mark-up generated by classes like what you have in your example; However the later approach is not generally recommended.

What I recommend is to re-factor your Object class to something like the following, where you still have the separation of concern applied; Your PHP code inside the render method will take care of the business logic and the proper Partial View will be loaded and returned in the end.

class PetHelper {

    private $view = null;

    public function render ( Child $child ) {

        if ( true === (bool) $child->hasPuppy() ) {
            $this->view = 'walk-the-puppy.html';
        } else {
            $this->view = 'play-with-kitten.html';
        }

        return $this->view;
    }
}