Repository navigation
Conversation
posthog-php-socket Compliance ReportDate: 2026-11-13T20:57:45.225562+00:00
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 25ms |
| Format Validation.Event Has Uuid | ✅ | 520ms |
| Format Validation.Event Has Lib Properties | ✅ | 522ms |
| Format Validation.Distinct Id Is String | ✅ | 521ms |
| Format Validation.Token Is Present | ✅ | 521ms |
| Format Validation.Custom Properties Preserved | ✅ | 521ms |
| Format Validation.Event Has Timestamp | ✅ | 521ms |
| Format Validation.Non Utc Event Timestamp Is Converted To Utc | ✅ | 521ms |
| Retry Behavior.Retries On 503 | ✅ | 5830ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 2522ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 2524ms |
| Retry Behavior.Respects Retry After Header | ❌ | 6330ms |
| Retry Behavior.Implements Backoff | ✅ | 16236ms |
| Retry Behavior.Retries On 500 | ✅ | 5135ms |
| Retry Behavior.Retries On 502 | ✅ | 5633ms |
| Retry Behavior.Retries On 504 | ✅ | 5627ms |
| Retry Behavior.Max Retries Respected | ✅ | 16246ms |
| Deduplication.Generates Unique Uuids | ✅ | 527ms |
| Deduplication.Preserves Uuid On Retry | ✅ | 5631ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ✅ | 10841ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ✅ | 5632ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 525ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 523ms |
| Compression.Sends Gzip When Enabled | ✅ | 521ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 521ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 517ms |
| Batch Format.Multiple Events Batched Together | ✅ | 509ms |
| Error Handling.Does Not Retry On 403 | ✅ | 2523ms |
| Error Handling.Does Not Retry On 413 | ✅ | 2523ms |
| Error Handling.Retries On 408 | ✅ | 5629ms |
Failures
retry_behavior.respects_retry_after_header
Retry delay too short: 803ms < 2500ms
Feature_Flags Tests
✅ 17/17 tests passed
View Details
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ✅ | 520ms |
| Request Payload.Flags Request Uses V2 Query Param | ✅ | 519ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ✅ | 521ms |
| Request Payload.Flags Request Omits Authorization Header | ✅ | 519ms |
| Request Payload.Token In Flags Body Matches Init | ✅ | 519ms |
| Request Payload.Groups Round Trip | ✅ | 520ms |
| Request Payload.Groups Default To Empty Object | ✅ | 519ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ✅ | 520ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ✅ | 519ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ✅ | 520ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 515ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 507ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ✅ | 523ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ✅ | 520ms |
| Retry Behavior.Retries Flags On 502 | ✅ | 622ms |
| Retry Behavior.Retries Flags On 504 | ✅ | 622ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ✅ | 521ms |
posthog-php-fork_curl Compliance ReportDate: 2026-11-13T20:57:26.116230+00:00
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 41ms |
| Format Validation.Event Has Uuid | ✅ | 532ms |
| Format Validation.Event Has Lib Properties | ✅ | 534ms |
| Format Validation.Distinct Id Is String | ✅ | 534ms |
| Format Validation.Token Is Present | ✅ | 535ms |
| Format Validation.Custom Properties Preserved | ✅ | 535ms |
| Format Validation.Event Has Timestamp | ✅ | 534ms |
| Format Validation.Non Utc Event Timestamp Is Converted To Utc | ✅ | 535ms |
| Retry Behavior.Retries On 503 | ✅ | 5862ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 2537ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 2536ms |
| Retry Behavior.Respects Retry After Header | ❌ | 6355ms |
| Retry Behavior.Implements Backoff | ✅ | 16285ms |
| Retry Behavior.Retries On 500 | ✅ | 5652ms |
| Retry Behavior.Retries On 502 | ✅ | 5653ms |
| Retry Behavior.Retries On 504 | ✅ | 5652ms |
| Retry Behavior.Max Retries Respected | ✅ | 16286ms |
| Deduplication.Generates Unique Uuids | ✅ | 543ms |
| Deduplication.Preserves Uuid On Retry | ✅ | 5651ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ✅ | 10870ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ✅ | 5656ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 541ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 538ms |
| Compression.Sends Gzip When Enabled | ✅ | 537ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 535ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 522ms |
| Batch Format.Multiple Events Batched Together | ✅ | 522ms |
| Error Handling.Does Not Retry On 403 | ✅ | 2539ms |
| Error Handling.Does Not Retry On 413 | ✅ | 2537ms |
| Error Handling.Retries On 408 | ✅ | 5654ms |
Failures
retry_behavior.respects_retry_after_header
Retry delay too short: 811ms < 2500ms
Feature_Flags Tests
✅ 17/17 tests passed
View Details
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ✅ | 526ms |
| Request Payload.Flags Request Uses V2 Query Param | ✅ | 525ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ✅ | 526ms |
| Request Payload.Flags Request Omits Authorization Header | ✅ | 526ms |
| Request Payload.Token In Flags Body Matches Init | ✅ | 526ms |
| Request Payload.Groups Round Trip | ✅ | 526ms |
| Request Payload.Groups Default To Empty Object | ✅ | 525ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ✅ | 526ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ✅ | 526ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ✅ | 526ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 520ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 518ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ✅ | 528ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ✅ | 528ms |
| Retry Behavior.Retries Flags On 502 | ✅ | 628ms |
| Retry Behavior.Retries Flags On 504 | ✅ | 628ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ✅ | 538ms |
posthog-php-lib_curl Compliance ReportDate: 2026-11-13T20:57:50.375907+00:00
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 29ms |
| Format Validation.Event Has Uuid | ✅ | 523ms |
| Format Validation.Event Has Lib Properties | ✅ | 526ms |
| Format Validation.Distinct Id Is String | ✅ | 526ms |
| Format Validation.Token Is Present | ✅ | 525ms |
| Format Validation.Custom Properties Preserved | ✅ | 525ms |
| Format Validation.Event Has Timestamp | ✅ | 526ms |
| Format Validation.Non Utc Event Timestamp Is Converted To Utc | ✅ | 526ms |
| Retry Behavior.Retries On 503 | ✅ | 5834ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 2529ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 2527ms |
| Retry Behavior.Respects Retry After Header | ❌ | 6336ms |
| Retry Behavior.Implements Backoff | ✅ | 16248ms |
| Retry Behavior.Retries On 500 | ✅ | 5636ms |
| Retry Behavior.Retries On 502 | ✅ | 5633ms |
| Retry Behavior.Retries On 504 | ✅ | 5634ms |
| Retry Behavior.Max Retries Respected | ✅ | 17050ms |
| Deduplication.Generates Unique Uuids | ✅ | 233ms |
| Deduplication.Preserves Uuid On Retry | ✅ | 5635ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ✅ | 10841ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ✅ | 5639ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 531ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 527ms |
| Compression.Sends Gzip When Enabled | ✅ | 526ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 525ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 520ms |
| Batch Format.Multiple Events Batched Together | ✅ | 515ms |
| Error Handling.Does Not Retry On 403 | ✅ | 2527ms |
| Error Handling.Does Not Retry On 413 | ✅ | 2528ms |
| Error Handling.Retries On 408 | ✅ | 5635ms |
Failures
retry_behavior.respects_retry_after_header
Retry delay too short: 804ms < 2500ms
Feature_Flags Tests
✅ 17/17 tests passed
View Details
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ✅ | 525ms |
| Request Payload.Flags Request Uses V2 Query Param | ✅ | 524ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ✅ | 523ms |
| Request Payload.Flags Request Omits Authorization Header | ✅ | 522ms |
| Request Payload.Token In Flags Body Matches Init | ✅ | 523ms |
| Request Payload.Groups Round Trip | ✅ | 523ms |
| Request Payload.Groups Default To Empty Object | ✅ | 523ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ✅ | 522ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ✅ | 523ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ✅ | 523ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 517ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 511ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ✅ | 527ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ✅ | 524ms |
| Retry Behavior.Retries Flags On 502 | ✅ | 626ms |
| Retry Behavior.Retries Flags On 504 | ✅ | 625ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ✅ | 525ms |
There was a problem hiding this comment.
PostHog Review · Standard · reviewed 6114a8e: 1 Should fix.
See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.

💡 Motivation and Context
Part of PostHog/posthog-android#577.
posthog-php had no way to read the payload of a remote config feature flag. posthog-node has
getRemoteConfigPayload()for this, and this adds the same method toPostHog\Client, with a staticPostHog::getRemoteConfigPayload()forwarder:It sends one
GET {host}/api/projects/@current/feature_flags/{key}/remote_config?token={projectToken}with the secret key as a bearer token, and returns the decoded payload. The endpoint can answer with a JSON string that itself holds JSON, so a string result is decoded a second time, and returned as is when that second decode fails.A few things that aren't obvious from the diff:
nullwhen the client is disabled, no secret key is set, the request fails, PostHog answers with a non-2xx status, or the body is not valid JSON.nullwithout a warning. PostHog answers a flag with no payload that way. posthog-node throws aSyntaxErroron this response today (await response.json()on an empty body,packages/node/src/client.ts:2272at 480395c4), so this is one more place where the port differs from posthog-node. An empty body with a non-2xx status, like the 404 for an unknown flag, is still a failure.rawurlencoded as one path segment, and so is the token. A key that is empty,.or..is refused before any request, because it would resolve to a different path.$feature_flag_calledevent. The timeout is the existingfeature_flag_request_timeout_msoption, 3 seconds by default.options['host']through the client's existingHttpClient, the same as the other flag calls.packages/laravelis unchanged. Its forwarders are declared explicitly, so the new method isn't exposed there, and that's worth a follow-up if we want it on the Laravel manager.Public API change:
api/public-api.jsongains the twogetRemoteConfigPayloadentries.💚 How did you test it?
test/RemoteConfigPayloadTest.php, 29 tests againstMockedHttpClient: the decode paths (object, double-encoded string, plain string, JSONnull, non-JSON), an empty and a whitespace-only 200 body with no warning, a 404 with an empty body, the guards (disabled client, no secret key, refused keys), non-2xx statuses and curl failures with no retry, the encoding of the key and the token, the request headers and options, the configured timeout, and the static forwarder.EmailsClientTest::testAnOversizedReplyIsNotReadOrRetried, which fails on some local runs with and without this change. It uses the loopback server and this PR doesn't touch it.phpcsreports 0 errors, andcomposer api:checkandcomposer api:check:laravelboth report an up-to-date snapshot.📝 Checklist
If releasing new changes
pnpm changeto generate a change intent file🤖 Agent context
DRI: @ioannisj
Autonomy: Human-driven (agent-assisted)