Skip to content

Commit 9be5ec5

Browse files
authored
feat: Add getFeatureFlagResult method to client (#103)
1 parent df2a40a commit 9be5ec5

5 files changed

Lines changed: 443 additions & 16 deletions

File tree

lib/Client.php

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,52 @@ public function getFeatureFlag(
254254
bool $onlyEvaluateLocally = false,
255255
bool $sendFeatureFlagEvents = true
256256
): null | bool | string {
257+
$result = $this->getFeatureFlagResult(
258+
$key,
259+
$distinctId,
260+
$groups,
261+
$personProperties,
262+
$groupProperties,
263+
$onlyEvaluateLocally,
264+
$sendFeatureFlagEvents
265+
);
266+
267+
return $result?->getValue();
268+
}
269+
270+
/**
271+
* Get the feature flag result including value and payload.
272+
*
273+
* This is the recommended method for getting feature flag data as it returns
274+
* both the flag value and payload in a single call, while properly tracking analytics.
275+
*
276+
* @param string $key
277+
* @param string $distinctId
278+
* @param array $groups
279+
* @param array $personProperties
280+
* @param array $groupProperties
281+
* @param bool $onlyEvaluateLocally
282+
* @param bool $sendFeatureFlagEvents
283+
* @return FeatureFlagResult|null
284+
* @throws Exception
285+
*/
286+
public function getFeatureFlagResult(
287+
string $key,
288+
string $distinctId,
289+
array $groups = array(),
290+
array $personProperties = array(),
291+
array $groupProperties = array(),
292+
bool $onlyEvaluateLocally = false,
293+
bool $sendFeatureFlagEvents = true
294+
): ?FeatureFlagResult {
257295
[$personProperties, $groupProperties] = $this->addLocalPersonAndGroupProperties(
258296
$distinctId,
259297
$groups,
260298
$personProperties,
261299
$groupProperties
262300
);
263301
$result = null;
302+
$payload = null;
264303
$featureFlagError = null;
265304

266305
foreach ($this->featureFlags as $flag) {
@@ -309,6 +348,12 @@ public function getFeatureFlag(
309348
$result = null;
310349
}
311350

351+
// Extract payload from response
352+
$rawPayload = $response['featureFlagPayloads'][$key] ?? null;
353+
if ($rawPayload !== null) {
354+
$payload = json_decode($rawPayload, true);
355+
}
356+
312357
if (!empty($errors)) {
313358
$featureFlagError = implode(',', $errors);
314359
}
@@ -371,13 +416,22 @@ public function getFeatureFlag(
371416
$this->distinctIdsFeatureFlagsReported->add($key, $distinctId);
372417
}
373418

374-
if (!is_null($result)) {
375-
return $result;
419+
if (is_null($result)) {
420+
return null;
421+
}
422+
423+
// Determine enabled and variant from result
424+
if (is_bool($result)) {
425+
return new FeatureFlagResult($key, $result, null, $payload);
426+
} else {
427+
return new FeatureFlagResult($key, true, $result, $payload);
376428
}
377-
return null;
378429
}
379430

380431
/**
432+
* @deprecated Use `getFeatureFlagResult()` instead which properly tracks the feature flag call,
433+
* and includes both the flag value and payload in a single method.
434+
*
381435
* @param string $key
382436
* @param string $distinctId
383437
* @param array $groups
@@ -392,20 +446,17 @@ public function getFeatureFlagPayload(
392446
array $personProperties = array(),
393447
array $groupProperties = array(),
394448
): mixed {
395-
$results = $this->flags($distinctId, $groups, $personProperties, $groupProperties);
396-
397-
if (isset($results['featureFlags'][$key]) === false || $results['featureFlags'][$key] !== true) {
398-
return null;
399-
}
400-
401-
$payload = $results['featureFlagPayloads'][$key] ?? null;
402-
403-
if ($payload === null) {
404-
return null;
405-
}
449+
$result = $this->getFeatureFlagResult(
450+
$key,
451+
$distinctId,
452+
$groups,
453+
$personProperties,
454+
$groupProperties,
455+
false,
456+
false
457+
);
406458

407-
# feature flag payloads are always JSON encoded strings.
408-
return json_decode($payload, true);
459+
return $result?->getPayload();
409460
}
410461

411462
/**

lib/FeatureFlagResult.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace PostHog;
4+
5+
/**
6+
* Represents the result of a feature flag evaluation, including both the value and payload.
7+
*/
8+
class FeatureFlagResult
9+
{
10+
private string $key;
11+
private bool $enabled;
12+
private ?string $variant;
13+
private mixed $payload;
14+
15+
public function __construct(
16+
string $key,
17+
bool $enabled,
18+
?string $variant = null,
19+
mixed $payload = null
20+
) {
21+
$this->key = $key;
22+
$this->enabled = $enabled;
23+
$this->variant = $variant;
24+
$this->payload = $payload;
25+
}
26+
27+
/**
28+
* Get the feature flag key.
29+
*/
30+
public function getKey(): string
31+
{
32+
return $this->key;
33+
}
34+
35+
/**
36+
* Whether the flag is enabled.
37+
*/
38+
public function isEnabled(): bool
39+
{
40+
return $this->enabled;
41+
}
42+
43+
/**
44+
* Get the variant value if this is a multivariate flag.
45+
*/
46+
public function getVariant(): ?string
47+
{
48+
return $this->variant;
49+
}
50+
51+
/**
52+
* Get the decoded JSON payload associated with this flag.
53+
*/
54+
public function getPayload(): mixed
55+
{
56+
return $this->payload;
57+
}
58+
59+
/**
60+
* Get the flag value in the same format as getFeatureFlag().
61+
* Returns the variant if set, otherwise the enabled boolean.
62+
* This matches the $feature_flag_response format.
63+
*/
64+
public function getValue(): bool|string
65+
{
66+
if ($this->variant !== null) {
67+
return $this->variant;
68+
}
69+
return $this->enabled;
70+
}
71+
}

lib/PostHog.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,46 @@ public static function getFeatureFlag(
171171
}
172172

173173
/**
174+
* Get the feature flag result including value and payload.
175+
*
176+
* This is the recommended method for getting feature flag data as it returns
177+
* both the flag value and payload in a single call, while properly tracking analytics.
178+
*
179+
* @param string $key
180+
* @param string $distinctId
181+
* @param array $groups
182+
* @param array $personProperties
183+
* @param array $groupProperties
184+
* @param bool $onlyEvaluateLocally
185+
* @param bool $sendFeatureFlagEvents
186+
* @return FeatureFlagResult|null
187+
* @throws Exception
188+
*/
189+
public static function getFeatureFlagResult(
190+
string $key,
191+
string $distinctId,
192+
array $groups = array(),
193+
array $personProperties = array(),
194+
array $groupProperties = array(),
195+
bool $onlyEvaluateLocally = false,
196+
bool $sendFeatureFlagEvents = true
197+
): ?FeatureFlagResult {
198+
self::checkClient();
199+
return self::$client->getFeatureFlagResult(
200+
$key,
201+
$distinctId,
202+
$groups,
203+
$personProperties,
204+
$groupProperties,
205+
$onlyEvaluateLocally,
206+
$sendFeatureFlagEvents
207+
);
208+
}
209+
210+
/**
211+
* @deprecated Use getFeatureFlagResult() instead. This method does not send
212+
* the $feature_flag_called event, leading to missing analytics.
213+
*
174214
* @param string $key
175215
* @param string $distinctId
176216
* @param array $groups

0 commit comments

Comments
 (0)