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.
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
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.
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.
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.
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
I think, you may try using ZendFramework.
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
Related
To start with I'm not exactly sure if this question will fit the question model of SO so moderators please close it if it doesn't fit...
I have been reading a lot on MVC and SoC lately and how they relate to programming in PHP and am having some difficulty grasping how the concepts differ to my current programming style. Any application I write uses url_rewrite routes, with the routing handled by a single file which selects the appropriate controller.php file based on the sub system requested. Then within that controller file the final smarty template file is assigned and the PHP file which contains the business logic of the page in question is included into the stack.
The issue I am having is that while I review MVC and SoC information all the examples I see are written as extensive inter-dependant classes and some rather deep namespaces, but when I code I only use objects where I need an object for reusable but distinct code (in line with object examples on the PHP site itself), and so wind up with some code being classed and namespaced nearly 70% of my application remains in the global namespace with no classing. It seems to me that this coding technique still meets the design principal of separation of concerns, though i'm not so sure about being MVC as every example of MVC I can find is built solely out of a very large number of classes.
Could someone please explain if I am way off base here or if I am achieving SoC and possibly even MVC with my current coding and explain to me if embedding the entire application within a range of classes is a requirement for SoC and MVC.
Thanks
OK I usually take on these open ended questions :P
Let me rephrase your whole thing to a new question – and feel free to tell me I am wrong!
I think you are asking - “Is my coding style in-line with best practice for x y z?”
Now look – i have been in a variety of roles, and I strongly believe that no one has ever cracked a complete SoC architecture – at some point there is always a trade-off between enabling someone at the view end to do their job, and someone upstream ingesting the input and making it work such that it ties to the database and logic.
For example - I am actually right now building a system that takes HTML files as input, reads them via PHP. PHP converts the HTML elements to a bunch of JSON and adds logic to that JSON based on x, y and z, then shoves it out to Facebook React components – which converts it all back to HTML / DOM – when you explain to someone that there is a sausage machine that takes, as input, HTML, and outputs HTML, you can see why they might go – holy shit what are you doing!!
Now – why did we do this? Because it made sense for the project, and it made sense for the team. We could have equally used some pre-defined framework and blah blah blah – however this worked for us.
(a caveat here would be, if you need a highly performant application, this might be the wrong approach, however – bear in mind that what you read (inter dependant classes etc.) may also not be performant – optimisation of PHP code is hard work – my advice here is, get it working first, then if the product is successful, pay someone to fix your shitty code – server time is cheap – your time is not)
My statement for you would be, without concrete examples and use cases – people will struggle to comment on your approach – but understand that there are many different ways of doing things and you may see much open source code written in one way or another, but if you write something that achieves a goal, your only concern should be that it is performant and that it has ‘enough’ separation such that your designer can work on design, your coder can work on code and your CEO can look at sales figures.
Hope this helps.
From the information you've given, you're doing a good job. I think you have a grasp at Separation of Concerns and probably MVC. I think you should take a closer look at how things are abstracted in other codebases, how things are modularized, and think about how you would handle things that potentially come up in web development.
What if I want to have some code run before every controller? Or middleware that runs between the request and the controller? Or inject a variable into the view after every controller is processed? How are you separating POST, GET, PUT, DELETE logic but still grouping them within a resource? Some of these can be achieved with your architecture but I think many of the solutions would be cleaner with a class-heavy architecture. Of course, something being cleaner is in the eye of the beholder.
Frameworks released to the public try to be generic and tackle as many use cases as possible. One issue I see is that you make the assumption that the controller file would be called last and then setup the view. So, even though the logic in there is in the global state, it only exists within that file. In essence, the file acts as a namespace. I don't think that's an assumption a generic web framework should make, but it's something you can get away with when writing something for yourself.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Why should I use templating system in PHP?
I was just curious as to how many developers actually do this?
Up to this time I haven't and I was just curious to whether it really helps make things look cleaner and easier to follow. I've heard using template engines like Smarty help out, but I've also heard the opposite. That they just create unnecessary overhead and it's essentially like learning a new language.
Does anyone here have experience with templates? What are your feelings on them? Are the helpful on big projects or just a waste of time?
On a side note: The company I work for doesn't have a designer, there are just two developers working on this project charged with the re-design/upgrade. I also use a bit of AJAX, would this have issues with a template engine?
Not only does this practice make the code look cleaner, it also has many long term and short term benefits.
You can never go wrong with organizing code. First off it makes it much easier to maintain and easier to read if someone else has to pick up after you. I have worked with Smarty before and it is nice, it keeps the designers work from interfering with the program code.
Using template systems and frameworks would make it much easier to accomplish tasks. There is a rule of thumb you can follow which is DRY (Don't Repeat Yourself). Frameworks help you achieve this goal.
You may want to look into MVC, this is the model that these frameworks are based off of. But you could implement this design structure without necessarily using framework. Avoiding the learning curve. For frameworks like Zend, the learning curve is much greater than some other ones.
I have found that Code Igniter is fairly easy to use and they have some VERY helpful video tutorials on their website.
Best of Luck!!
Actually it's the business logic that needs to be separated from the views. You can use php as a "template language" inside the views.
You can use ajax on any template engine i think.
Edit
My original response addressed the question whether to use a template engine or not to generate your html.
I argued that php is good enough for template tasks, as long as you separate business logic from presentation logic.
It's worth doing this even for simple pages, because it enables you to:
isolate the code that is the brain of your application from the code that is the face, and so you can change the face, without messing with the brain, or you can enhance the brain without braking the looks
isolate 80% of bugs in 20% of your code
create reusable components: you could assign different presentation code to the same business code, and vice versa;
separate concerns of the feature requests (business code) from the concerns of the design requests (presentation code), which also usually are related to different people on the client side, and different people on the contractor side
use different people to write the business code and the presentation code; you can have the designer to handle directly the presentation code, with minimal php knoledge;
A simple solution, which mimics MVC and doesn't use objects could be:
use a single controller php file, which receives all requests via a .httpdaccess file;
the controller decides what business and presentation code to use, depending on the request
the controller then uses an include statement to include the business php file
the business code does it's magic, and then includes the presentation php file
PHP is a template engine (or if you prefer, a hypertext preprocessor). When HTML is mixed heavily with PHP logic, it does become very difficult to maintain, which is why you would have functions defined separately to build various parts and simply build the page from short function calls embedded in the HTML. Done like this, I don't see much of a difference between Smarty and raw PHP, other than the choice of delimiters.
Separation of concerns is a very important tenant to any type of software development, even on the web. Too many times I have found that people just throw everything into as few files as possible and call it a day. This is most certainly the wrong way to do it. As has been mentioned, it will help with maintainability of the code for others, but more than that, it helps you be able to read the code. When everything is separated out, you can think about easily.
Code Ignitor, I have found, has been the easiest to learn framework for working with PHP. I pretty much started my current job and was up and running with it within a few days, from never having heard of it, to using it pretty efficiently. I don't see it as another language at all, either. Basically, using the framework forces me to organize things in a manageable way, and the added functionality is anlagous to using plugins and such for jQuery, or importing packages in Java. The thought that it's like learning another language seems almost silly.
So, in short, organize organize organize. Keep in mind, though, that there is a level of abstraction that just becomes absurd. A rule of thumb is that a class (or file in our case) should do one thing very well. This doesn't mean it is a class that wraps around print, but takes a string, formats it using a complex algorithm and then prints it (this is just an example). Each class should do something specific, and you can do that without any framework. What makes MVC great, though, is that it lets you organize things further, not just on the single class level, but on the level of "packages", being Model, View, and Controller (at least in the case of these frameworks; there are other ways to package projects). So, now you have single classes that do things well, and then you have them grouped with similar classes that do other things well. This way, everything is kept very clean an manageable.
The last level to think about once you have things organized into classes, and then packages, is how these classes get accessed between packages. When using MVC, the access usually will go Model<->Controller<->View, thus separating the model (which is usually database stuff and "business" code in the PHP world), from the view (which usually takes information from the user, and passes it along to the controller, who will then get more information from the model, if necessary, or do something else with the input information). The controller kind of works like the switchboard between the two other packages usually. Again, there are other ways to go with packaging and such, but this is a common way.
I hope that helps.
Smarty and other php template frameworks really do nothing more than compile to PHP anyway, and they also cache their results in most cases to allow for faster processing. You can do this all on your own, but if you ever look at the compiled templates that Smarty generates, and compare to the original Smarty template you create, you can see that one is far more readable than the other.
I write mostly mod_perl these days and started using templates (HTML::Template) halfway through our ongoing project. If I had to make the decision again, I would use templates right from the start - rewriting later to use templates is kind of tedious, though rewarding because you get nicer and cleaner code. For anything bigger than 2-3 pages in php, I would also use some template engine.
One big advantage of a templating engine such as Smarty is that non-developers can use it to embed the necessary logic that is used on the front-end (one really can't separate logic and display on all but the simplest sites). However, if the developer is the one maintaining the pages then using PHP would be preferable in my opinion.
If you separate out large logic blocks and maintain a consistent patten for looping and for-each flow control statements (i.e. don't use print statements, or only use print statements for one-liners, etc.) Then that should be okay.
Please redirect me if a similar question exists.. I haven't been able to find anything, though I'm sure that my problem is fairly common...
I have a page that has 5-6 divs that can be individually loaded through Ajax requests. Through a prototype ajax.request(), the server (php) echoes back the HTML code for the division before the client refreshes the divs's innerHTMLs.
Here's my question : What's the best practice for preserving the MVC pattern on the server side concerning the HTML code it throws out?
For now, my models return database data to the controller, enabling it to initiate a really long var containing the HTML code that it then echoes. My problem is that I end up with a lot of HTML code in my controller classes...
You could use JSON for transporting data to the client-side and constructing it there.
That way you'll have an abstracted data source not bound by your markup. JSON can be directly evaluated into a javascript object.
Do you really like to use MVC? The C can mostly be removed by Conventions / RESTful URLs.
Like Andy said, you should use JSON to transfer the data to the client side. XML is also a wide used alternative (because it acts much better if other apps have to use your services). XML can be tranformed easily to JSON! And JSON code is valid JavaScript Object code. So you can use it to stich client side templates together with it.
You should try EJS for browser/client side templating! If you do so, you have no HTML boilerplate in your controllers! Just business logic. That follows a lot of SOA best practices. The architecture pattern is called SOFEA or SOUI (which is the same).
I've written my homepage with it. The evaluation of a lot template engines has clerified that EJS is the best candidate.
Because:
1. It's fast!
2. It's free (MIT License)!
3. It works well with JQuery
4. It does realy modify the DOM, so other methods can access the used templates (JS Repeater doesn't).
Other frameworks:
JSmarty: Not such as easy to use but it can use Smarty templates. It isn't enteprise prooven and still under heavy development.
Trimpath Javascript Templates: Doesn't work well with JQuery/Prototype... Also still under development.
jQSmarty: Nice, but it seems that the development has stopped. The last change was in 2008.
seethrough_js: Invasive template layouting. Nice for Erlang people.
JsonML: Also an invasive template format which is based on JSON. What do you think about it? I think designers should stay at their HTML/CSS elements, so no knowledge is wasted.
JS Repeater: Reminds me at my own bad tries. I've checked it out and used it.. but it doesn't handle a lot of things very well. (Such es empty fields etc.)
Pure: Time to start a relegios war on how to develop pages? I think that Pure isn't the answer. It's bloating if you define what's really to do and it fails to scale like JSF. It has no invasive syntax, thats very good. But the price of the hard to use rules for rendering issues are a no go for me. It just feels don't right. I've met other people which think completly different! Test it out and let me know what you think.
This is what I do for MVC + AJAX...
Really simple implementation, if you were to ask me.
http://jarrettatwork.blogspot.com/2009/02/aspnet-mvc-ajax-brief-introduction.html
If think that the most important letter in MVC is V for working with AJAX. AJAX with HTML, and JS is part of presentation layer so by theory it is place for View - part.
View is responsible for what you send to end user, and MVC patter is there not only to separate Model, View and Controller but to enable us multiple views for the same data model provided.
So it is best to encapsulate code in a class and use that same controller code to render different views. In first case that could be drawing of a static page, but in other scenario it is view specially designed for AJAX calls and data may be in JSON or other standard format it doesn't matter, as long as you respect responsibilities that every layer has.
If the HTML is mostly in string literals, as I understand it is, you probably should move the HTML outside the <? ?> tags altogether and insert the dynamic contents from the database with small inline PHP snippets that reference variables set by the controller.
This is effectively a template mechanism. Remember, PHP is at its heart a template engine.
Example:
<?php
include 'controller.php'; // set variables used below
?>
<div>
<h1>Hi there, <?=$UserName?></h1>
<p>Since you've been here, <?=$numberOfDays?> days have gone by</p>
</div>
etc. This also gives you back the syntax highlighting in your HTML and gets you rid of having to concat all the long string literals inside your PHP code which often messes up the readability of the code.
All the popular PHP frameworks today use their own view layer implementation that is based on pure PHP templates and lots of helpers. I've tried some of them and always found that this approach introduced huge complications to quite simple things. For example, in Zend Framework forms and the pagination use their own solutions to customize the look of these items. The helpers re-invent loops, providing also quite slow solutions, and the whole view layer, in my opinion does not exist as a one part, but many of its functionality is delegated to other parts of the script. The same configuration problems occured in Symfony and admin generator, and in Kohana I was forced to duplicate the same code over all my forms. Is PHP really a good choice for the view layer? Do you also find these implementations inconvenient or maybe, why despite all these problems they are good and cannot be replaced, for example by a smart template engine (I don't mean Smarty :))?
Now I like PHP but ultimately, first and foremost, it is a templating language, not a general purpose programming language nor an object-oriented language. Don't fight it. Embrace it.
I've looked at a few different MVC frameworks like Symfony, CakePHP and Zend and I have a hard time getting past the examples. Typically they are "with these 17 files you can make a 'Hello world' program!" Huh?!?!
There is such a thing as complexity for sake of it and solving a problem before you have a problem and I'm yet to be convinced that these heavyweight (they are heavyweight) frameworks really adds value.
I'm more of a fan of the 'no framework' framework. This is really 'roll your own' but I think that it leads to the leanest, cleanest end result.
I feel similarly about Smarty. A lot of people on SO are big fans of Smarty but it's never made sense to me why you'd add a templating language to your... templating language.
Ultimately I end up writing this kind of PHP script most of the time
<?
require 'config.h'; // set up constants, DB connections and so on
page_header('My Page'); // page header, site menu and so on
deny_unregistered(); // security
if (/* user submitted page */) {
$valid = validate_form(/* validation rules */);
if ($valid === true) {
// do db changes
// redirect user ie POST+REDIRECT+GET
} else {
// output error messages
}
}
?>
// display page
<? page_footer(); ?>
With judicious use of helper functions (eg pagination links), the above is incredibly easy to read and debug. I also much prefer it to this model:
URL: /index.php?inc=blah
index.php:
<?
require "$inc.php"; // hopefully you sanitize this but so many don't
?>
I find this ugly, error-prone and even dangerous. I have a hierarchy of PHP files that mirrors the site structure (from a menu point of view) where each page is a PHP script. If they have common behaviour they both require it (not require_once, which is typically used as a hack for poor organisation).
Simple, easy, understandable, straightforward.
It seems a lot of programmers will throw a framework into the mix before there is really ever any need. I think this is a fairly lazy practice and one with a big cost: every decision made today is one that becomes harder to change later so put off making decisions like this as long as possible. Introducing something later is easier than introducing something now, finding out it doesn't really do what you want and then changing it later.
there are several other templating engines out there. however i've always found pure php to be the most convenient. i'm just more comfortable with it.
the thing i did not like about view helpers in ZF is that it usually made my code more bloated than cleaner. i'm specifically talking about the $this->url() helper :)
I seem right now to be embroiled in a debate with another programmer on this project who thinks that views have no merits. He proposes a system that PHP looks something like this:
$draw = new Draw;
$nav = $draw->wideHeaderBox().
$draw->left().
$draw->image().
Image::get($image,60,array('id'=>'header_image')).
$draw->imageEnd().
$draw->leftEnd().
$draw->left(10).
'<div id="header_text">'.
self::defaultSectionText().
'</div>'.
$draw->leftEnd().
and so on (this is in the controller btw). Now his arguments for this actually make some sense, he claims that if there is a redesign all we need to do is change the HTML in one place and it changes everywhere automatically. For some reason however, this method still rubs me the wrong way, is there any merit to views over this method? I mean besides not having to retype HTML by hand.
HTML time-savers are useful, but they're only useful when they're intuitive and easy-to-understand. Having to instantiate a new Draw just doesn't sound very natural. Furthermore, wideHeaderBox and left will only have significance to someone who intimately knows the system. And what if there is a redesign, like your co-worker muses? What if the wideHeaderBox becomes very narrow? Will you change the markup (and styles, presumable) generated by the PHP method but leave a very inaccurate method name to call the code?
If you guys just have to use HTML generation, you should use it interspersed in view files, and you should use it where it's really necessary/useful, such as something like this:
HTML::link("Wikipedia", "http://en.wikipedia.org");
HTML::bulleted_list(array(
HTML::list_item("Dogs"),
HTML::list_item("Cats"),
HTML::list_item("Armadillos")
));
In the above example, the method names actually make sense to people who aren't familiar with your system. They'll also make more sense to you guys when you go back into a seldom-visited file and wonder what the heck you were doing.
The argument he uses is the argument you need to have views. Both result in only changing it in one place. However, in his version, you are mixing view markup with business code.
I would suggest using more of a templated design. Do all your business logic in the PHP, setup all variables that are needed by your page. Then just have your page markup reference those variables (and deal with no business logic whatsoever).
Have you looked at smarty? http://smarty.php.net
I've done something like that in the past, and it was a waste of time. For instance, you basically have to write wrappers for everything you can already with HTML and you WILL forget some things. When you need to change something in the layout you will think "Shoot, I forgot about that..now I gotta code another method or add another parameter".
Ultimately, you will have a huge collection of functions/classes that generate HTML which nobody will know or remember how to use months from now. New developers will curse you for using this system, since they will have to learn it before changing anything. In contrast, more people probably know HTML than your abstract HTML drawing classes...and sometimes you just gotta get your hands dirty with pure HTML!
It looks pretty verbose and hard to follow to be honest and some of the code looks like it is very much layout information.
We always try to split the logic from the output as much as possible. However, it is often the case that the view and data are very tightly linked with both part dictating how the other should be (eg, in a simple e-commerce site, you may decide you want to start showing stock levels next to each product, which would obviously involve changing the view to add appropriate html for this, and the business logic to go and figure out a value for the stock).
If the thought of maintaining 2 files to do this is too much to handle, try splitting things into a "Gather data" part and a "Display View" part, getting you most of the benefits without increasing the number of files you need to manage.
I always find it much easier to work directly with html. Theres one less abstraction layer (html -> actual webpage / php function -> html -> actual webpage) to deal with then you just work in HTML.
I really think the 'just have to change it in one place' thing wont work in this case. This is because they'll be so many times when you want to change the output of a function, but only in just one place. Sure you can use arguments but you'll soon end up with some functions having like a dozen arguments. Yuck.
Bear in mind templating languages / systems often let you include sub templates, allowing you to have some reusable blocks of html.
The bottom line is if I had just started at your company and saw code like that everywhere, my first thought would be, 'Damn it! Need a new job again.'