Professional Documents
Culture Documents
Dos and Donts of C Program
Dos and Donts of C Program
PHP:
If you have a function or method that might enter an unknown state, or unexpected state throw
exceptions, that's what they're for. Check your input and be aware that even if your function is
called only internally, you never know what people will get to work with the code and you
therefore never know what they might think is appropriate to feed it.
Don't:
PHP:
1 function checkStuff($foo) {
2 switch($foo) {
3 case 'a': return 1;
4 case 'b': return 5;
5 }
6}
Do:
PHP:
1 function checkStuff($foo) {
2 $ret = null;
3 switch($foo) {
4 case 'a':
5 $ret = 1;
6 break;
7 case 'b':
8 $ret =2;
9 break;
1 default:
0 throw new InvalidArgumentException('Expected a or b for $foo');
1 }
1 return $ret;
1}
2
1
3
1
4
The exceptions I use most are InvalidArgumentException (for arguments I didn't expect),
UnexpectedValueException (for return values of other functions I didn't expect) and
LogicException (for a combination of circumstances that don't make sense). Whenever possible
and suitable, I extend these to provide more information about the context of the exception.
1 function getCount() {
2 if(is_null($this->_count)) {
3 $this->_count = count($this->_property);
4 }
5 return $this->_count;
6}
Design by contract, design for extension
Try to extract interfaces for all your classes. Even if you don't explicitly use these interfaces, e.g.
in type hints, next to being a good exercise it still serves the purpose of showing what parts of a
class are specific to the classes (own) implementation and what parts aren't. In other words: it
shows the reader what functionality of a class is actually there because it follows a contract
defined by an interface, and what code is merely aiding the implementation; hence showing how
the same interface could be used for other implementations.
Designing for extension means that you show what parts are actually meant to be extended.
This does not mean that you should declare everything protected or public. It means that you
should think hard about what entry points a derived class should use, and where it is supposed
to hook into base functionality. Think about what method should be final and what properties
could possibly be private, so you're not ambiguous about where you'd want a derived class to
hook in:
Don't:
PHP:
Do:
PHP:
It goes without saying that if you don't intend your class to be extended at all, you should
declare it final too.
Last but not least: always define a base constructor, even if it does nothing. This way, a derived
class has no reason not to call the base constructor (which imho a derived class always should),
so you won't break compatibility if you add initialization code to the base constructor later.
Don't:
PHP:
Do:
PHP:
1 if($current == $last) {
2 echo $htmlTableFooter;
3}
And most of all, don't repeat your code in your comments, as I saw some time back:
PHP:
1 // get page
2 $page = getPage();
3
4 // assign page to template
5 $smarty->assign('page', $page);