Ok, so passing arbitrary data grouped in arrays as parameters is not that bad, it’s certainly not evil, but there are definitely nicer ways to code. Here I’ll show you exactly why it’s not good programming practice.
First let me explain what I mean. When I say “passing arbitrary data grouped in arrays as parameters” I mean grouping some or all of the inputs to a method in an array and passing the array into the method call.
Lets look at an example. Image a login() method which has a signature like this:
public function login( array $parameters );
One might use the method like this:
$parameters = array ( 'user' => 'Billy', 'password' => 'pass', 'source_url' => '/home' ); $loginService->login($parameters);
So what’s wrong with using arrays like this? The big problem is that the methods contract is not clear. From looking at the methods signature we don’t get any clues about what the method needs in order to do its job, we only know that it needs an array called $parameters, which could be anything. What does the method need us to put into the $parameters array? To find this out we have to go and take a look at the code in the method; a complete waste of time which could be easily avoided.
You might think that having a vague contract is not that serious but really it is. An unclear contract makes your code more difficult to understand, and the number two rule of programming is that your code should be as easy to understand as possible (number one rule is that it works :)).
The vague contract has another problem too: you’re IDE won’t be able to help you at all when it comes to informing you what this method should accept, and for a developer in the flow that’s just frustrating.
The second reason why using arrays to group arbitrary method arguments is a little more subtle, it affects the quality of your code in ways you might not immediately see. It has to do with coupling, Stamp Coupling to be exact. Let’s have a quick look at the definition of Stamp Coupling:
Stamp coupling occurs between modules when data are passed by parameters using a data structure containing fields which may or may not be used
Stamp coupling promotes the creation of artificial data structures (i.e., grouping unrelated data elements together in a structure). Although this grouping was done with the intention of reducing coupling between modules, it in fact increases the coupling between modules since we are grouping unrelated data. This becomes a problem if the code that created the array in the first place changes, because it forces all the code where that data structure is accessed to change too, and since our method gets some elements out of the array it needs to know the exact structure of it, hence the coupling. You might be thinking “hang on, wouldn’t the same thing happen even if we grouped the data into an object instead of using an array?” and you’d be right, that’s why it is very important to think carefully about how you group data into data structures; only do it if the data is very related because then the data structure will be much less likely to need to change.
Back to our original example. I’m sure you’ve already spotted it but here comes the cleaner way of doing it: we change the signature of the login() method to explicitly specify the arguments it needs. This forces us to explicitly pass in the information that we need and nothing more. Now the methods signature is much easier to understand, and your IDE will be able to helpfully tell you that the login() method needs three parameters: $user, $password and $sourceUrl to work.
$loginService->login('Billy', 'pass', '/home');
Cases where arrays as arguments are good
I want to point out that there is a situation where passing arrays into methods is perfectly acceptable: when the array is a genuine collection of things. For example maybe we grouped a collection of videos into an array and the method needs all the videos as an argument. This is perfectly fine. Things get ugly only when we start grouping arbitrary data into arrays and passing them into methods.
Passing arbitrary data structures into methods is not good software design, since it makes the code more difficult to read (and therefore maintain) and it increases coupling. Instead, try to be explicit about what the method needs in order to do its job.
You’ll notice that it would be even better if we could type hint the arguments which the method needs because then it would be even more obvious what the method needs. We could also group the username and password into a User entity and pass that in instead of using strings, but thats another post.
Please contribute your thoughts below. What do you think about using arrays as arguments for methods?