Передача большого числа аргументов в функцию PHP

Постановка задачи

Часто функции требуют большого числа аргументов. Иногда это нужно сразу при её написании, а иногда количество аргументов разрастается при рефакторинге или появлении нового функционала. Помимо того, что иметь, скажем, десять аргументов в функции или методе — просто не эстетично, это создаёт и дополнительные сложности.

Например, у нас есть метод:

public function someFunction ($name, $id, $some_optional_param = null, $obligatory=false, $checked=true)
{
// тело функции
}

К примеру, где-то в коде вы хотите вызвать этот метод, оставив два предпоследних аргумента со значениями по умолчанию. Это будет уныло. А если ваш метод будет разрастаться до ещё большего числа аргументов, то уследить за их чехардой и вовсе будет нетривиальной задачей.

Рефакторинг также может вызвать головную боль, если, к примеру, ваш метод теперь должен будет принимать на вход новый аргумент, который предполагается заполнять часто, не довольствуясь значением по умолчанию. По уму надо его поместить где-то в начале списка аргументов, но тогда вам придётся пройтись по всем вызовам этого метода во всём коде и проконтролировать правильность порядка передаваемых аргументов.

Решение

В подобных случаях все или часть аргументов можно внести в ассоциативный массив. Золотым правилом может быть такое:

Если в большинстве случаев предполагается передавать актуальное значение аргумента в функцию, то оставляем его в качестве отдельного аргумента.

Если часто нужно будет использовать значение по умолчанию, но вносим этот аргумент в массив дополнительных параметров. Делается это так:

public function someFunction($id, $some_important_argument, $options = array())
{
    $default_options = array(
        'optional_arg1'=>false,
        'optional_arg2'=>1
    //...
);

$options = array_merge_recursive($default_options, $options);

// тело функции

}

Здесь $options — это массив дополнительных аргументов, а $default_options — их значения по умолчанию. Если в $default_options описаны все возможные аргументы, то дальше в теле функции необязательно проверять ключ аргумента на существование в массиве. В любом случае будет использовано либо переданное значение, либо значение по умолчанию.

Вызов этой функции может выглядеть так:

someFunction(1, true, $array('optional_arg2'=>25));

1 комментарий

  1. Думаю, если метод должен принять большое число аргументов то что то не так с методом. Но если все же никак, то лучше использовать DTO:

    function someFunctino(SomeDTO $dto)
    {
    // some stuff
    }

Добавить комментарий для myrkox Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.