container = new DefaultContainer(); $this->bootstrapper = new ContainerBootstrapper($this->container); // Initialize environment with encryption support $env = $this->initializeEnvironment(); // Make Environment available throughout the application $this->container->instance(Environment::class, $env); $typedConfig = new TypedConfigInitializer($env)($this->container); $this->container->instance(TypedConfiguration::class, $typedConfig); // ExecutionContext detection sollte das erste sein, das nach dem Instanziieren des containers passiert. noch bevor dem bootstrap des containers. $executionContext = ExecutionContext::detect($typedConfig->app); $this->container->instance(ExecutionContext::class, $executionContext); // Register MemoryMonitor as singleton $this->container->singleton(MemoryMonitor::class, $this->memoryMonitor); // Only log context in development - production doesn't need this noise //$envType = EnvironmentType::fromEnvironment($env); //if ($envType->isDevelopment()) { if($typedConfig->app->type->isDevelopment()) { // Fehleranzeige für die Entwicklung aktivieren ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); spl_autoload_register(function ($class) { if (empty($class)) { error_log('Empty class name detected in autoloader. Stack trace: ' . json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10))); return false; // Don't throw, just log and continue } return false; }, true, true); } } public function bootstrapWeb(): ApplicationInterface { $this->bootstrap(); $this->registerWebErrorHandler(); $this->registerApplication(); $mm = $this->container->get(MiddlewareManager::class); $this->container->instance(MiddlewareManagerInterface::class, $mm); $ed = $this->container->get(EventDispatcher::class); $this->container->instance(EventDispatcherInterface::class, $ed); return $this->container->get(ApplicationInterface::class); } public function bootstrapConsole(): ConsoleApplication { $this->bootstrap(); $this->registerCliErrorHandler(); $this->registerConsoleApplication(); return $this->container->get(ConsoleApplication::class); } public function bootstrapWorker(): Container { $this->bootstrap(); $this->registerCliErrorHandler(); $ed = $this->container->get(EventDispatcher::class); $this->container->instance(EventDispatcherInterface::class, $ed); $consoleOutput = new ConsoleOutput(); $this->container->instance(ConsoleOutput::class, $consoleOutput); return $this->container; } public function bootstrapWebSocket(): Container { $this->bootstrap(); $this->registerCliErrorHandler(); $consoleOutput = new ConsoleOutput(); $this->container->instance(ConsoleOutput::class, $consoleOutput); return $this->container; } private function bootstrap(): void { $this->collector->startTiming('bootstrap', PerformanceCategory::SYSTEM); $this->bootstrapper->bootstrap($this->basePath, $this->collector); $this->collector->endTiming('bootstrap'); // Initialize secrets management after container is bootstrapped $env = $this->container->get(Environment::class); $this->initializeSecretsManagement($env); // ErrorHandler wird jetzt kontextabhängig registriert // $this->container->get(ErrorHandler::class)->register(); } private function registerWebErrorHandler(): void { $this->container->get(ErrorHandler::class)->register(); } private function registerCliErrorHandler(): void { $output = $this->container->has(ConsoleOutput::class) ? $this->container->get(ConsoleOutput::class) : new ConsoleOutput(); $cliErrorHandler = new CliErrorHandler($output); $cliErrorHandler->register(); } private function registerApplication(): void { $this->container->singleton(ApplicationInterface::class, function (Container $c) { return new Application( $c, $c->get(ResponseEmitter::class), $c->get(TypedConfiguration::class) ); }); } private function registerConsoleApplication(): void { $this->container->singleton(ConsoleApplication::class, function (Container $c) { return new ConsoleApplication( $c, 'console', 'My Console App', null, ); }); } /** * Initialize environment with smart priority handling * * Uses EnvironmentLoader which orchestrates: * - Docker ENV vars loading (via $_ENV, $_SERVER) * - .env file loading * - Smart priority (Production: Docker ENV > .env, Development: .env > Docker ENV) * - Automatic encryption support for .env.secrets */ private function initializeEnvironment(): Environment { $loader = new EncryptedEnvLoader(); return $loader->load($this->basePath); } /** * Initialize secrets management after container is bootstrapped */ private function initializeSecretsManagement(Environment $env): void { $encryptionKey = $env->get('ENCRYPTION_KEY'); if ($encryptionKey === null) { return; // No secrets management without encryption key } try { $randomGenerator = $this->container->get(RandomGenerator::class); $serverEnvironment = $this->container->get(ServerEnvironment::class); $encryptionFactory = new EncryptionFactory($randomGenerator); $encryption = $encryptionFactory->createBest($encryptionKey); $secretManager = new SecretManager( $env, $encryption, $serverEnvironment, $randomGenerator ); $this->container->instance(SecretManager::class, $secretManager); } catch (\Throwable $e) { error_log("Failed to initialize secrets management: " . $e->getMessage()); } } }