Я только что узнал, что в PHP есть функция func_get_arg
которая позволяет разработчику использовать вариантный func_get_arg
получения аргументов. Это кажется очень полезным, потому что теперь количество аргументов может быть произвольным, но я не могу придумать хороший пример его использования.
Каковы некоторые примеры использования этой функции для полного использования ее полиморфной характеристики?
Обычно я использую func_get_args()
который проще использовать, если требуется несколько аргументов.
Например, чтобы воссоздать PHP max()
.
function max() { $max = -PHP_INT_MAX; foreach(func_get_args() as $arg) { if ($arg > $max) { $max = $arg; } } return $max; }
CodePad .
Теперь вы можете сделать echo max(1,5,7,3)
и получить 7
.
Прежде всего, вы используете термин «полиморфизм» совершенно неправильно. Полиморфизм – это понятие в объектно-ориентированном программировании, и оно не имеет ничего общего с переменным числом аргументов в функциях.
По моему опыту, все func_get_args
позволяют вам добавить немного синтаксического сахара.
Подумайте о функции, которая может принимать любое число целых чисел и возвращать их сумму. (Я обманываю, поскольку это уже существует в array_sum
. Но обман хорош, если он просто array_sum
пример). Вы можете сделать это так:
// you can leave "array" out; I have it because we should be getting one here function sum1(array $integers) { return array_sum($integers); }
Теперь вы бы назвали это так:
$sum = sum1(array(1)); $sum = sum1(array(1, 2, 3, 4));
Это не очень красиво. Но мы можем сделать лучше:
function sum2() { $integers = func_get_args(); return array_sum($integers); }
Теперь вы можете назвать это следующим образом:
$sum = sum2(1); $sum = sum2(1, 2, 3, 4);
Допустим, у нас есть несколько массивов, содержащих данные, в которых нам нужно искать ключи по их значениям без слияния этих массивов.
Массивы подобны:
$a = array('a' => 5, 'b' => 6); $b = array('a' => 2, 'b' => 8); $c = array('a' => 7, 'b' => 3);
В этом случае, скажем, нам нужно получить все значения ключа a
из всех массивов. Мы можем написать функцию, которая принимает произвольное количество массивов для поиска.
// we need the key, and at least 1 array to search in function simpleSearchArrays($key, $a1){ $arrays = func_get_args(); array_shift($arrays); // remove the first argument, which is the key $ret = array(); foreach($arrays as $a){ if(array_key_exists($key, $a)){ $ret[] = $a[$key]; } } return $ret; }
Поэтому, если мы используем функцию:
$x = simpleSearchArrays('a', $a, $b, $c);
Затем $x
будет содержать array(5, 2, 7)
.
Лично я не думаю, что для нормальной работы есть хороший прецедент. Как контролер, мне нравится точно знать, что передается моим функциям, и мне нравится точно знать, что я передаю.
Однако его можно использовать для таких вещей, как динамическая / статическая URL-маршрутизация. Когда вы переписываете (через mod_rewrite), URL-адрес указывает на одну загрузку.
В этом смысле у вас могут быть аргументы, которые необязательно должны существовать при каждом запросе страницы.
Я почти никогда не использовал func_get_arg()
, но я довольно func_get_args()
использую его кузена func_get_args()
. Вот один пример: функция по строкам выражения echo
который сущность кодирует все свои аргументы:
function ee() { $args = func_get_args(); echo implode('', array_map('htmlentities', $args)); }
Я использую эту функцию совсем немного.
Вот еще один полезный пример – функция, выполняющая ту же работу, что и функция COALESCE()
SQL.
function coalesce() { $args = func_get_args(); foreach ($args as $arg) { if (!is_null($arg)) { return $arg; } } return null; }
Он возвращает первый непустой аргумент, переданный в, или null
если нет такого аргумента.
Начиная с php5.6, больше не существует func_get_arg
; что не означает, что его функциональность больше не нужна, но заменяется вариационной функцией с использованием синтаксиса:
/** * @param array $arguments */ public function poit(...$arguments) { foreach($arguments as $argument) { ... } }
Это особенно полезно, если в конце есть методы, которые перегружены; нужно сначала отфильтровать первые аргументы, как показано на примере :
Старый стиль с помощью func_get_arg
:
function foo($a, $b) { $c = array(); if (func_num_args() > 2) { for($i = 0; $i < func_num_args()-2; $i++) { $c[] = func_get_arg($i+2); } } var_dump($a, $b, $c) // Do something } foo('a', 'b', 'c', 'd');
Новый вариационный стиль;
function foo($a, $b, …$c) { var_dump($a, $b, $c); // Do something } foo('a', 'b', 'c', 'd');
Оба foo производят один и тот же вывод, один намного проще писать.
Прочтите официальный документ и func_get_args()
что func_get_args()
:
Получает массив списка аргументов функции.
Эта функция может использоваться вместе с func_get_arg()
и func_num_args()
чтобы позволить пользовательским функциям принимать списки аргументов переменной длины.
<?php function foo() { $numargs = func_num_args(); echo "Number of arguments: $numargs \n"; if ($numargs >= 2) { echo "Second argument is: " . func_get_arg(1) . "\n"; } $arg_list = func_get_args(); for ($i = 0; $i < $numargs; $i++) { echo "Argument $i is: " . $arg_list[$i] . "\n"; } } foo(1, 2, 3); ?>