PHP Function Arguments - Use an array or not?

2020-05-24 05:34发布

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?

9条回答
走好不送
2楼-- · 2020-05-24 06:01

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).

查看更多
别忘想泡老子
3楼-- · 2020-05-24 06:05

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.

查看更多
Root(大扎)
4楼-- · 2020-05-24 06:11

Your co-worker is crazy. It's perfectly acceptable to pass in an array as a function argument. It's prevalent in many open source applications including Symfony and Doctrine. I've always followed the 2 argument rule, if a function needs more than two arguments, OR you think it will use more than two arguments in the future, use an array. IMO this allows for the most flexibility and reduces any calling code defects which may arise if an argument is passed incorrectly.

Sure it takes a little bit more work to extrapolate the values from the array, and you do have to account for required elements, but it does make adding features much easier, and is far better than passing 13 arguments to the function every time it needs to be called.

Here is a snippet of code displaying the required vs optional params just to give you an idea:

// Class will tokenize a string based on params
public static function tokenize(array $params)
{
    // Validate required elements
    if (!array_key_exists('value', $params)) {
        throw new Exception(sprintf('Invalid $value: %s', serialize($params)));
    }        

    // Localize optional elements
    $value            = $params['value'];
    $separator        = (array_key_exists('separator', $params)) ? $params['separator'] : '-';
    $urlEncode        = (array_key_exists('urlEncode', $params)) ? $params['urlEncode'] : false;
    $allowedChars     = (array_key_exists('allowedChars', $params)) ? $params['allowedChars'] : array();
    $charsToRemove    = (array_key_exists('charsToRemove', $params)) ? $params['charsToRemove'] : array();

....
查看更多
登录 后发表回答