PHP Function Arguments - Use an array or not?

21,090

Solution 1

Well, it's kinda usefully. But for some arguments which is passing always it's better to use classic passing like function some($a1, $a2). I'm doing like this in my code:

function getSome(SomeClass $object, array $options = array())
{
    // $object is required to be an instance of SomeClass, and there's no need to get element by key, then check if it's an object and it's an instance of SomeClass

    // Set defaults for all passed options
    $options = array_merge(array(
        'property1' => 'default1',
        'property2' => 'default2',
        ... => ...
    ), $options); 
}

So, as you can see I like that code style too, but for core-arguments I prefer classic style, because that way PHP controls more things which should I, if I used the you code style.

Solution 2

Don't do that!

Passing all in an array is a bad idea most of the time.

  • It prevents people from using your function without knowing what it needs to operate.
  • It lets you create functions needing lots of parameters when probably you should create a function with more precise argument needs and a narrower goal

It seems like the contrary of injecting in a function what it needs.

Function arguments can be provided in any order

I have no such preference. I don't understand that need.

Easier to read code / more self documenting (in my opinion)

Most IDEs will present you with the different arguments a function needs. If one sees a function declaration like foo(Someclass $class, array $params, $id) it is very clear what the function needs. I disagree that a single param argument is easier to read or self documenting.

Less prone to errors, because when calling a function I must investigate the proper array keys

Allowing people to pass in an array without knowing that values will be defaulted is not close to "not error-prone". Making it mandatory for people to read your function before using it is a sure way for it never to be used. Stating that it needs three arguments along with their defaults is less error prone because people calling your function will know which values the parameters will be defaulted to, and trust that it will present the result they expect.


If the problem you are trying to solve is a too great number of arguments, the right decision is to refactor your functions into smaller ones, not hide function dependencies behind an array.

Solution 3

I'm assuming you're asking whether it's A Good Thing to write all functions so that they accept only one argument, and for that argument to be an array?

If you're the only person who's ever going to work on your code then you can do what you like. However, by passing all argument values through an array, anyone else is going to have to work harder to understand what the function does and why / how they could use it, especially if they're using an IDE with auto-complete for function names etc. They don't call it a "function signature" for nothing.

I'd recommend that array parameters are reserved either for items where you don't know how many there will be (e.g. a series of data items), or for groups of related options / settings (which may be what's going on in the Wordpress example that you mention?).

If you do continue with a blanket approach to array arguments then you should at least be aware of its impact on readability and take some steps to counter that issue.

Solution 4

Your co-worker is right. Not only is it more code for the same functionality, it is harder to read and probably has lowered performance (Since you need to call isset for each param and you need to access an array to set values).

Solution 5

This borders on Cargo Cult programming. You say this is more readable and self-documenting. I would ask how? To know how to use your function/method I have to read into the code itself. There's no way I can know how to use it from the signature itself. If you use any half-decent IDE or editor that supports method signature hinting this will be a real PITA. Plus you won't be able to use PHP's type-hinting syntax.

If you find you are coding a load of parameters, especially optional parameters then it suggests there might be something wrong with your design. Consider how else you might go about it. If some or all of the parameters are related then maybe they belong to their own class.

Share:
21,090
ethanpil
Author by

ethanpil

Updated on July 09, 2022

Comments

  • ethanpil
    ethanpil almost 2 years

    I like creating my PHP functions using key=>value pairs (arrays) as arguments instead of individual parameters.

    For example, I prefer:

    function useless_func($params) {
        if (!isset($params['text'])) { $params['text'] = "default text"; }     
        if (!isset($params['text2'])) { $params['text2'] = "default text2"; }   
        if (!isset($params['text3'])) { $params['text3'] = "default text3"; }   
        echo $params['text'].$params['text2'].$params['text3'];
        return;
    }
    

    And I don't like:

    function useless_func($text = "default text", $text2 = "default text2", $text3 = "default text3") {
            echo $text.$text2.$text3;
        return;
    }
    

    I had first seen things done this way extensively in the Wordpress codebase.

    The reason I prefer arrays:

    • Function arguments can be provided in any order
    • Easier to read code / more self documenting (in my opinion)
    • Less prone to errors, because when calling a function I must investigate the proper array keys

    I was discussing this with a co-worker and he says that it's useless and just leads to extra code and it's much harder to set the default values. Basically, he disagrees with me completely on all three points.

    I am looking for some general advise and guidance from experts who might be able to provide insight: What's the better or more proper way to do this?