Передать больше параметров чем есть
Если в функцию передать больше параметров чем она принимает то выдаст варнинг. Но его можно подавить собакой @. Вот только тогда она возвращает null без вариантов... А мне надо чтобы вернуло ее результат, взяв нужное количество параметров. Единственное что приходит в голову это через рефлексию посмотреть сколько у нее параметров и урезав массив вызвать потом через call_user_func_array, но может можно как-то попроще?
Ответы (2 шт):
Вот этот вариант вам подойдет? Списки аргументов переменной длины
Специально для злопыхателей объясняю что я хотел сделать и как я в итоге решил проблему указанную в вопросе:
function iterable_filter($data, $callback = null) {
$index = 0;
if (!is_callable($callback))
$callback = 'boolval';
foreach ($data as $key => $value) {
if (callable_invoke($callback, [$value, $key, $index++]))
yield $key => $value;
}
}
Люблю я заниматься велосипедописательством иногда. Это моя реализация - аналог функции array_filter, но работающий со всем что можно перебирать, а не только с массивами. Как бонус - возвращает генератор.
И тут я не мог просто вызывать $callback с тремя аргументами - кидало ошибку (потому что я не хотел передавать туда калбэк с тремя аргументами). То есть я хотел добиться вариативности и по желанию передавать калбэк с одним, двумя или тремя аргументами (вместо того чтобы извращаться со флагами как в оригинальной array_filter, плюс я еще добавил туда индекс третьим аргументом - тоже может быть полезно).
В итоге мне пришлось все-таки залезть через рефлексию:
function callable_reflection($callback) {
if (is_string($callback)) {
$parts = explode('::', $callback);
if (count($parts) > 1)
$callback = [$parts[0], $parts[1]];
}
if (is_array($callback) && count($callback) > 1) {
list($classOrObject, $method) = $callback;
return new ReflectionMethod($classOrObject, $method);
} elseif (is_string($callback) && is_callable($callback)) {
return new ReflectionFunction($callback);
}
throw new \TypeError('Callback is not callable');
}
function callable_params_count($callback, $requiredOnly = false) {
$reflection = callable_reflection($callback);
return $requiredOnly ? $reflection->getNumberOfRequiredParameters() : $reflection->getNumberOfParameters();
}
function callable_invoke($callback, $args) {
$callbackParamsCount = callable_params_count($callback);
$argsCount = count($args);
if ($argsCount > $callbackParamsCount)
$args = array_slice($args, 0, $callbackParamsCount, true);
elseif ($argsCount < $callbackParamsCount)
throw new LengthException('Too few args');
return call_user_func_array($callback, $args);
}