0) { Coroutine::getContextFor()[$id] = $value; } else { static::$nonCoContext[$id] = $value; } return $value; } public static function get(string $id, $default = null, $coroutineId = null) { if (Coroutine::id() > 0) { return Coroutine::getContextFor($coroutineId)[$id] ?? $default; } return static::$nonCoContext[$id] ?? $default; } public static function has(string $id, $coroutineId = null) { if (Coroutine::id() > 0) { return isset(Coroutine::getContextFor($coroutineId)[$id]); } return isset(static::$nonCoContext[$id]); } /** * Release the context when you are not in coroutine environment. */ public static function destroy(string $id) { unset(static::$nonCoContext[$id]); } /** * Copy the context from a coroutine to current coroutine. * This method will delete the origin values in current coroutine. */ public static function copy(int $fromCoroutineId, array $keys = []): void { $from = Coroutine::getContextFor($fromCoroutineId); if ($from === null) { return; } $current = Coroutine::getContextFor(); if ($keys) { $map = array_intersect_key($from->getArrayCopy(), array_flip($keys)); } else { $map = $from->getArrayCopy(); } $current->exchangeArray($map); } /** * Retrieve the value and override it by closure. */ public static function override(string $id, \Closure $closure) { $value = null; if (self::has($id)) { $value = self::get($id); } $value = $closure($value); self::set($id, $value); return $value; } /** * Retrieve the value and store it if not exists. * @param mixed $value */ public static function getOrSet(string $id, $value) { if (! self::has($id)) { return self::set($id, value($value)); } return self::get($id); } public static function getContainer() { if (Coroutine::id() > 0) { return Coroutine::getContextFor(); } return static::$nonCoContext; } }