diff --git a/src/Illuminate/Auth/Access/Gate.php b/src/Illuminate/Auth/Access/Gate.php index 3e3b17b806b1..9cc701561ea4 100644 --- a/src/Illuminate/Auth/Access/Gate.php +++ b/src/Illuminate/Auth/Access/Gate.php @@ -450,7 +450,7 @@ protected function callbackAllowsGuests($callback) */ protected function parameterAllowsGuests($parameter) { - return ($parameter->getClass() && $parameter->allowsNull()) || + return ($parameter->hasType() && $parameter->allowsNull()) || ($parameter->isDefaultValueAvailable() && is_null($parameter->getDefaultValue())); } diff --git a/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php index 99950baea92f..f626187b069b 100644 --- a/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php +++ b/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php @@ -8,6 +8,7 @@ use Illuminate\Contracts\Routing\BindingRegistrar; use Illuminate\Contracts\Routing\UrlRoutable; use Illuminate\Support\Arr; +use Illuminate\Support\Reflector; use Illuminate\Support\Str; use ReflectionClass; use ReflectionFunction; @@ -204,9 +205,9 @@ protected function resolveImplicitBindingIfPossible($key, $value, $callbackParam continue; } - $instance = $parameter->getClass()->newInstance(); + $className = Reflector::getParameterClassName($parameter); - if (! $model = $instance->resolveRouteBinding($value)) { + if (is_null($model = (new $className)->resolveRouteBinding($value))) { throw new AccessDeniedHttpException; } @@ -225,8 +226,8 @@ protected function resolveImplicitBindingIfPossible($key, $value, $callbackParam */ protected function isImplicitlyBindable($key, $parameter) { - return $parameter->name === $key && $parameter->getClass() && - $parameter->getClass()->isSubclassOf(UrlRoutable::class); + return $parameter->getName() === $key && + Reflector::isParameterSubclassOf($parameter, UrlRoutable::class); } /** diff --git a/src/Illuminate/Container/BoundMethod.php b/src/Illuminate/Container/BoundMethod.php index 8501232621e7..f350d580e760 100644 --- a/src/Illuminate/Container/BoundMethod.php +++ b/src/Illuminate/Container/BoundMethod.php @@ -157,16 +157,20 @@ protected static function getCallReflector($callback) protected static function addDependencyForCallParameter($container, $parameter, array &$parameters, &$dependencies) { - if (array_key_exists($parameter->name, $parameters)) { - $dependencies[] = $parameters[$parameter->name]; + if (array_key_exists($parameter->getName(), $parameters)) { + $paramName = $parameter->getName(); - unset($parameters[$parameter->name]); - } elseif ($parameter->getClass() && array_key_exists($parameter->getClass()->name, $parameters)) { - $dependencies[] = $parameters[$parameter->getClass()->name]; + $dependencies[] = $parameters[$paramName]; - unset($parameters[$parameter->getClass()->name]); - } elseif ($parameter->getClass()) { - $dependencies[] = $container->make($parameter->getClass()->name); + unset($parameters[$paramName]); + } elseif (! is_null($className = Util::getParameterClassName($parameter))) { + if (array_key_exists($className, $parameters)) { + $dependencies[] = $parameters[$className]; + + unset($parameters[$className]); + } else { + $dependencies[] = $container->make($className); + } } elseif ($parameter->isDefaultValueAvailable()) { $dependencies[] = $parameter->getDefaultValue(); } diff --git a/src/Illuminate/Container/Container.php b/src/Illuminate/Container/Container.php index efcad236a264..c0e2082b360c 100755 --- a/src/Illuminate/Container/Container.php +++ b/src/Illuminate/Container/Container.php @@ -846,7 +846,7 @@ public function build($concrete) /** * Resolve all of the dependencies from the ReflectionParameters. * - * @param array $dependencies + * @param \ReflectionParameter[] $dependencies * @return array * * @throws \Illuminate\Contracts\Container\BindingResolutionException @@ -868,7 +868,7 @@ protected function resolveDependencies(array $dependencies) // If the class is null, it means the dependency is a string or some other // primitive type which we can not resolve since it is not a class and // we will just bomb out with an error since we have no-where to go. - $results[] = is_null($dependency->getClass()) + $results[] = is_null(Util::getParameterClassName($dependency)) ? $this->resolvePrimitive($dependency) : $this->resolveClass($dependency); } @@ -920,7 +920,7 @@ protected function getLastParameterOverride() */ protected function resolvePrimitive(ReflectionParameter $parameter) { - if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->name))) { + if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->getName()))) { return $concrete instanceof Closure ? $concrete($this) : $concrete; } @@ -942,7 +942,7 @@ protected function resolvePrimitive(ReflectionParameter $parameter) protected function resolveClass(ReflectionParameter $parameter) { try { - return $this->make($parameter->getClass()->name); + return $this->make(Util::getParameterClassName($parameter)); } // If we can not resolve the class instance, we will check to see if the value diff --git a/src/Illuminate/Container/Util.php b/src/Illuminate/Container/Util.php index 5feca5510d06..86dac5b9b39c 100644 --- a/src/Illuminate/Container/Util.php +++ b/src/Illuminate/Container/Util.php @@ -35,4 +35,19 @@ public static function unwrapIfClosure($value) { return $value instanceof Closure ? $value() : $value; } + + /** + * Get the class name of the given parameter's type, if possible. + * + * From Reflector::getParameterClassName() in Illuminate\Support. + * + * @param \ReflectionParameter $parameter + * @return string|null + */ + public static function getParameterClassName($parameter) + { + $type = $parameter->getType(); + + return ($type && ! $type->isBuiltin()) ? $type->getName() : null; + } } diff --git a/src/Illuminate/Foundation/Console/ClosureCommand.php b/src/Illuminate/Foundation/Console/ClosureCommand.php index eb6ddc0eaaca..c0d736bdb3da 100644 --- a/src/Illuminate/Foundation/Console/ClosureCommand.php +++ b/src/Illuminate/Foundation/Console/ClosureCommand.php @@ -46,8 +46,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $parameters = []; foreach ((new ReflectionFunction($this->callback))->getParameters() as $parameter) { - if (isset($inputs[$parameter->name])) { - $parameters[$parameter->name] = $inputs[$parameter->name]; + if (isset($inputs[$parameter->getName()])) { + $parameters[$parameter->getName()] = $inputs[$parameter->getName()]; } } diff --git a/src/Illuminate/Foundation/Events/DiscoverEvents.php b/src/Illuminate/Foundation/Events/DiscoverEvents.php index 8d89e52805ac..0fa87135c9ff 100644 --- a/src/Illuminate/Foundation/Events/DiscoverEvents.php +++ b/src/Illuminate/Foundation/Events/DiscoverEvents.php @@ -2,6 +2,7 @@ namespace Illuminate\Foundation\Events; +use Illuminate\Support\Reflector; use Illuminate\Support\Str; use ReflectionClass; use ReflectionException; @@ -58,7 +59,7 @@ protected static function getListenerEvents($listeners, $basePath) } $listenerEvents[$listener->name.'@'.$method->name] = - optional($method->getParameters()[0]->getClass())->name; + Reflector::getParameterClassName($method->getParameters()[0]); } } diff --git a/src/Illuminate/Routing/ImplicitRouteBinding.php b/src/Illuminate/Routing/ImplicitRouteBinding.php index b3b6ca088730..e30372dab807 100644 --- a/src/Illuminate/Routing/ImplicitRouteBinding.php +++ b/src/Illuminate/Routing/ImplicitRouteBinding.php @@ -4,6 +4,7 @@ use Illuminate\Contracts\Routing\UrlRoutable; use Illuminate\Database\Eloquent\ModelNotFoundException; +use Illuminate\Support\Reflector; use Illuminate\Support\Str; class ImplicitRouteBinding @@ -22,7 +23,7 @@ public static function resolveForRoute($container, $route) $parameters = $route->parameters(); foreach ($route->signatureParameters(UrlRoutable::class) as $parameter) { - if (! $parameterName = static::getParameterName($parameter->name, $parameters)) { + if (! $parameterName = static::getParameterName($parameter->getName(), $parameters)) { continue; } @@ -32,7 +33,7 @@ public static function resolveForRoute($container, $route) continue; } - $instance = $container->make($parameter->getClass()->name); + $instance = $container->make(Reflector::getParameterClassName($parameter)); if (! $model = $instance->resolveRouteBinding($parameterValue)) { throw (new ModelNotFoundException)->setModel(get_class($instance), [$parameterValue]); diff --git a/src/Illuminate/Routing/RouteDependencyResolverTrait.php b/src/Illuminate/Routing/RouteDependencyResolverTrait.php index 17213d4a6f7e..b3e887b169cb 100644 --- a/src/Illuminate/Routing/RouteDependencyResolverTrait.php +++ b/src/Illuminate/Routing/RouteDependencyResolverTrait.php @@ -3,6 +3,7 @@ namespace Illuminate\Routing; use Illuminate\Support\Arr; +use Illuminate\Support\Reflector; use ReflectionFunctionAbstract; use ReflectionMethod; use ReflectionParameter; @@ -68,15 +69,15 @@ public function resolveMethodDependencies(array $parameters, ReflectionFunctionA */ protected function transformDependency(ReflectionParameter $parameter, $parameters) { - $class = $parameter->getClass(); + $className = Reflector::getParameterClassName($parameter); // If the parameter has a type-hinted class, we will check to see if it is already in // the list of parameters. If it is we will just skip it as it is probably a model // binding and we do not want to mess with those; otherwise, we resolve it here. - if ($class && ! $this->alreadyInParameters($class->name, $parameters)) { + if ($className && ! $this->alreadyInParameters($className, $parameters)) { return $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() - : $this->container->make($class->name); + : $this->container->make($className); } } diff --git a/src/Illuminate/Routing/RouteSignatureParameters.php b/src/Illuminate/Routing/RouteSignatureParameters.php index fe5b170f5e3b..535d5edcbf32 100644 --- a/src/Illuminate/Routing/RouteSignatureParameters.php +++ b/src/Illuminate/Routing/RouteSignatureParameters.php @@ -2,6 +2,7 @@ namespace Illuminate\Routing; +use Illuminate\Support\Reflector; use Illuminate\Support\Str; use ReflectionFunction; use ReflectionMethod; @@ -22,7 +23,7 @@ public static function fromAction(array $action, $subClass = null) : (new ReflectionFunction($action['uses']))->getParameters(); return is_null($subClass) ? $parameters : array_filter($parameters, function ($p) use ($subClass) { - return $p->getClass() && $p->getClass()->isSubclassOf($subClass); + return Reflector::isParameterSubclassOf($p, $subClass); }); } diff --git a/src/Illuminate/Support/Reflector.php b/src/Illuminate/Support/Reflector.php new file mode 100644 index 000000000000..a38fed71bed8 --- /dev/null +++ b/src/Illuminate/Support/Reflector.php @@ -0,0 +1,37 @@ +getType(); + + return ($type && ! $type->isBuiltin()) ? $type->getName() : null; + } + + /** + * Determine if the parameter's type is a subclass of the given type. + * + * @param \ReflectionParameter $parameter + * @param string $className + * @return bool + */ + public static function isParameterSubclassOf($parameter, $className) + { + $paramClassName = static::getParameterClassName($parameter); + + return ($paramClassName && class_exists($paramClassName)) + ? (new ReflectionClass($paramClassName))->isSubclassOf($className) + : false; + } +}