Ответ 1
Сделать функцию одним параметром: массив. Передайте фактические параметры как значения в массиве.
Изменить: ссылку в комментарии Pekka, просто подводит итог.
Я написал функцию PHP, которая может принимать 10 параметров, но требуется только 2. Иногда я хочу определить восьмой параметр, но я не хочу вводить пустые строки для каждого из параметров, пока не достиг восьмого.
Одна из моих идей заключалась в том, чтобы передать абстрактную функцию с массивом параметров, которые передают ее к реальной функции.
Есть ли лучший способ настроить функцию, чтобы я мог передавать только те параметры, которые я хочу?
Сделать функцию одним параметром: массив. Передайте фактические параметры как значения в массиве.
Изменить: ссылку в комментарии Pekka, просто подводит итог.
Что я сделал в этом случае, это передать массив, где ключ - это имя параметра, а значение - это значение.
$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.
ПРИМЕЧАНИЕ. Это старый ответ для PHP 5.5 и ниже. PHP 5. 6+ поддерживает аргументы по умолчанию
В PHP 5.5 и ниже вы можете достичь этого, используя один из этих 2 методов:
function method_1()
{
$arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
$arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}
function method_2($arg1 = null, $arg2 = null)
{
$arg1 = $arg1? $arg1: "default_value_for_arg1";
$arg2 = $arg2? $arg2: "default_value_for_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
function functionName($value, $value2 = null) {
// do stuff
}
Я думаю, вы можете использовать объекты как params-транспорты.
$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" в этой функции, в противном случае вы получите "Notice: Undefined property: 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']."!";
}
Если для создания объекта с допустимым состоянием требуется только два значения, вы можете просто удалить все остальные необязательные аргументы и предоставить для них сеттеры (если вы не хотите, чтобы они менялись во время выполнения). Затем просто создайте объект с двумя необходимыми аргументами и установите остальные по мере необходимости через установщик.
Дальнейшее чтение
Я знаю, что это старый пост, но у меня была проблема, подобная 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);
Если вы обычно просто передаете 8-е значение, вы можете изменить порядок своих параметров так, чтобы он был первым. Вам нужно только указать параметры до последнего, который вы хотите установить.
Если вы используете разные значения, у вас есть 2 варианта.
Можно было бы создать набор функций-оболочек, которые принимают разные параметры и устанавливают значения по умолчанию для остальных. Это полезно, если вы используете только несколько комбинаций, но можете очень быстро разобраться.
Другой вариант - передать массив, где ключи являются именами параметров. Затем вы можете просто проверить, есть ли значение в массиве с ключом, и если не использовать значение по умолчанию. Но опять же, это может стать беспорядочным и добавить много дополнительного кода, если у вас много параметров.
function yourFunction($var1, $var2, $optional = Null){
... code
}
Вы можете создать обычную функцию, а затем добавить необязательные переменные, задав для них значение Null по умолчанию.
Значение Null по-прежнему является значением, если вы не вызовете функцию со значением для этой переменной, оно не будет пустым, поэтому без ошибок.
func( "1", "2", default, default, default, default, default, "eight" );