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); $this->container->instance(TypedConfiguration::class, new TypedConfigInitializer($env)($this->container)); // ExecutionContext detection sollte das erste sein, das nach dem Instanziieren des containers passiert. noch bevor dem bootstrap des containers. $executionContext = ExecutionContext::detect($env); $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()) { // 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); register_shutdown_function(function () { $error = error_get_last(); if ($error !== null) { echo 'SHUTDOWN ERROR: ' . print_r($error, 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(); $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 encryption support */ private function initializeEnvironment(): Environment { // First, try to load basic environment to get encryption key $basicEnv = Environment::fromFile($this->basePath . '/.env'); $encryptionKey = $basicEnv->get('ENCRYPTION_KEY'); // If we have an encryption key, use the encrypted loader if ($encryptionKey !== null) { try { // These dependencies will be resolved later through the container $randomGenerator = $this->container->get(RandomGenerator::class); $encryptionFactory = new EncryptionFactory($randomGenerator); $encryptedLoader = new EncryptedEnvLoader($encryptionFactory, $randomGenerator); return $encryptedLoader->loadEnvironment($this->basePath, $encryptionKey); } catch (\Throwable $e) { // Fallback to basic environment if encryption fails error_log("Failed to load encrypted environment: " . $e->getMessage()); return $basicEnv; } } // Fallback to basic environment loading return $basicEnv; } /** * 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()); } } }