77/**
88 * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/context.md#overview
99 */
10- class Context
10+ final class Context
1111{
12- /**
13- * @var ContextKey|null
14- */
15- protected $ key ;
12+ /** @var self|null */
13+ private static $ current_context ;
14+
15+ /** @var self|null */
16+ private static $ root ;
1617
1718 /**
18- * @var mixed|null
19+ * This will set the given Context to be the "current" one. We return a token which can be passed to `detach()` to
20+ * reset the Current Context back to the previous one.
21+ *
22+ * @return callable():Context - token for resetting the $current_context back
1923 */
20- protected $ value ;
21-
22- /** @var self|null */
23- protected $ parent ;
24+ public static function attach ( Context $ ctx ): callable
25+ {
26+ $ former_ctx = self :: getCurrent ();
27+ self :: $ current_context = $ ctx ;
2428
25- protected static $ current_context = null ;
29+ return static function () use ($ former_ctx ) {
30+ return $ former_ctx ;
31+ };
32+ }
2633
2734 /**
2835 * @param non-empty-string $key
@@ -34,6 +41,92 @@ public static function createKey(string $key): ContextKey
3441 return new ContextKey ($ key );
3542 }
3643
44+ /**
45+ * Given a token, the current context will be set back to the one prior to the token being generated.
46+ * @param callable():Context $token
47+ */
48+ public static function detach (callable $ token ): Context
49+ {
50+ return self ::$ current_context = $ token ();
51+ }
52+
53+ public static function getCurrent (): Context
54+ {
55+ return self ::$ current_context ?? (self ::$ current_context = self ::getRoot ());
56+ }
57+
58+ public static function getRoot (): self
59+ {
60+ if (null === self ::$ root ) {
61+ self ::$ root = new self ();
62+ }
63+
64+ return self ::$ root ;
65+ }
66+
67+ /**
68+ * Static version of get()
69+ * This is primarily useful when the caller doesn't already have a reference to the Context that they want to mutate.
70+ * This will operate on the "current" global context in that scenario.
71+ *
72+ * There are two ways to call this function:
73+ * 1) With a $ctx value:
74+ * Context::getValue($key, $ctx) is functionally equivalent to $ctx->get($key)
75+ * 2) Without a $ctx value:
76+ * This will fetch the "current" Context if one exists or create one if not, then attempt to get the value from it.
77+ *
78+ * @param ContextKey $key
79+ * @param Context|null $ctx
80+ *
81+ * @return mixed
82+ */
83+ public static function getValue (ContextKey $ key , $ ctx =null )
84+ {
85+ $ ctx = $ ctx ?? static ::getCurrent ();
86+
87+ return $ ctx ->get ($ key );
88+ }
89+
90+ /**
91+ * This is a static version of set().
92+ * This is primarily useful when the caller doesn't already have a reference to a Context that they want to mutate.
93+ *
94+ * There are two ways to call this function.
95+ * 1) With a $parent parameter:
96+ * Context::setValue($key, $value, $ctx) is functionally equivalent to $ctx->set($key, $value)
97+ * 2) Without a $parent parameter:
98+ * In this scenario, setValue() will use the `$current_context` reference as supplied by `getCurrent()`
99+ * `getCurrent()` will always return a valid Context. If one does not exist at the global scope,
100+ * an "empty" context will be created.
101+ *
102+ * @param ContextKey $key
103+ * @param mixed $value
104+ * @param Context|null $parent
105+ *
106+ * @return Context a new Context containing the k/v
107+ */
108+ public static function withValue (ContextKey $ key , $ value , $ parent =null )
109+ {
110+ if (null === $ parent ) {
111+ return self ::$ current_context = new self ($ key , $ value , self ::getCurrent ());
112+ }
113+
114+ return new self ($ key , $ value , $ parent );
115+ }
116+
117+ /**
118+ * @var ContextKey|null
119+ */
120+ protected $ key ;
121+
122+ /**
123+ * @var mixed|null
124+ */
125+ protected $ value ;
126+
127+ /** @var self|null */
128+ protected $ parent ;
129+
37130 /**
38131 * This is a general purpose read-only key-value store. Read-only in the sense that adding a new value does not
39132 * mutate the existing context, but returns a new Context which has the new value added.
@@ -69,7 +162,7 @@ final public function __construct(?ContextKey $key=null, $value=null, $parent=nu
69162 */
70163 public function with (ContextKey $ key , $ value )
71164 {
72- return new static ($ key , $ value , $ this );
165+ return new self ($ key , $ value , $ this );
73166 }
74167
75168 /**
@@ -90,33 +183,6 @@ public function activate(): Scope
90183 return new Scope (self ::attach ($ this ));
91184 }
92185
93- /**
94- * This is a static version of set().
95- * This is primarily useful when the caller doesn't already have a reference to a Context that they want to mutate.
96- *
97- * There are two ways to call this function.
98- * 1) With a $parent parameter:
99- * Context::setValue($key, $value, $ctx) is functionally equivalent to $ctx->set($key, $value)
100- * 2) Without a $parent parameter:
101- * In this scenario, setValue() will use the `$current_context` reference as supplied by `getCurrent()`
102- * `getCurrent()` will always return a valid Context. If one does not exist at the global scope,
103- * an "empty" context will be created.
104- *
105- * @param ContextKey $key
106- * @param mixed $value
107- * @param Context|null $parent
108- *
109- * @return Context a new Context containing the k/v
110- */
111- public static function withValue (ContextKey $ key , $ value , $ parent =null )
112- {
113- if (null === $ parent ) {
114- return static ::$ current_context = new static ($ key , $ value , static ::getCurrent ());
115- }
116-
117- return new static ($ key , $ value , $ parent );
118- }
119-
120186 /**
121187 * Fetch a value from the Context given a key value.
122188 *
@@ -134,66 +200,4 @@ public function get(ContextKey $key)
134200
135201 return $ this ->parent ->get ($ key );
136202 }
137-
138- /**
139- * Static version of get()
140- * This is primarily useful when the caller doesn't already have a reference to the Context that they want to mutate.
141- * This will operate on the "current" global context in that scenario.
142- *
143- * There are two ways to call this function:
144- * 1) With a $ctx value:
145- * Context::getValue($key, $ctx) is functionally equivalent to $ctx->get($key)
146- * 2) Without a $ctx value:
147- * This will fetch the "current" Context if one exists or create one if not, then attempt to get the value from it.
148- *
149- * @param ContextKey $key
150- * @param Context|null $ctx
151- *
152- * @return mixed
153- */
154- public static function getValue (ContextKey $ key , $ ctx =null )
155- {
156- $ ctx = $ ctx ?? static ::getCurrent ();
157-
158- return $ ctx ->get ($ key );
159- }
160-
161- public static function getCurrent (): Context
162- {
163- if (null === static ::$ current_context ) {
164- static ::$ current_context = new static ();
165- }
166-
167- return static ::$ current_context ;
168- }
169-
170- /**
171- * This will set the given Context to be the "current" one. We return a token which can be passed to `detach()` to
172- * reset the Current Context back to the previous one.
173- *
174- * @param Context $ctx
175- *
176- * @return callable token for resetting the $current_context back
177- */
178- public static function attach ($ ctx ): callable
179- {
180- $ former_ctx = static ::$ current_context ;
181- static ::$ current_context = $ ctx ;
182-
183- return function () use ($ former_ctx ) {
184- return $ former_ctx ;
185- };
186- }
187-
188- /**
189- * Given a token, the current context will be set back to the one prior to the token being generated.
190- *
191- * @param callable $token
192- *
193- * @return Context
194- */
195- public static function detach (callable $ token )
196- {
197- return static ::$ current_context = call_user_func ($ token );
198- }
199203}
0 commit comments