protected function getParamsClosure(\ReflectionMethod $constructor, array $class_rule): callable
    {
        $param_details = []; // Initialize parameter details.

        foreach ($constructor->getParameters() as $_parameter) {
            $_name = $_parameter->getName();

            $_class      = $_parameter->getClass();
            $_class_name = $_class->name ?? '';

            $_is_variadic       = $_parameter->isVariadic();
            $_has_default_value = $_parameter->isDefaultValueAvailable();
            $_default_value     = $_has_default_value ? $_parameter->getDefaultValue() : null;

            $param_details[] = [$_name, $_class_name, $_is_variadic, $_has_default_value, $_default_value];
        } // unset($_parameter, $_name, $_class, $_class_name, $_is_variadic, $_has_default_value, $_default_value);

        return function (array $args) use ($constructor, $param_details, $class_rule) {
            $parameters = []; // Initialize parameters.

            if ($class_rule['constructor_args']) { // Note: `$args` take precedence here.
                $args = array_merge($this->resolveJitClosures($class_rule['constructor_args']), $args);
            }
            foreach ($param_details as list($_name, $_class_name, $_is_variadic, $_has_default_value, $_default_value)) {
                if ($args && array_key_exists($_name, $args)) {
                    if ($_is_variadic && is_array($args[$_name])) {
                        $parameters = array_merge($parameters, $args[$_name]);
                    } else {
                        $parameters[] = $args[$_name];
                    }
                } elseif ($_class_name && !$_has_default_value) {
                    $parameters[] = $this->get($_class_name);
                } elseif ($_has_default_value) {
                    $parameters[] = $_default_value;
                } else {
                    throw new \Exception(sprintf('Missing `$%1$s` to `%2$s` constructor.', $_name, $constructor->class));
                }
            } // unset($_name, $_class_name, $_is_variadic, $_has_default_value, $_default_value);

            return $parameters; // With deep dependency injection.
        };
    }
protected function getParamsClosure(\ReflectionMethod $constructor, array $class_rule): callable
    {
        $param_details = []; // Initialize parameter details.

        foreach ($constructor->getParameters() as $_parameter) {
            $_name = $_parameter->getName();

            $_class      = $_parameter->getClass();
            $_class_name = $_class->name ?? '';

            $_is_variadic       = $_parameter->isVariadic();
            $_has_default_value = $_parameter->isDefaultValueAvailable();
            $_default_value     = $_has_default_value ? $_parameter->getDefaultValue() : null;

            $param_details[] = [$_name, $_class_name, $_is_variadic, $_has_default_value, $_default_value];
        } // unset($_parameter, $_name, $_class, $_class_name, $_is_variadic, $_has_default_value, $_default_value);

        return function (array $args) use ($constructor, $param_details, $class_rule) {
            $parameters = []; // Initialize parameters.

            if ($class_rule['constructor_args']) { // Note: `$args` take precedence here.
                $args = array_merge($this->resolveJitClosures($class_rule['constructor_args']), $args);
            }
            foreach ($param_details as list($_name, $_class_name, $_is_variadic, $_has_default_value, $_default_value)) {
                if ($args && array_key_exists($_name, $args)) {
                    if ($_is_variadic && is_array($args[$_name])) {
                        $parameters = array_merge($parameters, $args[$_name]);
                    } else {
                        $parameters[] = $args[$_name];
                    }
                } elseif ($_class_name && !$_has_default_value) {
                    $parameters[] = $this->get($_class_name);
                } elseif ($_has_default_value) {
                    $parameters[] = $_default_value;
                } else {
                    throw new \Exception(sprintf('Missing `$%1$s` to `%2$s` constructor.', $_name, $constructor->class));
                }
            } // unset($_name, $_class_name, $_is_variadic, $_has_default_value, $_default_value);

            return $parameters; // With deep dependency injection.
        };
    }
protected function getParamsClosure ( \ ReflectionMethod $ constructor , array $ class_rule ) : callable { $ param_details = [ ] ; // Initialize parameter details. foreach ( $ constructor -> getParameters ( ) as $ _parameter ) { $ _name = $ _parameter -> getName ( ) ; $ _class = $ _parameter -> getClass ( ) ; $ _class_name = $ _class -> name ?? '' ; $ _is_variadic = $ _parameter -> isVariadic ( ) ; $ _has_default_value = $ _parameter -> isDefaultValueAvailable ( ) ; $ _default_value = $ _has_default_value ? $ _parameter -> getDefaultValue ( ) : null ; $ param_details [ ] = [ $ _name , $ _class_name , $ _is_variadic , $ _has_default_value , $ _default_value ] ; } // unset($_parameter, $_name, $_class, $_class_name, $_is_variadic, $_has_default_value, $_default_value); return function ( array $ args ) use ( $ constructor , $ param_details , $ class_rule ) { $ parameters = [ ] ; // Initialize parameters. if ( $ class_rule [ 'constructor_args' ] ) { // Note: `$args` take precedence here. $ args = array_merge ( $ this -> resolveJitClosures ( $ class_rule [ 'constructor_args' ] ) , $ args ) ; } foreach ( $ param_details as list ( $ _name , $ _class_name , $ _is_variadic , $ _has_default_value , $ _default_value ) ) { if ( $ args && array_key_exists ( $ _name , $ args ) ) { if ( $ _is_variadic && is_array ( $ args [ $ _name ] ) ) { $ parameters = array_merge ( $ parameters , $ args [ $ _name ] ) ; } else { $ parameters [ ] = $ args [ $ _name ] ; } } elseif ( $ _class_name && ! $ _has_default_value ) { $ parameters [ ] = $ this -> get ( $ _class_name ) ; } elseif ( $ _has_default_value ) { $ parameters [ ] = $ _default_value ; } else { throw new \ Exception ( sprintf ( 'Missing `$%1$s` to `%2$s` constructor.' , $ _name , $ constructor -> class ) ) ; } } // unset($_name, $_class_name, $_is_variadic, $_has_default_value, $_default_value); return $ parameters ; // With deep dependency injection. } ; }
Magic happens here.

@since 151115 Initial release.

@param \ReflectionMethod $constructor Constructor.
@param array             $class_rule  A class-specific rule.

@return callable Closure that returns an array of parameters.
Magic happens here .