Skip to content

Improve code quality and ensure compatibility with PHP 8.1+ #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down
82 changes: 70 additions & 12 deletions Reflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use ReflectionException;
use ReflectionMethod;
use MaplePHP\Container\Exceptions\NotFoundException;
use ReflectionNamedType;
use ReflectionParameter;
use ReflectionUnionType;

class Reflection
{
Expand Down Expand Up @@ -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);
}
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
Expand All @@ -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];
Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -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();
Expand Down