The truth is that some practices will pay off
in spades toward making your code coder-friendly. Others are more of a
nice touch. For now, I would like to sketch out the basics and show you
how to make gains quickly with a few practical points.
Practical PHP Coding Standards
I
have been thinking a lot lately about PHP coding standards. I recently
became intimately familiar with the Pear Coding Standards through
developing hands-on in that style. The truth is that while many points
seemed valuable, on the whole a lot of the "finer points" of the coding
standards did not really seem like the kind of stuff that would
necessarily make code more maintainable for teams. The truth is that
some practices will pay off in spades toward making your code
coder-friendly. Others are more of a nice touch.
In my upcoming article for International PHP Magazine, I plan to go
into detail on the enterprise PHP coding standards I have employed and
found useful in developing business-critical web applications. For now,
I would like to sketch out the basics and show you how to make gains
quickly with a few practical points:
- Use PHPDocumentor to document all functions and classes
- Separate Code From Content (html)
- Separate Content From Layout and Formatting (css)
First,
we will briefly touch upon documentation. Extremists in the extreme
programming camp might try to persuade you that coding well and coding
in pairs means the code documents itself. The truth is, however, that
not all developers want to dig through code to find out how it works --
they just want to reapply it quickly to their own situation. This is
especially true in the case of an API. Enter PHPDocumentor.
PHPDocumentor is a very valuable tool for creating developer
documentation. All functions and classes should be documented using
PHPDocumentor DocBlocks and should be tested to make sure that
PHPDocumentor can generate documentation from this code without errors
or warnings.
More important than just the tool used, the documentation must be written in a useful way. This means:
- Document all input variables, their type, and any ranges (e.g. an integer between 1 and 10)
- Document all output variable(s), and their type(s)
- Document any side effects (e.g. changing a global variable or class variable)
- Describe what the function does or what the class does
- (Optional) Give an example of how to use the function or class
See the example in the Pear manual for a demonstration of these principles.
The second directive is: Separate Code From Content. This means use a
templating system. The most basic form of templating system is to
simply use PHP itself to only output variables and maybe perform some
minimal formatting on the variable output. For example:
<table>
<tr>
<td>
<?= $foo; ?>
</td>
<td>
<?= date("l dS of F Y h:i:s A", $bar); ?>
</td>
...
Other examples of templating systems include Smarty and Flexy.
Using a templating system means making a conscious decision to divide
programmatically generated content up into variables. The criteria are:
- Where the string will live on the page (layout)
- How the string will look in terms of style (formatting)
The
end result is that HTML tags and content should not be output from the
main program using print or echo wherever possible. Instead, variables
should be passed into the template, and the template should handle
outputting the contents of the variable as well as minor formatting
(for example, transforming an ISO date into a more human-readable date).
Separating code from content has many benefits. Probably the single
greatest impact is maintainability. Not having to think in both PHP and
HTML makes a developer's life easier. Much easier. Furthermore,
multi-language sites benefit tremendously from using templates.
Finally, a template system can be used to change the "skin" or overall
look-and-feel of an application without changing the underlying
functionality. The Serendipity blog system I use on my personal web
site is skinnable, and the look-and-feel of my site was rendered
entirely through use of the web-based admin tool to choose sidebar
content and CSS for look-and-feel. More on the power of
layout-independent content when we look at separating content from
layout and formating via css.
There are, of course, some exceptions to the use of templates. For
example, when returning large sets of MySQL data into a table, it is
often much faster to display the results of mysql_fetch_array() or
mysql_fetch_assoc directly using echo. This kind of tradeoff can be
easily achieved by using PHP as your template system. Exceptions made
for sake of performance are important to note in your documentation, so
that developers understand you were being deliberate, not lazy, in your
choices.
Another major benefit of a template engine is division of labor.
Programmers can program, and designers can design in HTML, then paste
in the appropriate tags to display the programmatically generated
content. This is also one of the major benefits of the third guideline:
separate content from layout and formatting. This is partly achieved
through using a template engine. The other half of the equation is
Cascading Style Sheets or CSS.
While this may at first seem more like a design issue than a PHP issue,
the truth is I have seen way too many lines of code that look like this:
<?PHP
$foo = '<center><font color="#FF0000">'.$bar.'</font></center>';
?>
...
<?= $foo ?>
Using CSS, you can separate the formatting and layout from the content itself, as follows:
<style type="text/css">
.error {
color: #FF0000;
text-align: center;
}
</style>
...
<div class="error"><?= $bar ?></div>
In practice, it is also a good idea to move CSS code as well as
Javascript code off the main page, into separate files and use <link
rel=...> to make the contents of these external files available on
the main page. It is not only helpful for pushing real content further
up the page for purposes of search engine ranking, but it keeps the
HTML less cluttered and means less scrolling to get at the body content.
Dynamically generating CSS is typically a bad idea. Unless the
application absolutely needs this, generating CSS in PHP puts
responsibility for the style elements in the programmer's court, rather
than the designer's court. Calling up different stylesheets that can be
manipulated statically by a designer is a different matter -- this is
an excellent way to provide a different look-and-feel to your web
application based on, for example, the company of the person that is
using the application. Such 'rebranding' can often be rolled together
with custom content on a per-company basis to create a unique portal
environment.
The power of CSS as a means to replacing tables for layout is
strikingly displayed in the CSS Zen Garden. In practical usage, I find
a combination of tables and CSS still makes for the fastest and most
efficient way to create layout. As browsers (and designers) mature, it
appears that <div> will be fast replacing <table> not only
for formatting and style but layout as well.
Keeping content separate from layout keeps the both the division of
work and the division of elements (PHP, HTML, CSS) very clear. This
increases maintainability as well as accountability for each aspect of
the site -- designers design, coders code.
I hope you have enjoyed this tutorial and that your team development
projects get a quick and painless boost in productivity by following
these simple guidelines. Look for my upcoming article in International
PHP Magazine, where I will go into greater detail about Enterprise PHP
Coding standards, or how to make the CEO fall in love with PHP.
|