У меня есть это:
function foo($a='apple', $b='brown', $c='Capulet') { // do something }
Что-то вроде этого возможно:
foo('aardvark', <use the default, please>, 'Montague');
Если это ваша функция, вы можете использовать null
качестве подстановочного знака и установить значение по умолчанию позже внутри функции:
function foo($a=null, $b=null, $c=null) { if (is_null($a)) { $a = 'apple'; } if (is_null($b)) { $b = 'brown'; } if (is_null($c)) { $c = 'Capulet'; } echo "$a, $b, $c"; }
Затем вы можете пропустить их, используя null
:
foo('aardvark', null, 'Montague'); // output: "aarkvark, brown, Montague"
Если это ваша собственная функция, а не ядро PHP, вы можете сделать следующее:
function foo($arguments = []) { $defaults = [ 'an_argument' => 'a value', 'another_argument' => 'another value', 'third_argument' => 'yet another value!', ]; $arguments = array_merge($defaults, $arguments); // now, do stuff! } foo(['another_argument' => 'not the default value!']);
Нашли это, вероятно, все еще правильно:
http://www.webmasterworld.com/php/3758313.htm
Короткий ответ: нет.
Длинный ответ: да, в разных kludgey способами, которые описаны в выше.
Вы в значительной степени нашли ответ, но академический / высокоуровневый подход – это функция currying, которую я, честно говоря, никогда не использовал, но полезен для того, чтобы знать, что существует.
Вы можете использовать некоторые причуды, передавая все аргументы в виде массива, например, ceejayoz , или некоторый сложный код, который анализирует func_get_args () и сливается со списком значений по умолчанию. Чтобы не скопировать его, вам придется использовать объекты и черты. Наконец, чтобы иметь возможность передавать все виды значений (не исключая нуль или ложь, делая их сигналом для замены подстановки по умолчанию), вам придется объявить фиктивный специальный тип DefaultParam. Еще один минус заключается в том, что вам нужно дублировать имена и значения по умолчанию в объявлении функции, если вы хотите получить подсказки типа или помощь в любой среде IDE.
class DefaultParam {} trait multi_arg_functions { private static function multi_arg($defaults, $list, $preserve_index = false) { $arg_keys = array_slice(array_keys($defaults), 0, count($list)); if ($preserve_index) { $listed_arguments = array_slice($list, 0, count($arg_keys)); $extras = array_slice($list, count($arg_keys), null, true); } else { $listed_arguments = array_splice($list, 0, count($arg_keys)); $extras = &$list; } unset($list); $arguments = array_combine($arg_keys, $listed_arguments); $arguments = array_filter($arguments, function ($entry) { return !($entry instanceof DefaultParam); //remove entries that mean default, a special class in this case }); $arguments = array_merge($defaults, $arguments); return [$arguments, $extras]; } } class b { use multi_arg_functions; static function func1($an_argument = 'a value', $another_argument = 'another value', $third_argument = 'yet another value') { //give defaults here to get hints in an IDE list($args, $extras) = self::multi_arg( //note: duplicate names and defaults [ 'an_argument' => 'a value', 'another_argument' => 'another value', 'third_argument' => 'yet another value!', ], func_get_args()); echo json_encode(['args' => $args, 'extras' => $extras])."\n"; } } $default_param = new DefaultParam(); b::func1('value 1'); b::func1('value 2', $default_param, 'third argument'); b::func1('value 3', $default_param, 'third argument', 'fourth argument');
сclass DefaultParam {} trait multi_arg_functions { private static function multi_arg($defaults, $list, $preserve_index = false) { $arg_keys = array_slice(array_keys($defaults), 0, count($list)); if ($preserve_index) { $listed_arguments = array_slice($list, 0, count($arg_keys)); $extras = array_slice($list, count($arg_keys), null, true); } else { $listed_arguments = array_splice($list, 0, count($arg_keys)); $extras = &$list; } unset($list); $arguments = array_combine($arg_keys, $listed_arguments); $arguments = array_filter($arguments, function ($entry) { return !($entry instanceof DefaultParam); //remove entries that mean default, a special class in this case }); $arguments = array_merge($defaults, $arguments); return [$arguments, $extras]; } } class b { use multi_arg_functions; static function func1($an_argument = 'a value', $another_argument = 'another value', $third_argument = 'yet another value') { //give defaults here to get hints in an IDE list($args, $extras) = self::multi_arg( //note: duplicate names and defaults [ 'an_argument' => 'a value', 'another_argument' => 'another value', 'third_argument' => 'yet another value!', ], func_get_args()); echo json_encode(['args' => $args, 'extras' => $extras])."\n"; } } $default_param = new DefaultParam(); b::func1('value 1'); b::func1('value 2', $default_param, 'third argument'); b::func1('value 3', $default_param, 'third argument', 'fourth argument');
Примечание: с помощью preserve_index = true вы получаете дополнительные аргументы, начиная с исходного индекса.