Bunkermaster's Debugging 101 and BuzzLY's Code Share in the Echo Lounge proved popular, and I thought something similar could be done here. Instead of debugging tips or nifty code snippets, though, I was thinking of providing a place where people could drop off (and critique!) tips for programming "Best Practice". Short subject-line-sized suggestions to write useful code/usable programs, and a blurb about why.
These are about program design and structure, and site usability/accessibility; everyone has their own style and there's no such thing as Best Practice about where to put the parentheses - only shop standards.
Same sort of thing as Debugging 101: [noparse]For tip titles[/noparse], and to kick things off here are a couple or three from me.
1. In instance methods, prefer returning $this to returning void.
Why? Many methods that return void exist to alter the state of the object, or to cause it to perform some sort of I/O. Often, calls to such methods are followed by further alterations or I/O. By having such a method return $this it's easy to chain calls. Instead of writing
$buffer->append($foo);
$buffer->normalize();
$buffer->fill($bar);
$buffer->write();
$buffer->truncate();
you can have
$buffer->append($foo)->normalize()->fill($bar)->write()->truncate();
Sometimes $this wouldn't be appropriate: for example, a shutdown method that makes the object unusable wouldn't yield any benefit by being made to return $this. But try and see if something useful can be returned - something that characterises what the object has just done (such as a collection object's "delete" method(s) returning what was just deleted).
2. Prefer class constants to defined constants.
Instead of
define('SOMECLASS_FOO', 42);
class SomeClass
{
use
class SomeClass
{
const FOO = 42;
Why?
Automatic namespacing: if the constant value belongs to a particular class, it ought to say so. Personally, I'd've made the DOM extension's "XML" constants all class constants of DOMNode or DOMAttr depending, and the "DOM" class constants of DOMException; but I didn't write the DOM spec I'd've preferred DOMNode::ENTITY to XML_ENTITY_NODE and DOMAttr::ID to DOM_ATTRIBUTE_ID.
But the real reason is compile-time parsing and optimisation. The define() function is executed at runtime, so creating the symbol and giving it a value has to wait until then; a class constant is parsed at compile time and an optimising bytecode compiler can create the symbol, give it a value, and substitute that value for the symbol when it appears before the program runs.
Of course, not all defined constants can be turned into class constants: some constants just don't belong to classes (even if you create an interface to contain them), while others can't be determined until runtime (class constants are by definition statically initialised). And then there is the slightly disturbing fact that defined constants can use arbitrary strings for names (using class constants avoids doing this).
Update: From PHP 5.3.0, [man]const[/man] can be used outside of class definitions as well. For groups of related constants, having them in a class groups them together and also provides a place where methods that rely principally on those constants can reside.
3. Give select drop downs quickly-distinguishable names
I got the idea from this one from the search page here, unfortunately. I was tabbing through filling out the keywords and I wanted to search by title. If "Search" had been plain text, followed by a dropdown containing "Entire Posts" and "Titles Only", then I could have reached it by typing 'T'. But as it stands, trying to type the desired dropdown value means typing "Search T".
Yeah, yeah, it's only two options. But it's easy to imagine quite reasonable dropdowns with a couple of dozen entries (the time zone selector on your edit options page, for example).
Of course, the text that appears in a drop down does have to mean something, and it does have to fit everything else. As George Orwell put it, "Break any of these rules sooner than say anything outright barbarous."