"ClassName::method" => Defer[] */ private static array $registry = []; /** * @param string $class * @param string $method * @param Defer $defer * @return void */ public static function add(string $class, string $method, Defer $defer): void { $key = self::key($class, $method); self::$registry[$key][] = $defer; } /** * @param string $class * @param string $method * @return Defer[] */ public static function get(string $class, string $method): array { return self::$registry[self::key($class, $method)] ?? []; } /** * @param string $class * @return bool */ public static function hasAny(string $class): bool { $prefix = $class . '::'; foreach (array_keys(self::$registry) as $key) { if (str_starts_with($key, $prefix)) { return true; } } return false; } /** * @param string $class * @return array method => Defer[] */ public static function getAll(string $class): array { $result = []; $prefix = $class . '::'; foreach (self::$registry as $key => $defers) { if (str_starts_with($key, $prefix)) { $method = substr($key, strlen($prefix)); $result[$method] = $defers; } } return $result; } /** * @param string $class * @param string $method * @return void */ public static function execute(string $class, string $method): void { $key = self::key($class, $method); if (!isset(self::$registry[$key])) { return; } $defers = self::$registry[$key]; unset(self::$registry[$key]); foreach ($defers as $defer) { try { $callback = $defer->callback; $params = $defer->params; if (is_array($callback)) { [$cbClass, $cbMethod] = $callback; $instance = \Kiri::getDi()->get($cbClass); call_user_func([$instance, $cbMethod], ...$params); } else { $instance = \Kiri::getDi()->get($callback); call_user_func([$instance, '__invoke'], ...$params); } } catch (\Throwable $throwable) { \Kiri::getLogger()->error('Defer callback failed: ' . $throwable->getMessage()); } } } /** * @return void */ public static function clear(): void { self::$registry = []; } /** * @param string $class * @param string $method * @return string */ private static function key(string $class, string $method): string { return $class . '::' . $method; } }