6

I use PHP quite a bit, and whenever I see a "PHP-hate" thread on some forum or even popular PHP-related discussions here, I usually see something along the lines of:

PHP is too messy/sloppy/crappy, because you have a tangled web of presentation and logic.

Then I see the PHP-Defenders replying to some version of the above saying that is isn't necessarily true. I got to thinking "How is this possible...?" and "What counts as mixing presentation with logic?" I couldn't figure it out, so now I'm here.

Which of these is the best practice? Or is there an even better way that I'm not aware of?

<?php
    if(!function()) {
        echo '<div id="results">The result is a lie.</div>';
        }
?>

Or

<div id="results">
    <?php
        if(!function()) {
            echo 'The result is a lie.';
            }
    ?>
</div>

I know the above examples don't really look like a big deal, but after browsing through web apps of mine, I realized it was all kind of messy (because I was mixing HTML and PHP), so I was hoping there was a good way to develop while keeping things nice and neat.

Andrew
  • 12,172
  • 16
  • 46
  • 61
  • I personally stick to the first option and output everything via code. I find that to be much cleaner. – Brad Jan 19 '11 at 20:44
  • It's not a wand, it's a wizard. One always able separate matters. If they want to. – Your Common Sense Jan 19 '11 at 20:45
  • *(related)* [MVC: how much code should be in a view?](http://stackoverflow.com/questions/4698880/mvc-how-much-code-should-be-in-a-view/4699689) – Gordon Jan 19 '11 at 20:50
  • @Col. Shrapnel - I realize that; I was hoping for tips on becoming a...more magical wizard. (Assuming I understood your comment correctly. :P) – Andrew Jan 19 '11 at 20:50
  • there is no rocket science in this. JUST SEPARATE. Separate your code into 2 parts: getting data part and display part. no need for all that crap like MVC, smarty and such. The real separation should be in one's head. Here is a small example of what I am talking about http://stackoverflow.com/questions/3988627/using-template-on-php – Your Common Sense Jan 19 '11 at 20:53
  • 1
    However, sometimes a template become as messy as hell. Don't worry. It 's just follows presentation LOGIC: more complex logic - more complex template. And don't let them fool you - no template engine can solve that. – Your Common Sense Jan 19 '11 at 20:56

7 Answers7

11

Maybe you want to look at a template engine, like smarty. That can separate it for you.

Linkage: http://www.smarty.net/

Some (hopefully balanced) additions seeing the rather large comment-section below:

There seems to be a lot of discussion on smarty. There are two extra camps in this as far as I can tell,

one says: Template engine, ok, but smarty is not the best; use (insert your choice here). e.g.: twig or dwoo.

and another one says: Do not use a seperate template engine! As PHP is perfectly capable of doing this itself. Examples from the comments include:

Use Zend_View and Savant

Nanne
  • 64,065
  • 16
  • 119
  • 163
  • +1: This is the right answer. Write your HTML as a template, and use PHP to fill in the blanks, and serve it up. – Oliver Charlesworth Jan 19 '11 at 20:44
  • I'm not really sure why this just got a -1? It is not a "look somewhere else sollution", This is really a way to stop all those PHP troubles of mixing... – Nanne Jan 19 '11 at 20:45
  • heard some good things about twig too (but haven't used it myself) – Nanne Jan 19 '11 at 20:46
  • +1 Templates are the best way to separate presentation with logic – Damp Jan 19 '11 at 20:47
  • 3
    PHP is the best template engine itself – Your Common Sense Jan 19 '11 at 20:48
  • I recently used Dwoo, a php5 Smarty rewrite that supports template inheritance, and liked it a lot. http://dwoo.org/ – scragz Jan 19 '11 at 20:50
  • Big -1. Smarty is a terrible solution. PHP itself is a template langauge and should be used as such. Smarty causes unnecessary performance penalties, weird behavior, and code that becomes unmaintainable. Having worked on a large project formerly using Smarty and now using a solution that takes advantage of PHP itself, and after extensive profiling, PHP is much better. Check out things like Zend_View or Savant for an example of better template engines – mfonda Jan 19 '11 at 20:52
  • @mfonda: I think Smarty is more of an example, the point being: use templates. (I hate Smarty too). Besides, Zend_View and Savant aren't *templating engines*, PHP is the templating engine that makes both of them work. They are merely wrappers to make templating easier and faster. – netcoder Jan 19 '11 at 20:56
  • "that's just, like, your _opinion_ man.. (but I stand by my solution: pure html designers can work with smarty, and have a hard time working with complicated OO PHP. It's a simple sollution that might have not been the best in your case, but can be a good solution nonetheless) (edit: to be clear: that first sentence was a quote and a joke. not trying to be anoying :) ) – Nanne Jan 19 '11 at 20:57
  • @netcoder I think suggesting to use Smarty is very poor advice. You are being pedantic; would it make you happier if I said template _system_ instead of template _engine_? The exact point I was making is that PHP itself should be used, which is exactly why I suggest things that make using PHP easier. – mfonda Jan 19 '11 at 20:59
  • I wonder if anyone of smarty advocates tried to compare templates written in smarty and PHP. If ever used smarty at all... – Your Common Sense Jan 19 '11 at 21:01
  • @mfonda: Not being so pedantic no, there's a huge difference between an *engine* and a *system*. That said, I see your point. – netcoder Jan 19 '11 at 21:04
  • @Col. Shrapnel: I used to do Smarty on old projects years ago. It's similar to PHP, except that Smarty is a pain when you want some fancy display logic. It's only "nicer" because there aren't any ` – netcoder Jan 19 '11 at 21:08
  • Maybe the point is that you tend to use less logic, and therefore are somewhat forced to do this in someplace other then your template. But I see your points. I hope they're represented somewhat correctly in the changed answer? This so someone doens't have to read the discussion in all these comments ;) – Nanne Jan 19 '11 at 21:12
  • Are there any comparisons of Smarty vs other template engines in speed and features?? (Currently using Smarty at work) – Echo says Reinstate Monica Jan 19 '11 at 21:55
  • Savant, based on their example, looks pretty nifty. I think I'll give that a try, thanks! – Andrew Jan 20 '11 at 02:29
  • @Echo well features are equal. And for these few sites where templating speed matters, smarty is not an option – Your Common Sense Jan 20 '11 at 06:28
  • @Col. Shrapnel, how is the speed so bad? I found these: http://www.raintpl.com/PHP-Template-Engines-Speed-Test/ and http://gonzalo123.wordpress.com/2011/01/17/php-template-engine-comparison/ and Smarty doesn't not seem like it is extremely slow or anything. – Echo says Reinstate Monica Jan 20 '11 at 15:20
  • @Echo there are tests and there is real life. And again - it's for these **few** sites for which template speed does matter. Most likely for yours it doesn't - so, don't worry. – Your Common Sense Jan 20 '11 at 15:48
  • @Col. Shrapnel, ok. thanks for all the info. If I ever get to that point, I'll know what to get rid of. – Echo says Reinstate Monica Jan 20 '11 at 15:55
2

Think of logic and presentation where the logic is a type of electrical socket and the presentation is a light bulb. Now you can have a number of sockets in your house, some with different sized threads. You can also have a bunch of light bulbs, of different colors, some cheap ones, some expensive ones. The point is that one light bulb could go into one or more socks, and one socket can accept more than one bulb, but you can only match one bulb to one socket at a time.

So if you have a really nice bulb (or really nice html template) you want to be able to move that bulb around to where you need it (or apply the same logic). And if one day you decide you want to use a blue light bulb, you can simply change the bulb, you don't have to install a whole new electrical socket just to change the color.

Getting back to logic and presentation, if you have the common case where you have a form on a web page, sometimes you show that form the first time a user loads the page, and sometimes you want to show it after the user has filled in some of the inputs, but maybe there were errors or missing information. In this case the logic would either do nothing, just show the form, or try to process the form, find the error, and then display the form revealing the errors.

You can do this with mixed logic and presentation in the same file, sure, but what happens when more than one person starts to edit your script? Maybe the script breaks and they don't know what to do so they comment out some important section to get it working again. That is like someone going to change a bulb and then deciding to rewire your light switches. But sometimes when you are confronted with bad wiring there is no other way to fix the problem, the problem goes from a simple "Please change the light bulb" to "Make the lights work." In a properly designed system, where components are isolated in a sensible way, things are usually easier to fix.

In other words, mixing logic and presentation is like hardwiring your lightbulbs using bare wire, and then connecting the wires to the mains without even a circuit breaker for safety.

Roger Halliburton
  • 1,965
  • 3
  • 14
  • 18
1

The second example is better.

The easiest way to avoid mixing presentation with logic would be to use an MVC framework like Symfony or CakePHP. These allow you to separate data (models) from logic (controller) and presentation (views).

The other answer is a good one: use templating. Templating is almost always a part of an MVC framework.

Rafe Kettler
  • 75,757
  • 21
  • 156
  • 151
0

You can define helper methods in an included file or at the top of the page:

<?php
function result_if_good()
{
    if (!function()) {
       return 'The result is a lie.';
    }
}
?>

And then elsewhere, in your HTML:

<div id="results"><?php echo result_if_good();?></div>

Keeping all of your logic out of your presentation.

scragz
  • 6,670
  • 2
  • 23
  • 23
  • There is a problem. That helper function become the same mess – Your Common Sense Jan 19 '11 at 20:49
  • Except it is straight PHP and conditionals with no HTML. Even with a templating engine, you can still put too much conditional logic in your templates, and it's good to start putting them in view helpers. – scragz Jan 19 '11 at 20:52
0

If you want true separation between your logic and your interface, you should check out the MVC pattern.

I use the views in the MVC pattern with a template's engine to achieve clean HTML files for my views

Maher4Ever
  • 1,270
  • 11
  • 26
0

I think, you may try using ZendFramework.

Shuhel Ahmed
  • 963
  • 8
  • 14
0

I prefer a situation where a script puts out the HTML and javascript if needed. In other words something more like (in pseudo python):

#Primitives
def htmlheader(title):
    return "<html><head><title>%title</title></head>" % title 

def body:
    return "<body>"

def para(content):
    return "<p>%content</p>" %  content

def htmlend:
    return "</body></html>"

#New file: View

print htmlheader()
print body()
print para("This is my paragraph")
print para("Hello, %salatation %lastname" % dbresult.salutation, dbresult.lastname)
print htmlend()

PHP suffers from being surrounded by <>, which are already pretty hard to read.

YMMV

With primitives in place to put out that actual html, you can then make a controller layer which simply hands pure data to the view. More pseudoPython:

#ViewController

db = dbconnect("host", "user", "password");

view.mainbody.show(getCurrentNews(db))
view.header.show(getTopHeadLines(db))
if (user.isLoggedIn):
  view.footer.userNavigation()
else:
    view.footer.showDefault()
view.render
Hack Saw
  • 2,741
  • 1
  • 18
  • 33
  • Very unclear example which doesn't actually output a single HTML tag – Your Common Sense Jan 19 '11 at 21:04
  • I added primitives to help the example. – Hack Saw Jan 19 '11 at 21:19
  • Well your HTML doesn't looks like HTML. it's all in quote-delimited strings. No syntax highlight, escaping mess and all that crap. Do you really use it? For the real world templates? – Your Common Sense Jan 19 '11 at 21:24
  • My goal isn't to be looking at html, it's to be considering the logic of getting my data displayed on the user's browser. A real primitive library would cover a lot of special applications like making boxed paragraphs (probably by marking the para with a "box" CSS attribite, and replying on a base CSS to provide the layout). I don't want to see it, except maybe in final form. Then I would hope the primitive engine would lay it out indented and whatnot. But frankly, I hope I don't have to look at the html at all. – Hack Saw Jan 19 '11 at 21:29