What are the best practices for passing multiple variables to a function using PHP

function, php

Solution

Highly depends on the use case.

But here are some solutions to this problem.

Fixed Order

If the order is somewhat fixed and you never have a need to change it, then:

<?php

function fn($a1, $a2, $a3, $a4, $a5, $a6 = null, $a7 = "foo", $a8 = "bar", array $a9 = array()) {}

Pros

- Self documenting

- Type hinting

- Default values

Cons

- Fixed order

Array

If on the other hand the order is somewhat different all the time, use the array thingy.

<?php

function fn($a1, $a2, $a3, $a4, $a5, array $optional = array()) {}

fn("", "", "", "", "", array("arg9" => false));

Pros

- Easy to use

- No fixed order

Cons

- Not self documenting

- Costly to validate

Parameter Object

A parameter object is of course a valid solution as well, but impractical to handle:

<?php

class Args {

  public $arg5 = "foo";

  public $arg6 = "bar";

  public $arg7 = null;

  public $arg8 = array();

  public $arg9 = true;

}

function fn($arg1, $arg2, $arg3, $arg4, $arg5, \Args $optional = null) {}

// Now comes the impractical part.
$optional = new Args();
$optional->arg9 = false;
fn("", "", "", "", "", $optional);

Pros

- Self documenting

- No fixed order

Cons

- Highly impractical

- Costly to validate

Array to Parameter Object

You could mix the two approaches:

<?php

class Args {

  public $arg5 = "foo";

  public $arg6 = "bar";

  public $arg7 = null;

  public $arg8 = array();

  public $arg9 = true;

  public __construct($args) {
    foreach ($args as $property => $value) {
      $this->"set{$property}"($value);
    }
  }

  public function setArg5($value) {
    if (is_string($value) === false) {
      throw new \InvalidArgumentException;
    }
    $this->arg5 = $value;
  }

  // and so on ...

}

function fn($arg1, $arg2, $arg3, $arg4, $arg5, array $optional = null) {
  if (isset($optional)) {
    $optional = new Args($optional);
  }
  // ...
}

fn("", "", "", "", "", array("arg9" => false));

Pros

- Easy validation

- Separation of concern

- Easy to pass along

- Easy to handle

- Possible to document the API

Cons

- Still not possible to document it as good as the fixed args approach

- Costly to validate

Variadics

There's a new feature in PHP 5.6 that you might find useful, variadics:

<?php

function fn($a1, $a2, $a3, $a4, $a5, ...$optional) {}

Pros

- Very fast

- Allows to build special APIs (e.g. database prepared statement binding)

Cons

- Not easily documented

- Costly to validate

Named Parameters

And we might see named parameters in the future.

Problem

I have a function that takes 5 parameters, and as the application grew we needed to add few more parameters which ended up in 9 parameters with 4 of them having default values. I was wondering is it better to pass parameters like this or use an array? I prefer to have it like this ``` fun(array( 'par1' => 'x', 'par2' => 'y', ..... ) ) ``` Insted of ``` func($par1, $par2, $par3, ...); ``` What do you think?

Original source

Related problems