I have a method like this:
public function create (array $hash) {
$id = $hash[ID_KEY];
$this->store[$id] = $hash;
}
I want to guard it against bugs caused by bad input. For instance, my code can mistakenly pass $hash
with
$id = '' or $id = null,
in which case it will be stored silently referenced by null
. Instead I want to see a warning and revise my code to get rid of it. So I guess the best way is to throw Exception:
if (! $id) throw new Exception("Hash with empty id");
Note that I am using empty strings as default values for several method arguments and for default return values, so this kind of bug can easily occur. (Using null
instead of empty string here doesn't seem to change anything, even if it is not recommended by Uncle Bob.)
The problem is -- there are many methods like that. Is it really best practice to guard each of them for each argument that can become null
but shouldn't?
For instance, another method does only reading. Then it seems there is no need to guard against null
because nothing will ever be stored referenced by null
, right? Or shall I still guard defensively, to prepare for the case I may somewhere in the future decide to allow storage referenced by null
and forget to adjust the guards?
This sounds kind of the safest way but would clutter all methods with bulks of guarding code for all indices involved there. Is this really the best way?
EDIT. I put more guards and indeed discovered few bugs that I wouldn't find otherwise. Also my tests didn't spot them.
Furthermore, it helped to better understand the role of read methods - to return value if found or return empty Array
if not. The input $id = null
goes under not found and hence also returns empty Array
. That way the method is clean and consistent.
You can use PHP's is_null() and empty() to easily manage this kind of output. Also I suggest you to write a list of function used only in debug (since you want to perfectionate your code). Call these function in each method you want to test and set a constant like DEBUG_MODE to handle the debug functions' behavior. All of this could be also done using unit testing, which would require more attention and time. But if you have both or want to learn something new, unit testing is clearly a better choice.
Also it is a good practice to handle ALL CASES you can think of. For instance, if your "reading method" expects not to find a null value (because you think there are none because you eradicated by testing over testing), if this "reading method" happens to find a null value a "ugly" PHP error would be shown somewhere, or worse, if error_report is shut you might never see a problem, or even worse, the code might continue its execution and utterly damage further data.