$value) { self::$config[$name] = $value; } } unset($a); } } final class registry { private static $registry = []; protected function __construct() { } public static function get(string $name, $key = false) { if (isset(self::$registry[strtolower($name)])) { $a = self::$registry[strtolower($name)]; if ($key === false) { return $a; } if (isset($a[$key])) { return $a[$key]; } } return null; } public static function set(string $name, $value): bool { if (array_key_exists(strtolower($name), self::$registry)) { return false; } self::$registry[strtolower($name)] = $value; return true; } } final class di { protected $services = []; public function register(string $service_name, callable $callable): void { $this->services[$service_name] = $callable; } public function has(string $service_name): bool { return (array_key_exists($service_name, $this->services)); } public function exists(string $service_name) { // an Alias to has return $this->has($service_name); } /* Note args may be an object or an array maybe more...! * This will Call/Execute the service */ public function get_service( string $service_name, $args = [], ...$more ) { if ($this->has($service_name) ) { return $this->services[$service_name]($args, $more); } return $this->resolve($service_name); // Try to Auto-Wire } public function get_auto(string $service_name) { if ($this->has($service_name) ) { return $this->services[$service_name]($this); } return $this->resolve($service_name); // Try to Auto-Wire } public function __set(string $service_name, callable $callable): void { $this->register($service_name, $callable); } public function __get(string $service_name) { return $this->get_service($service_name); } public function list_services_as_array(): array { return array_keys($this->services); } public function list_services_as_string(): string { return implode(',', array_keys($this->services)); } public function resolve(string $service_name) { try { $reflection_class = new \ReflectionClass($service_name); } catch (\ReflectionException $e) { if (! is_live()) { var_dump($e->getTrace()); echo $e->getMessage(); exit; } else { throw new \Exception("Failed to resolve resource: {$service_name}!"); } } if (! $reflection_class->isInstantiable()) { throw new \Exception("The Service class: {$service_name} is not instantiable."); } $constructor = $reflection_class->getConstructor(); if (! $constructor) { return new $service_name; } $parameters = $constructor->getParameters(); if (! $parameters) { return new $service_name; } $dependencies = array_map( function(\ReflectionParameter $param) { $name = $param->getName(); $type = $param->getType(); if (! $type) { throw new \Exception("Failed to resolve class: {$service_name} becasue param {$name} is missing a type hint."); } if ($type instanceof \ReflectionUnionType) { throw new \Exception("Failed to resolve class: {$service_name} because of union type for param {$name}."); } if ($type instanceof \ReflectionNamedType && ! $type->isBuiltin()) { return $this->get_auto($type->getName()); } throw new \Exception("Failed to resolve class {$service_name} because of invalid param {$param}."); }, $parameters ); return $reflection_class->newInstanceArgs($dependencies); } } // Initialize our Dependency Injector registry::set('di', new di()); // Setup php for working with Unicode data, if possible if (extension_loaded('mbstring')) { mb_internal_encoding('UTF-8'); mb_http_output('UTF-8'); mb_language('uni'); mb_regex_encoding('UTF-8'); setlocale(LC_ALL, "en_US.UTF-8"); } require_once CodeHydrater_FRAMEWORK . 'bootstrap/common.php'; require_once CodeHydrater_FRAMEWORK . 'bootstrap/requires.php'; require_once CodeHydrater_FRAMEWORK . 'bootstrap/auto_loader.php'; registry::set('loader', new Psr4AutoloaderClass); registry::get('loader')->register(); registry::get('loader')->add_namespace("CodeHydrater\bootstrap", CodeHydrater_FRAMEWORK . "bootstrap"); registry::get('loader')->add_namespace("CodeHydrater", CodeHydrater_FRAMEWORK . "classes"); registry::get('loader')->add_namespace("Project", CodeHydrater_PROJECT); load_all::init(CodeHydrater_PROJECT); // Keep these blocks of code here not anywhere before it... if (! defined('ENVIRONMENT')) { if (is_live() === false) { define('ENVIRONMENT', 'development'); } else { define('ENVIRONMENT', 'production'); } } function is_live(): bool { if (configure::has('CodeHydrater', 'live')) { $live = configure::get('CodeHydrater', 'live'); } if ($live === null) { $live = errors::get_live_mode(); } return (bool) $live; } $returned_route = \CodeHydrater\router::execute(); if ($returned_route["found"] === false) { $app = new \CodeHydrater\app(); $app->load_controller(); }