Yahya Uddin Yahya Uddin - 1 year ago 73
PHP Question

PHP: Sending a list of options as an argument (alternative to named parameters/ argument bag)

I wish to give a list of options as an argument to a function.

The Ideal Scenario: Named Parameters

If PHP has named parameters it would be done like so:

function setOptions($title, $url, $public = true, $placeholder = "type here...") {

setOptions($title = "Hello World", $url = "example.com", $placeholder = "hi");

Unfortunately PHP does not have named parameters (please tell me if PHP7 is planned to have some as a comment).

The solution everyone else is using: Associative Array

Most PHP scripts I have seen use an alternative array approach like so:

function setOptions($options) {

'title' => "Hello World",
'url' => "example.com",
'placeholder' => "hi"

Drawbacks of Associative Array Approach

Although this works fine, there are the following drawbacks:

  • The user does not benefit from autocompletion (taking a long time to write)

  • The user can easily makes mistakes in spellings

  • The don't know what options is available, so may frequently revert back to documentation

Is there a better way?

Is there a better way that can address these issues (either in current PHP or PHP7 or maybe even hacklang(?)).

Answer Source

In Hack, you can use Shapes. Shapes define a structure for associative arrays so that things can be autocompleted (depending on IDE support) and spelling mistakes are picked up by the type checker.

For instance, your example could be reworked like:

function setOptions(shape(
  'title' => string,
  'url' => string,
  'public' => ?bool,
  'placeholder' => ?string,
) $options) {
  $title = $options['title'];
  $url = $options['url'];
  $public = Shapes::idx($options, 'public', true);
  $placeholder = Shapes::idx($options, 'placeholder', 'type here...');

  'title' => 'Hello World',
  'url' => 'example.com',
  'placeholder' => 'hi',

This marks title and url to both be required options and public and placeholder are optional (all nullable types in shapes are considered to be optional). Shapes::idx is then used to get the value provided, or the default value (the third argument) if a value was not passed in.