Функция PHP с дополнительными параметрами

Я написал функцию PHP, которая может принимать 10 параметров, но требуется только 2. Иногда я хочу определить восьмой параметр, но я не хочу вводить пустые строки для каждого из параметров, пока не достиг восьмого.

Одна из моих идей заключалась в том, чтобы передать абстрактную функцию с массивом параметров, которые передают ее к реальной функции.

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

Сделать функцию одним параметром: массив. Передайте фактические параметры как значения в массиве.


Изменить: ссылка в комментарии Пекки просто подводит итог.

То, что я сделал в этом случае, – это передать массив, где ключ – это имя параметра, а значение – значение.

$optional = array( "param" => $param1, "param2" => $param2 ); function func($required, $requiredTwo, $optional) { if(isset($optional["param2"])) { doWork(); } } 

Чтобы выполнить то, что вы хотите, используйте массив, как сказал Раббот (хотя это может стать болью для документирования / поддержки при чрезмерном использовании). Или просто используйте традиционные необязательные аргументы.

 //My function with tons of optional params function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL) { //Do stuff } my_func('Hi', 'World', null, null, 'Red'); 

Тем не менее, я обычно обнаруживаю, что, когда я начинаю писать функцию / метод с таким количеством аргументов, чаще всего это запах кода, и его можно переопределить / абстрагироваться во что-то гораздо более чистое.

 //Specialization of my_func - assuming my_func itself cannot be refactored function my_color_func($reg_a, $reg_b, $opt = 'Red') { return my_func($reg_a, $reg_b, null, null, $opt); } my_color_func('Hi', 'World'); my_color_func('Hello', 'Universe', 'Green'); 

Проверьте значения аргументов по умолчанию в документации php.

Примечание: это старый пост, но может помочь кому-то сейчас или в будущем.

Вы можете достичь этого, используя один из этих двух методов:

  • используя функции func_num_args () и func_get_arg () ;
  • используя аргументы по умолчанию;

Как использовать

 function method_1() { $arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_fot_arg1"; $arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_fot_arg2"; } function method_2($arg1 = null, $arg2 = null) { $arg1 = $arg1? $arg1: "default_value_fot_arg1"; $arg2 = $arg2? $arg2: "default_value_fot_arg2"; } 

Я предпочитаю второй метод, потому что он чист и понятен, но иногда вам может понадобиться первый метод.

В PHP 5.6 и более поздних версиях списки аргументов могут включать … токен, чтобы обозначить, что функция принимает переменное количество аргументов. Аргументы будут переданы в заданную переменную в виде массива; например:

Пример использования … для доступа к аргументам переменной

 <?php function sum(...$numbers) { $acc = 0; foreach ($numbers as $n) { $acc += $n; } return $acc; } echo sum(1, 2, 3, 4); ?> 

Вышеприведенный пример выводит:

 10 

Переменные аргументов переменной содержат документацию по PHP

Если для создания объекта с допустимым состоянием требуются только два значения, вы можете просто удалить все остальные необязательные аргументы и предоставить для них сеттеры (если вы не хотите, чтобы их изменяли во время выполнения). Затем просто создайте объект с двумя необходимыми аргументами и установите остальные по мере необходимости через установщик.

дальнейшее чтение

  • Мартин Фаулер о конструкторе против инъекции сеттера и
  • Инъекция зависимостей через конструкторы или средства определения свойств?

Я знаю, что это старый пост, но у меня была проблема, подобная OP, и это то, к чему я пришел.

Пример массива, который вы могли бы передать. Вы можете заказать это, если требуется определенный заказ, но для этого вопроса это будет делать то, что задано.

 $argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here'); 

Это управляемо, легко читается, и точки извлечения данных могут быть добавлены и удалены в момент уведомления в любом месте кодирования и все же избежать массового переписывания. Я использовал целые ключи для подсчета с исходным вопросом OP, но строковые ключи можно было использовать так же легко. На самом деле для удобочитаемости я бы посоветовал это.

Прикрепите это во внешнем файле для удобства

 function unknown_number_arguments($argument_set) { foreach ($argument_set as $key => $value) { # create a switch with all the cases you need. as you loop the array # keys only your submitted $keys values will be found with the switch. switch ($key) { case 1: # do stuff with $value break; case 2: # do stuff with $value; break; case 3: # key 3 omitted, this wont execute break; case 5: # do stuff with $value; break; case 8: # do stuff with $value; break; default: # no match from the array, do error logging? break; } } return; } 

поставьте это в начале, если файл.

 $argument_set = array(); 

Просто используйте их, чтобы назначить следующий фрагмент данных для нумерации / именования в соответствии с тем, откуда поступают данные.

 $argument_set[1][] = $some_variable; 

И, наконец, передать массив

 unknown_number_arguments($argument_set); 

Я думаю, вы можете использовать объекты как params-transportes.

 $myParam = new stdClass(); $myParam->optParam2 = 'something'; $myParam->optParam8 = 3; theFunction($myParam); function theFunction($fparam){ return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!"; } 

Разумеется, вы должны установить значения по умолчанию для «optParam8» и «optParam2» в этой функции, в другом случае вы получите «Примечание: неопределенное свойство: stdClass :: $ optParam2»

Если вы используете массивы в качестве функциональных параметров, мне нравится, чтобы установить значения по умолчанию:

 function theFunction($fparam){ $default = array( 'opt1' => 'nothing', 'opt2' => 1 ); if(is_array($fparam)){ $fparam = array_merge($default, $fparam); }else{ $fparam = $default; } //now, the default values are overwritten by these passed by $fparam return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!"; } 

Если вы обычно просто передаете 8-е значение, вы можете изменить порядок своих параметров так, чтобы он был первым. Вам нужно только указать параметры до последнего, который вы хотите установить.

Если вы используете разные значения, у вас есть 2 варианта.

Можно было бы создать набор функций обертки, которые принимают разные параметры и устанавливают значения по умолчанию для остальных. Это полезно, если вы используете только несколько комбинаций, но можете очень быстро разобраться.

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

 func( "1", "2", default, default, default, default, default, "eight" );