Передать больше параметров чем есть

Если в функцию передать больше параметров чем она принимает то выдаст варнинг. Но его можно подавить собакой @. Вот только тогда она возвращает 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);
}
→ Ссылка