Writers who write professionally (for the media or in a book) often get the benefit of having an editor who will tell them when they’re wrong. For bloggers, our “editorial staff” is often the readers of our works. When enough people tell you that you’re wrong, it’s worth listening.
Last week was one of those weeks for me: my article, Always Return Something, was flat wrong. The arguments I made were hollow and the writing was bad. I apologize.
That said, I want to clarify exactly what I believe about returning values and proper coding procedure when writing functions. I do believe that strategic return values make a lot of sense. You should always return something.
There are many valid cases when you should return something like NULL. But there are many cases where developers allow NULL to be returned, when they can and in my opinion, should return something else. Let’s discuss a few of these.
Tell me what you did.
One common case for not having a return value is when you issue a command (see Command-query separation). However, for many commands I like it if you return to me the output of whatever you did, for later use by me should I need it.
For example, if you’re issuing a command line command, tell me what the result was. Return to me whatever the database returned to you if you’re issuing a database command. Sure, maybe that value isn’t usable but let me make that decision.
Don’t return null in error cases.
Many native PHP functions will emit a warning and return NULL if they are not provided the correct arguments. In my opinion, this is an incorrect behavior.
Instead, I believe your functions should issue exceptions. Sure, unhandled exceptions are fatal (while warnings are not), but at least give me the opportunity to fix whatever it was that I broke, or to fail gracefully.
Allow for fluent interfaces when they are appropriate.
I dislike fluent interfaces (and will write a separate post on my distain for them later this week). However, there are a few cases when I think a fluent interface is warranted.
The first case is in the setter methods of a class. You should be able to simply chain together the setter methods of a class to configure it. While there’s a definite fine line in having multiple setter calls (versus configuring the object in the constructor), I believe setters should generally return $this.
Secondly, when using an ORM or a data storage layer, fluent interfaces can be reasonable. For example:
<?php $db->fetch($conditions)->orderBy(‘date’)->limit(2)->execute(); ?>
This is a fluent interface that makes perfect sense to anyone who knows SQL. I embrace using fluent interfaces for this kind of communication, when the intent is clear and the outcome unambiguous.
But be sure to return NULL when it’s warranted.
Null is a value in PHP and should be returned in certain cases.
NULL is a perfectly valid value when the database returns a NULL to you. It’s also a perfectly valid response when requesting information that doesn’t exist. NULL is a perfectly valid response in these cases.
Use the return keyword often
I am a big fan of failing early. When you know that a request cannot be completed, or that the result result will be NULL, simply use the “return” keyword to end processing on a function.
Similarly, as a habit I usually use the “return” keyword at the end of a function even if the function will simply exit and even if I am not returning a value. PHP will return a NULL, but this return keyword will indicate to a developer who follows me that I intentionally ended the function, rather than simply let it die.
Returns are hard.
Understanding what to return and when is a complex process and there are many opinions. I like return values while other people don’t. In PHP, even functions that you leave without a return value will return NULL; this is expected behavior. Still, I favor being explicit over allowing PHP to naturally take its course, and I encourage you to do the same.