I've recently been embarking on a mission to completely eliminate PHP code from my view files, here is why.
What are Views?
Often when you're building a website or application, if you build from scratch you end up doing a lot of the same kinds of things, like turning requests into specific pages, handling form validation, caching, etc.
A long while ago (in the 70's according to http://c2.com/cgi/wiki?ModelViewControllerHistory) Xerox Parc created the first MVC architecture, which was meant to act as a guide to how to develop software with a logical structure.
On the web, MVC shares the same basic principles and breaks down into these constituent parts:
- Models – the models should handle all the data within the application, such as pulling data from files and APIs, and making database calls
- Views – these should display the data and contain all of the front-end display stuff
- Controllers – the controllers handle the business logic for the application, and interprets all the user requests and makes decisions on how to handle them. Typically routing is handled by the controllers.
The idea is to separate the basic parts of the app to make code more manageable and reusable; a model for fetching user information can be used many times across the application, a view partial can be used within lots of other main views, and so on.
Views in Popular PHP Frameworks
I'm using the term framework a little loosely here, as some of what I'll be looking at are CMSs, but from working with them, this is what I see:
- this is the most popular PHP CMS in use right now, and doesn't follow a strictly MVC pattern, but it does have a semblance of views, which it calls the Loop. The WordPress Codex actively encourages a lot of PHP code in these templates in order to get anything useful done, even if it's simply echoing out the title of a page.
- Expression Engine
- lesser used now than it once was due to its age, this CMS is actually built on a true MVC framework. However, the CMS loses the MVC aspect of this. It does have templates that are their equivalent to views though. These are generally managed through the CMS, and by default are bereft of any PHP code. However, there is an option to include and process PHP in the templates if necessary.
- one of the most popular MVC frameworks for PHP given its size, speed, and easy learning curve. The official documentation for the views encourages using PHP (and some bad PHP, although that's another issue) in the views.
- this modern PHP framework has become incredibly popular in recent years. It offers a couple of ways of working with views: the old-school method which is HTML strewn with bits of PHP, or using the Blade templating engine. The latter keeps PHP out of the views.
- Out of the box Symfony offers the Twig templating engine, which keeps PHP out of the view entirely. This engine has been the inspiration of many others.
- Zend is quite old-school here, and its documentation instructs using PHP blocks within the HTML of your views, breaking in and out of PHP as you need.
Why is Mixing PHP and HTML Bad?
I'm not saying that this is the greatest sin that anyone could ever commit when it comes to PHP development, but it does have a few drawbacks:
- It makes development between front and back end teams more difficult
- Frontend devs need to know enough PHP to work inside of the template files, or
- Frontend devs need to work around the PHP of the templates
- Backend devs need to integrate the front and back ends
- It makes automated code testing more difficult. Tools like CodeSniffer may complain about certain rules you have in place, and unit tests may not exist for any functionality in the views
- It can be a lot harder to read, as breaking in and out of HTML (called escaping from HTML) can make code messy, and hard to follow.
- There are no safeguards preventing bad unescaped input being injected into the pages content. If PHP code within the view does not perform its own checking of data before outputting it to the page, some forms of XSS attacks are made possible.
The Flip Side of the Coin
There is the argument that we shouldn't coddle frontend developers, and they should be aware, and indeed comfortable, with PHP. I put the question about whether or not views should be PHP-free to the PHP General mailing list which I'm a member of, and had some great feedback. One reply was from an accomplished web developer and teacher, Tedd Sperling, who remarked that “Trying to protect Developers from technology is like swimming against the current.”, which was one of my main arguments for; to protect frontend developers. His full reply is on the PHP news web archive (http://news.php.net/php.general/325328) and he makes a good case that developers should have a basic understanding of the full stack, even if they don't actively work as a full stack developer. I've grown to respect Tedds input throughout the many years I've been on the PHP mailing list, and while I do agree with him on this point, I still think there is a good case for PHP-free views in an MVC architecture.
Is This The Real Life, Or Is This Just Fantasy?
I've had the pleasure about half a year ago of having to make some amendments to a project that contained a particular view file that exhibited many of the traits that I am aiming to avoid in views. Breaking in and out of PHP as much as done in this example (I've preserved it as it was in the original, and no, I didn't anonymise it, the code really did have array elements called 'nav3Link2Url'!) leads to the kinds of indentation that makes a Python developer cry. If you've never developed in Python, just have a quick Google of the indentation syntax, and you will understand!
I spent far longer than I should have trying to edit the code to fix a bug, and I can only imagine how difficult a task this might be for someone who does not understand PHP too well. So much of the logic included in this view should have been in the controller, or passed over to a templating class to handle, to avoid the issues I outlined above.
Of course, this is not an isolated case, just the one I found that would exhibit some of the worst traits. May projects suffer from this kind of code (for which I'm yet to come up with or discover a name for) when they're under strict time constraints and difficult feature requests. With at least the aim of avoiding PHP in views, this type of spaghetti code should be moved from the views and worked into more logical and structured OOP
What Can Be Done?
Use a templating engine. That is about the best advice I could give anyone aiming to achieve MVC view Zen. There are many great ones out there, like Twig, Smarty, Blade, Mustache, and many more. There's a great overview of the different popular engines right now over at http://www.sitecrafting.com/blog/top-5-php-template-engines/ which goes into detail about features, documentation & support, and speed (who wants the most amazing templating engine in the world if it runs at a glacier pace?)
But What About the Fringe Cases?
Of course there are going to be situations where one size does not fit all, there will always be the exception to prove the rule. As with any rule in programming, sometimes there will be a situation where it makes sense to break it. Before you do though, just spare a moment about whether it's really necessary. Maybe you could structure your model slightly differently to provide different output? Perhaps you could tweak your controller to use a different view entirely?
Go with what makes sense for your project and its restrictions, but bear in mind the lifetime of the project, as you or one of your colleagues may need to work on it in the future. There's a great quote I love and use often (which appears to have been attributed to many people over the past, the earliest definite reference I found is John F Woods in 1991): “Code as if the next guy to maintain your code is a homicidal maniac who knows where you live”.