diff --git a/EventHandler.php b/EventHandler.php index 9b786e1..0111d82 100755 --- a/EventHandler.php +++ b/EventHandler.php @@ -51,18 +51,18 @@ public function addHandler(object|string $handler, string|array $method = null): public function addEvent(callable|object|string $event, ?string $bind = null): void { - if(!is_callable($event)) { - if(is_string($event)) { + if (!is_callable($event)) { + if (is_string($event)) { $reflect = new Reflection($event); $event = $reflect->get(); } - if(is_object($event) && !($event instanceof EventInterface)) { + if (is_object($event) && !($event instanceof EventInterface)) { throw new Exception("Event object/class needs to be instance of \"EventInterface\"!", 1); } } - if (is_null($bind)) { + if ($bind === null) { $this->event[] = $event; } else { $this->event[] = [$bind => $event]; @@ -95,7 +95,7 @@ public function __call(string $method, array $args): mixed throw new BadMethodCallException("The method \"".$method."\" does not exist in the class (" . $handler[0]::class . ")", 1); } */ - if (is_null($handler[1][0]) || in_array($method, $handler[1])) { + if ($handler[1][0] === null || in_array($method, $handler[1])) { $this->bindable[$method] = $method; } $data = call_user_func_array([$handler[0], $method], $args); @@ -136,7 +136,7 @@ final protected function triggerEvents(): void */ final protected function getEvent(callable|object $data): void { - if(is_callable($data)) { + if (is_callable($data)) { $data(); } else { $data->resolve(); diff --git a/Reflection.php b/Reflection.php index 7c66ac3..63a2d84 100755 --- a/Reflection.php +++ b/Reflection.php @@ -9,6 +9,9 @@ use ReflectionException; use ReflectionMethod; use MaplePHP\Container\Exceptions\NotFoundException; +use ReflectionNamedType; +use ReflectionParameter; +use ReflectionUnionType; class Reflection { @@ -74,19 +77,23 @@ public function dependencyInjector(?object $class = null, ?string $method = null { $args = []; $constructor = $this->setDependMethod($method, $this->reflect); - if(!is_null($constructor)) { + if ($constructor !== null) { $params = $constructor->getParameters(); $this->injectRecursion($params, $this->reflect->getName()); foreach ($params as $param) { - if ($param->getType() && !$param->getType()->isBuiltin()) { - $classKey = $param->getType()->getName(); + if (!$this->isBuiltin($param)) { + $classKey = $this->getClassNameFromParam($param); + if (!$classKey) { + continue; + } + if (isset(self::$class[$classKey])) { $args[] = self::$class[$classKey]; } } } } - if(!is_null($this->dependMethod)) { + if ($this->dependMethod !== null) { $this->dependMethod = null; return $constructor->invokeArgs($class, $args); } @@ -104,12 +111,24 @@ public function setDependMethod(?string $method, ReflectionClass $inst): ?Reflec { $method = ($method === "constructor") ? null : $method; $this->dependMethod = $method; - if(is_null($this->dependMethod)) { + if ($this->dependMethod === null) { return $inst->getConstructor(); } return $inst->getMethod($this->dependMethod); } + /** + * Check if a parameter type is built-in + * + * @param ReflectionParameter $param Parameter to check + * @return bool Returns true if a parameter type is not built-in, false otherwise + */ + private function isBuiltin(ReflectionParameter $param): bool + { + $type = $param->getType(); + return ($type instanceof ReflectionNamedType && $type->isBuiltin()); + } + /** * This will return reflection if class exist or error pointing to file where error existed, * @param class-string $className @@ -142,8 +161,11 @@ private function injectRecursion(array $params, string $fromClass, array $_args { $_args = []; foreach ($params as $param) { - if ($param->getType() && !$param->getType()->isBuiltin()) { - $classNameA = $param->getType()->getName(); + if (!$this->isBuiltin($param)) { + $classNameA = $this->getClassNameFromParam($param); + if (!$classNameA) { + continue; // skip if class name couldn't be resolved + } $inst = $this->initReclusiveReflect($classNameA, $fromClass); $reflectParam = []; $constructor = $inst->getConstructor(); @@ -172,6 +194,42 @@ private function injectRecursion(array $params, string $fromClass, array $_args return $_args; } + /** + * Extracts the class name from a ReflectionParameter object + * Handles named types, union types, and intersection types (PHP 8.1+) + * Returns the first non-built-in type name found or null if none exists + * + * @param ReflectionParameter $param The reflection parameter to analyze + * @return string|null The extracted class name or null if no class name is found + */ + private function getClassNameFromParam(ReflectionParameter $param): ?string + { + $type = $param->getType(); + + if ($type instanceof ReflectionNamedType && !$type->isBuiltin()) { + return $type->getName(); + } + + if ($type instanceof ReflectionUnionType) { + foreach ($type->getTypes() as $innerType) { + if ($innerType instanceof ReflectionNamedType && !$innerType->isBuiltin()) { + return $innerType->getName(); + } + } + } + + // Optionally handle ReflectionIntersectionType for PHP 8.1+ + if (PHP_VERSION_ID >= 80100 && $type instanceof ReflectionIntersectionType) { + foreach ($type->getTypes() as $innerType) { + if ($innerType instanceof ReflectionNamedType && !$innerType->isBuiltin()) { + return $innerType->getName(); // or return all names if needed + } + } + } + return null; + } + + /** * Will insert interface classes (the default classes) * @param ReflectionClass $inst @@ -181,7 +239,7 @@ private function injectRecursion(array $params, string $fromClass, array $_args private function insertInterfaceClasses(ReflectionClass $inst, string $classNameA): void { if ($this->allowInterfaces) { - if (!is_null(self::$interfaceFactory)) { + if (self::$interfaceFactory !== null) { foreach (self::$interfaceFactory as $call) { self::$class[$classNameA] = $call($inst->getShortName(), $classNameA, $inst); } @@ -208,7 +266,7 @@ private function insertMultipleNestedClasses( ): array { $args = []; foreach ($reflectParam as $reflectInstance) { - if ($reflectInstance->getType() && !$reflectInstance->getType()->isBuiltin()) { + if (!$this->isBuiltin($reflectInstance)) { $classNameB = $reflectInstance->getType()->getName(); if (isset(self::$class[$classNameB])) { $args[] = self::$class[$classNameB]; @@ -265,7 +323,7 @@ public function getReflect(): ReflectionClass */ public function get(): mixed { - if (!is_null($this->method)) { + if ($this->method !== null) { $method = $this->reflect->getMethod($this->method); if ($method->isConstructor()) { return $this->getClass(); @@ -275,7 +333,7 @@ public function get(): mixed } $inst = $this->reflect->newInstanceWithoutConstructor(); - if (!is_null($this->args)) { + if ($this->args !== null) { return $method->invokeArgs($inst, $this->args); } else { return $method->invoke($inst); @@ -296,7 +354,7 @@ public static function getClassList(): array */ private function getClass(): object { - if (!is_null($this->args)) { + if ($this->args !== null) { $inst = $this->reflect->newInstanceArgs($this->args); } else { $inst = $this->dependencyInjector();