I am just wondering if its normal to embed PHP in the HTML, or is it considered dirty/unprofessional. For example consider following lines:
<? if($photo == 0) { ?>
<div class ="reminder">Hey <?=$name;?>, You don't have any photo. </div>
<? } else { ?>
<div class ="ok">Do you want to change your photo? </div>
<? } ?>
Is this kind of code ok? How the similar work can be done in a clean/professional way (without PHP frameworks? )
Thanks.
As long as you keep the logic of your program outside the html, it is ok. You need to mix it in your templates, for example. Template-engines like smarty replace the {$myVar} with < ? php echo $myVar; ? > (simply spoken), so it is not possible to avoid it completely. But things like
<?php
include "db.php";
connect_db();
// check login
echo "< html >< head><body>...";
?>
is NOT good practice, because you mix everything together: program logic (login-check, db-stuff) and output (echo html). Just have a look at the MVC and keep the "separation of concerns" in mind.
Your example looks ok because you have only that logic in your html which is needed to control the output directly. But calculating the value of $photo, depending on a db entry for example, would NOT be good in your html, because this is program logic. Output (HTML) and logic should be devided all the time.
It's very normal, whether it's good or not is a completely separate topic. It's really all about the size of your project and your requirements for maintainability/flexibility.
If it's a small project, just do what you have to in order to get it done. However a point exists at which it becomes unwieldy to develop without a framework. This is all very subjective and varies from project to project, but this is the general principle.
It's OK to use PHP in templates but many people prefer to work with a templating language because it forces separation and ensures you don't litter your templatse with loads of PHP. If you do go down the template route Twig and Smarty are quite good since they compile the template into PHP which speeds things up.
If you're writing PHP in your templates try to follow some best practise coding standards to keep things neat. For example:
Use full <?php tags for compatibility.
When writing any loops instead of curly braces use colons. To end the statement you need to explicitly write it as endforeach/endif/endwhile/etc. This makes PHP templates more readable.
If you have a lot of logic move this into an external PHP file to keep the PHP in your template short and readable
If there is only one PHP statement in your PHP tag you don't need to end it with a semi-colon. Again, helps readability
An example:
<?php if ($photo == 0): ?>
<div class ="reminder">Hey <?php echo $name ?>, You don't have any photo.</div>
<?php else: ?>
<div class ="ok">Do you want to change your photo?</div>
<?php endif ?>
See more at:
http://www.php.net/manual/en/control-structures.alternative-syntax.php
http://framework.zend.com/manual/en/coding-standard.overview.html
for that you can use smarty templete .... it improves your coding style and works fast ... visit smarty and try it, it's really awesome
From what I have read either will work, but most people just use the echo statements for small, conditional html.
I try to keep this at a minimum, because i find it harder to debug it with all the
< ? } ?>
flowing around in the code (wordpress theme gurus does this alot)
There will be many opinions about this. Mixing HTML and PHP can become very messy, but this looks fine. Many professionals work just this way. If it works for you, it's good.
To make it more readable, I tend to keep the brackets on separate lines, just so you can be sure to be able to find them all easily, but thats just me.
there was an answer from guy named alexn
Dunno why did he delete it, it's looks best answer to me, so, I am only reproducing it:
I would say that's the way to go. You
have a nice, clean separation of PHP
and HTML.
Here's another option:
<? if($photo == 0): ?>
<div class ="reminder">Hey <?=$name?>, You don't have any photo. </div>
<? else: ?>
<div class ="ok">Do you want to change your photo? </div>
<? endif ?>
Related
I'm working on a form that auto-generates a large addition when the user specifies, including a editable canvas, selectable inputs, textareas and so on. I'm wondering if there's a tool for appending large blocks of HTML more easily and with better style: for instance, in my codeigniter PHP views it's easily done just by closing the PHP tag and referencing variables using <?=var?>.
<?php if (condition) {?>
<h1>List a variable <?=$var?></h1>
<?php }?>
Is the above terrible style? Is there a comparable tool to use for javascript so I can include html with proper indentation?
EDIT:
To be clearer, I'm not looking for a lot of input on the php - my objective is to make editing the HTML I'm inserting with javascript cleaner.
The problem is analogous to this:
<?php
if (condition) {
echo "<div>";
echo "<p> a line of html code<p>";
echo "<h1> more stuff and a ".$variable;
echo "<div>";
}
?>
//vs
<?php
if (condition) { ?>
<div>
<p> A line of html code, but easier to edit</p>
<h1> a <?=$var?>
</div>
<? } ?>
The second one is cleaner and easier to edit for the developer. So I'd like to do the same with javascript and take this:
$(this).append('<p>a whole bunch of stuff'+var+'more stuff<p>');
$(this).append('<p>more stuff<p>');
$(this).append('<h1>more stuff<h1>');
And make it easier to manage.
Indentation is for the DEVELOPER, to make source code maintainable and readable. It has nothing to do with making "view source" look nice.
It does look a little unpleasant, certainly.
I'd probably write it like this, if I was using that particular approach to page generation.
<?php
if (condition)
echo "<h1>List a variable $var</h1>";
?>
You may also like to look into the DOM methods of php. They can make creating reusable, modular code much easier.
They're not as fast as simple string operations, but far neater and more powerful. When the daily traffic means this difference in speed is a problem you've probably got the money to throw at some ode monkey to make the required changes.
Try CoffeeScript. It adds some features to normal javascript like string interpolation, block strings and stuff that makes writing huge blocks of HTML string literals a piece of cake.
I don't want to use an MVC framework. I don't want to use a template engine. I am a few man shop where the developers where all the hats, no graphic artists. We do it all (all layers). I do not want code mixed with presentation, like I have with Classic ASP.
But, I do not know what my code is suppose to look like between server side and the actual presentation.
If I'm not emitting HTML in my server side code, how does it get to the HTML page so I can do things like <span><?= $myvar ?></span>? and put loops in the html page?
Thank you for any advice.
For using loops and all, I use the alternative syntax for the control structures.
An example:
<div id="messages"<?php if(!(isset($messages) && count($messages))): ?> class="hidden"<?php endif; ?>>
<?php if(isset($messages)): ?>
<?php foreach($messages as $message): ?>
<div class="message"><?php echo $message; ?></div>
<?php endforeach; ?>
<?php endif; ?>
</div>
For more information, see this: http://php.net/manual/en/control-structures.alternative-syntax.php
Oh also, I use a semi-MVC structure, where I have a class that handles templates (views), basically it's just a class that I create an instance of, pass a set of variables, then render the template when the instance get destroyed. I have an array of variables in that class, and then use extract to pass all variables in the include, like so:
extract($this->variables, EXTR_SKIP);
include($this->file);
EDIT: Here is the same example in Smarty:
<div id="messages"{if isset($messages) && !count($messages)} class="hidden"{/if}>
{if isset($messages)}
{foreach from=$messages item=message}
<div class="message">{$message}</div>
{/foreach}
{/if}
</div>
Simple PHP projects usually generate the full HTML in-place instead of populating templates, so you'd just echo it out in your PHP code.
This gets messy, so you WILL end up coding some kind of templating system for any moderately complex website.
A possible alternative is to serve your page as completely static HTML/CSS and use AJAX to fetch the actual contents dynamically (JSON would be a good transport format, it's native to JS and can easily be generated from PHP). This gets you rid of all the HTML littered across your PHP code. Whether this is a viable alternative or not depends on the case.
<span><?= $myvar ?></span> works.
A loop would look like:
<html>
<body>
<?php
for ($i=1; $i<=5; $i++)
{
echo "The number is " . $i . "<br />";
}
?>
</body>
</html>
Example taken from here.
I really recommend that you use the php Template Inheritance system. (Don't let it scare you, it's only one file.) This is a simple set of functions that helps you to build extensible PHP views without the problems and limitations of manual includes.
It's still Pure PHP, so you don't need to learn some strange template language. It may not look like much, but it's really powerful once you start using it.
To be sure, you can do it all by yourself - but what you want is still MVC pattern, or separation of concerns ("I do not want code mixed with presentation"). Or at least MV, for very simple applications (although it's still dirty, having models directly influence the view).
The easiest way to achieve this is to first collect and process all data, then just print them. No complex code allowed in the php files directly exposed to the web.
<?php
require('model.inc');
process_capuchin_monkey_order_form();
?>
...
<h1>Thank you for your order of <?php echo $order->num_monkeys; ?> monkeys.</h1>
...
typically you would want to just make sure you have as little PHP in your HTML as possible. This means doing all of the data processing before hand, and simply passing a set of variables in one way or another to a method or function that includes the HTML.
Any HTML with PHP intermixed could be considered a template. Here's a simplified example:
// view class
class View {
public function render($html_template) {
include('view_path/' . $html_template . '.php');
}
}
// html template file 'view_path/main.php'
<html>
<body>
<h1><?= $this->title ?></h1>
</body>
</html>
// usage
$view = new View();
$view->title = 'Some Title';
$view->render('main');
You should use an MVC-like separation of concerns no matter what you do. This means:
At least one file is all html and is given a handful of variables. (view/template)
At least one file is all php and only talks to the database. (model)
At least one file processes the http request, pulls data from database, and executes the view.
The core of every php templating language is the use of extract() and include inside a function:
function render_template($___filename, $___data) {
extract($___data, EXTR_SKIP);
include $__filename;
}
You can pretty this up with a class interface (view objects) or with output buffering, but this is the core of every template system. Your controller's responsibility is simply to assemble that $__data argument (usually with data from a database) for a given view.
I have a big page with much spaghetti code. I'm not sure which solution is faster for the server.
The first solution
<div> ... many html code ....
<?
if(isset($ubo['day']['xxl']['0']))
{
$firstHit = $ubo['day']['xxl']['0']['title'];
echo "<div style=\"cursor:pointer;\">$firstHit </div>";
}
?>
... many html code .... </div>
this solution ( I use ' instead of " )
<?
// many php code
if(isset($ubo['day']['xxl']['0']))
{
$firstHit = $ubo['day']['xxl']['0']['title'];
}
// one echo with all html code
echo "<div> ... many html code ....
<div style='cursor:pointer;'>$firstHit </div>
... many html code .... </div>";
?>
or this solution
<?
// many php code
if(isset($ubo['day']['xxl']['0']))
{
$firstHit = $ubo['day']['xxl']['0']['title'];
}
// one echo with all html code
echo "<div> ... many html code ....
<div style=\"cursor:pointer;\">$firstHit </div>
... many html code .... </div>";
?>
Practically, it doesn't really matter. What matters is that your code is maintainable and clean. You should look into using a PHP framework like CodeIgniter or CakePHP to make your code more well-structured.
You should have as little HTML inside PHP echo/print statements as possible; it is good to close PHP tags and just have the natural HTML. This is because the parser won't travel through the echo/print statement and and parse it. Thus, your first solution is certainly the best in terms of speed.
Of the solutions presented, I would say that the first is probably best. General rule is that you should put as much into strait HTML as possible. This is both for the developer's sake as well as the server's. Stuff outside of <?php ?> is basically raw data which, while it still needs to be parsed on some level, can basically be served to the user straight up.
If anything, you may want to refine it further:
<!-- as a note: in all of your examples except the first, this div exists.
In the first it only exists if the isset returns true. -->
<div style="cursor:pointer;">
<php?
if(isset($ubo['day']['xxl']['0']))
{
echo $ubo['day']['xxl']['0']['title'];
} ?>
</div>
You also could probably optimize through storing $ubo['day']['xxl'] in some local variable elsewhere on the page.
Do you have performance problem ? If no don't bother about "better for the server" and do "better for your code" instead.
And i'd say that all this is the same, most of the performance are due to I/O (sql query/web service, hard disk) not syntax details.
So do the best code for yourself you'll see later about performance.
The second solution might be faster than the first, because you are sending the content only once and it also looks a little better (PHP is more separated from HTML).
However performance difference between all 3 solutions will be very small and you really should't put attention to it.
Follow the hint "premature code optimization is evil" :-) I dont think that it makes a (big) difference what you use in your given code. It would be much better to have a clean code separation in mvc. Then you can use a template engine which supports caching for your massive html code and there's no need to output it every time with an echo! Besides this performance optimization has much more effect on DB-issues, your general code structure and the code at client side. For example, avoid inline css styles to reduce transferred html code.
do you use PHP opcode cache?
do you use memcached for generated subpages?
have you optimized your database queries?
do you use icongroup images? do you compress JS and CSS?
have you really run out of all the low hanging fruits?
First steps are done, some pages are coded. And after looking to the result I've got the question... how much code is there should be in templates (View)?
For example, here is a template file:
<?php $this->load->view('header'); ?>
<?php $this->load->view('banner'); ?>
<div id="items">
<?php
for($i=0; $i<count($main); $i++) {
echo '<div class="item">
<div class="name">'.$main[$i]['name'].'</div>';
if($main[$i]['icq']=='') { }
else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; }
echo '</div>';
}
?>
</div>
<?php $this->load->view('footer'); ?>
Do you think there is too much code in this template or it is normal?
The first answer was actually spot on, but the user deleted it (probably due to peer pressure). Basically, you do not want any logic in your template. In an ideal world, you had a tag for all the model data, but since we are in an HTML world, there isn't, so you either have to use XSLT or use ViewHelpers.
Let's focus on the ViewHelper approach.
This is hard to maintain:
<div id="items">
<?php
for($i=0; $i<count($main); $i++) {
echo '<div class="item">
<div class="name">'.$main[$i]['name'].'</div>';
if($main[$i]['icq']=='') { }
else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; }
echo '</div>';
}
?>
</div>
And it won't get any better if you replace the PHP with Smarty. This is easy to maintain:
<div id="items">
<?php echo itemlist($items, 'template.htm') ?>;
</div>
Below the now deleted question, there was a commentor objecting this "code isn't easy to maintain for non-coders because now they don't know where itemlist is defined and what it does." but that's complete gibberish. Think about it for a second.
On the one hand, they claim non-coders will have issues with a simple function call but on the other hand they expect them to understand the mishmash of PHP code mixed with HTML. A designer does not care about the presentation logic, but just the actual presentation. The output.
A single function call clearly says: "here be an item list", which is much easier to grasp than "here is a for that echoes a div and maybe something else if icq is given". A function call is as good as a tag. It has clearly defined input and output. How it achieves that output is irrelevant to anyone but the developer.
Your ViewHelper encapsulates the presentation logic. It's a snippet you can reuse across all of your Views. That is much more maintainable than copy and pasting all that logic over and over again when needed. In the example above, there is two arguments to the helper:
$items is an array or other traversable type holding your actual item data
'template.htm' is the filename of the template used to render the data
I'll make the second one optional, because I'd assume it's always the same template anyway. But since the commentor complained the non-coder wouldn't know where to look, I felt it necessary to show how easy it is to tell the non-coder where to look.
function itemlist($items, $template = './templates/itemlist.htm') {
ob_start();
foreach($items as $item) {
include $template;
}
return ob_get_flush();
}
There might be more efficient approaches to solve the inclusion of the template. The main idea should be clear though. Hide the presentation logic from the actual template. Your "template.htm" would then look like this:
<div class="item">
<div class="name"><?php echo $item['name'] ?></div>
<?php echo contact($item, 'icq' 'phone'); ?>
</div>
No if and elses. No string concatenations or curly braces. The logic to decide how to the user can be contacted is hidden in a ViewHelper as well. All the non-coder has to know now is the arguments to the ViewHelpers and that's as easy as knowing which attribute to write to a tag. Give them a cheat sheet if necessary.
Related information:
http://martinfowler.com/eaaCatalog/templateView.html
EDIT
Due to the two comments below I decided to expand on this answer. The above is not abstraction for abstraction's sake. It is for reusability and maintainability. I've already pointed that out above but let me explain that here again.
Actually, I find it odd to object to using ViewHelpers because you'll have "have presentation in two places" but not complain about separating header, banner and footer. It's the same thing. You isolate parts that are reusable and put them into their own templates. Separating the logic from the template in that step is just the natural next step to achive even more maintainability.
A view template that contains logic is effectively a script and not a template. Any view template that contains the logic to assemble itself is doomed to repeat itself. This might not be an issue with small sites but if you are working on a site with a couple dozen or even hundreds of view and widgets, not abstracting these parts will lead to code duplication. Put all the logic into the template and it will quickly become a tangled mess of c&p'ed markup mixed with conditionals. For any duplication, you'll double the time it takes to change it. Add inline styles and obtrusive Javascript and you are in maintenance hell.¹
If you use OOP for the other parts of your application, then why would you go procedural in your view? If you understood that you should separate Javascript and CSS from your HTML, why would you mix PHP into your template? It doesn't make sense. The OP's code snippet is a script and not a template. As such, it is the domain of the developer. And because of that you apply all the good practise you apply to other parts of your application as well. And that includes isolating logic into functions and/or classes.
Granted, a designer looking into a script might not immediately know what's going on. But then again, she might not know that either once you start to add in native PHP functions. What's mb_strimwidth doing? And substr? What's that ?: construct? The more actual PHP you add, the harder it will be to read for non-developers.
If you want to have designers work on templates, don't give them scripts. Give them templates. And if you do, isolate the logic from it and replace it with easy to grasp function calls. Use function names that clearly communicate what the function does. So the designer only needs to know if "I use this with that input, I will always get that output. I don't care how that output comes to be. I'll leave that to the developer".
Isolating the logic into functions (or classes) also gives you the immediate advantage of being able to test the logic used to render specific parts on that page in isolation. You don't have to setup the entire environment required to create a page, but just pass in the required input and assert it's output (that's why the function buffers the string instead of outputting it btw).
¹For those of you who think this is not an issue, I strongly suggest to find yourself a legacy application that truly keeps all the logic in the view template. Try to change a few things. Once you have had the pleasure of eating through 2500 lines of spaghetti code with at least 500 chars each and containing a mix of repeated PHP, HTML, CSS and JavaScript you'll know what I am talking about.
I don't think what you're trying to achieve in the view is too much logic, but I think it should be cleaned up somewhat.
Something like:
<?php foreach($main as $item): ?>
<div class="item">
<div class="name"><?php echo $item['name']; ?></div>
<?php if($item['icq']): ?>
<div class="phone"><?php echo $item['phone']; ?></div>
<?php endif; ?>
</div>
<?php endforeach; ?>
I find that a lot easier to read, and it does the same job. I also don't think it would be hard for a non-coder to modify, which is ultimately the goal of a view.
When the templates need a lot of logic is could be useful to introduce the ViewModel pattern
The logic that determines when a certain block is shown is placed in the view model.
Example
A template snippet:
<?php if($item['show_phone_number']): ?>
<div class="phone"><?php echo $item['phone_number']; ?></div>
<?php endif; ?>
A view model snippet:
$item['show_phone_number'] = $item["icq"] == '';
short answer:
As little as is viably possible.
View is no a template.
Or at least - it should not be a template. Views are generally instance of classes, which are responsible for dealing with presentational logic. They juggle multiple templates and decide which one to use and what data pass into them.
But CI has none of this. You are basically stuck with a template, which pretends to be "View" , and and instances of ActiveRecord, which they tell you are "Models". Hell .. in proper MVC the Model isn't even a specific class but an application layer.
In long term, this situation will force both presentation logic and business logic into the controller, while at the same time, producing hard-to-maintain templates and activerecord classes.
I think as James, too much code, but you can add an array variable to the get_items() function, to control the prefix and suffix of each item, something like:
$options = Array('item_prefix' => '<div class="item">', 'item_suffix' => '</div>'...)
echo get_items();
Your views should definitely contain most of the html tags, so I do not think that a function get_items should be placed somewhere else. Just clean up your templates a little bit and work with the alternative loop syntax as suggested by Karpie. You could also think about using some existing templating engine like Twig but with that the views have to contain some references to your data as well...
What you want to achieve is that non-coders can edit your html files without having to understand too much scripting logic.
I have been designing websites for a while now, but there is one thing that I have never been quite sure of when using PHP and HTML. Is it better to have the whole document in PHP and echo HTML like so:
<?php
doSomething();
echo "<div id=\"some_div\">Content</div>";
?>
Or have a HTML file like so and just add in the PHP:
<html>
<body>
<?php doSomething(); ?>
<div id="some_div">Content</div>
</body>
</html>
It seems tidier to echo HTML, especially if lots of PHP gets used throughout the page, but doing so loses all formatting of the HTML i.e. colors in the IDE etc.
There are varying opinions on this. I think there are two good ways:
Use a templating engine like Smarty that completely separates code and presentation.
Use your second example, but when mixing PHP into HTML, only output variables. Do all the code logic in one block before outputting anything, or a separate file. Like so:
<?php $content = doSomething();
// complex calculations
?>
<html>
<body>
<?php echo $content; ?>
<div id="some_div">Content</div>
</body>
</html>
Most full-fledged application frameworks bring their own styles of doing this; in that case, it's usually best to follow the style provided.
I think this would depend on your group's or your own decided convention. And it can and should vary depending on what type of file you're working in. If you follow the MVC pattern then your views should be the latter. If you're writing a class or some non-output script/code then you should use the former.
Try to keep a separation of display or formatting of output and the logic that provides the data. For instance let's say you need to make a quick page that runs a simple query and outputs some data. In this case (where there is no other existing infrastructure or framework) you could place the logic in an include or in the top or the bottom of the file. Example:
<?php
# define some functions here that provide data in a raw format
?>
<html>
<body>
<?php foreach($foo = data_function($some_parameter) as $key => $value): ?>
<p>
<?=$value;?>
</p>
<?php endforeach; ?>
</body>
</html>
Or you could place the logic and function definitions in an include file or at the bottom of the file.
Now if you're producing some sort of class that has output (it really shouldn't) then you would echo the HTML or return it from the method being called. Preferably return it so that it can be output whenever and however the implementer would like.
The syntax highlighting is an important benefit of the second method, as you said. But also, if you're following good practices where logic and presentation are separated, you will naturally find that your files that contain HTML are almost entirely HTML, which then, naturally, leads to your second method again. This is the standard for MVC frameworks and the like. You'll have a bunch of files that are all PHP, doing logic, and then when that's done they'll include a presentation file which is mostly HTML with a sprinkling of PHP.
Simple:
More PHP - close HTML in PHP. When you generate HTML code in PHP, when you are doing something like a class, so it is better to make it in echo.
Less PHP - close PHP in HTML. This is stuff like just putting vars into fields of HTML stuff, like forms... And such.
The best approach is to separate the HTML from the PHP using template system or at least some kind of HTML skeleton like:
<main>
<header/>
<top-nav/>
<left-col>
<body />
</left-col>
<right-col />
<footer/>
</main>
Each node represents a template file e.g. main.php, hrader.php and so on. Than you have to separate the PHP code from the templates as something like functions.php and fineally use your second approach for template files and keeping functions clean of "echos" and HTML.
If you can, use a template engine instead.
Although it is slightly easier at first to mix your HTML and PHP, separating them makes things much easier to maintain later on.
I would recommend checking out TemplateLite which is based on Smarty but is a little more light weight.
I've reached a conclusion that using views in MVC framework e.g. Laravel, Yii, CodeIgniter is the best approach even if you are not displaying the html straight away.
Inside the view do all the echoing and looping of prepared variables, don't create or call functions there, unless formatting existing data e.g. date to specific format date('Y-m-d', strtodate(123456789)). It should be used only for creating HTML, not processing it. That's what frameworks have controllers for.
If using plain PHP, create you own view function to pass 3 variables to - html file, array of variables, and if you want to get output as string or print it straight away for the browser. I don't find a need for it as using frameworks is pretty much a standard. (I might improve the answer in the future by creating the function to get view generated HTML) Please see added edit below as a sample.
Frameworks allow you to get the HTML of the view instead of displaying it. So if you need to generate separate tables or other elements, pass the variables to a view, and return HTML.
Different fremeworks may use various type of templating languages e.g. blade. They help formatting the data, and essentially make templates easier to work with. It's also not necessary to use them for displaying data, or if forced to use it by the framework, just do required processing before posting the variables, and just "print" it using something like {{ yourVariable }} or {{ yourVariable.someProperty }}
Edit: here's a plain PHP (not framework PHP) - simple-php-view repository as a sample view library that allows to generate HTML using variables. Could be suitable for school/university projects or such where frameworks may not be allowed.
The repository allows to generate HTML at any time by calling a function and passing required variables to it, similar to frameworks. Separately generated HTML can then be combined by another view.
It depends on the context. If you are outputting a lot of HTML with attributes, you're going to get sick of escaping the quotation marks in PHP strings. However, there is no need to use ?><p><? instead of echo "<p>"; either. It's really just a matter of personal taste.
The second method is what I usually use. And it was the default method for me too. It is just to handy to get php to work inside html rather than echo out the html code. But I had to modify the httpd.conf file as my server just commented out the php code.