11<?php
22
3+ // phpcs:disable PSR1.Files.SideEffects
4+
35// PostHog PHP library example
46//
57// This script demonstrates various PostHog PHP SDK capabilities including:
@@ -89,9 +91,10 @@ function loadEnvFile()
8991echo "3. Feature flag dependencies examples \n" ;
9092echo "4. Context management and tagging examples \n" ;
9193echo "5. ETag polling examples (for local evaluation) \n" ;
92- echo "6. Run all examples \n" ;
93- echo "7. Exit \n" ;
94- $ choice = trim (readline ("\nEnter your choice (1-7): " ));
94+ echo "6. Error tracking examples \n" ;
95+ echo "7. Run all examples \n" ;
96+ echo "8. Exit \n" ;
97+ $ choice = trim (readline ("\nEnter your choice (1-8): " ));
9598
9699function identifyAndCaptureExamples ()
97100{
@@ -266,7 +269,11 @@ function flagDependencyExamples()
266269 [],
267270 true
268271 );
269- echo "📊 Beta feature comparison - @example.com: " . json_encode ($ beta1 ) . ", regular: " . json_encode ($ beta2 ) . "\n" ;
272+ echo "📊 Beta feature comparison - @example.com: "
273+ . json_encode ($ beta1 )
274+ . ", regular: "
275+ . json_encode ($ beta2 )
276+ . "\n" ;
270277
271278 echo "\n🎯 Results Summary: \n" ;
272279 echo " - Flag dependencies evaluated locally: " . ($ result1 != $ result2 ? "✅ YES " : "❌ NO " ) . "\n" ;
@@ -301,7 +308,10 @@ function flagDependencyExamples()
301308 true
302309 );
303310 if ($ dependentResult3 !== "breaking-bad " ) {
304- echo " ❌ Something went wrong evaluating 'multivariate-root-flag' with pineapple@example.com. Expected 'breaking-bad', got ' " . json_encode ($ dependentResult3 ) . "' \n" ;
311+ echo " ❌ Something went wrong evaluating 'multivariate-root-flag' with pineapple@example.com. "
312+ . "Expected 'breaking-bad', got ' "
313+ . json_encode ($ dependentResult3 )
314+ . "' \n" ;
305315 } else {
306316 echo "✅ 'multivariate-root-flag' with email pineapple@example.com succeeded \n" ;
307317 }
@@ -316,7 +326,10 @@ function flagDependencyExamples()
316326 true
317327 );
318328 if ($ dependentResult4 !== "the-wire " ) {
319- echo " ❌ Something went wrong evaluating multivariate-root-flag with mango@example.com. Expected 'the-wire', got ' " . json_encode ($ dependentResult4 ) . "' \n" ;
329+ echo " ❌ Something went wrong evaluating multivariate-root-flag with mango@example.com. "
330+ . "Expected 'the-wire', got ' "
331+ . json_encode ($ dependentResult4 )
332+ . "' \n" ;
320333 } else {
321334 echo "✅ 'multivariate-root-flag' with email mango@example.com succeeded \n" ;
322335 }
@@ -490,14 +503,101 @@ function etagPollingExamples()
490503 if ($ beforeEtag === $ afterEtag && $ beforeEtag !== null ) {
491504 echo "No change (304 Not Modified) - $ currentFlagCount flag(s) \n" ;
492505 } else {
493- echo "🔄 Flags updated! New ETag: " . ($ afterEtag ? substr ($ afterEtag , 0 , 20 ) . "... " : "none " ) . " - $ currentFlagCount flag(s) \n" ;
506+ echo "🔄 Flags updated! New ETag: "
507+ . ($ afterEtag ? substr ($ afterEtag , 0 , 20 ) . "... " : "none " )
508+ . " - $ currentFlagCount flag(s) \n" ;
494509 }
495510
496511 $ iteration ++;
497512 sleep (5 );
498513 }
499514}
500515
516+ function errorTrackingExamples ()
517+ {
518+ echo "\n" . str_repeat ("= " , 60 ) . "\n" ;
519+ echo "ERROR TRACKING EXAMPLES \n" ;
520+ echo str_repeat ("= " , 60 ) . "\n" ;
521+
522+ PostHog::init (
523+ $ _ENV ['POSTHOG_PROJECT_API_KEY ' ],
524+ [
525+ 'host ' => $ _ENV ['POSTHOG_HOST ' ] ?? 'https://app.posthog.com ' ,
526+ 'debug ' => true ,
527+ 'ssl ' => !str_starts_with ($ _ENV ['POSTHOG_HOST ' ] ?? 'https://app.posthog.com ' , 'http:// ' ),
528+ 'error_tracking ' => [
529+ 'enabled ' => true ,
530+ 'context_provider ' => static function (array $ payload ): array {
531+ return [
532+ 'distinctId ' => 'sdk-demo-user ' ,
533+ 'properties ' => [
534+ '$error_source ' => $ payload ['source ' ],
535+ ],
536+ ];
537+ },
538+ ],
539+ ],
540+ null ,
541+ $ _ENV ['POSTHOG_PERSONAL_API_KEY ' ]
542+ );
543+
544+ echo "Auto capture enabled for uncaught exceptions, PHP errors, and fatal shutdown errors. \n" ;
545+ echo "The demo below still uses manual capture so it can finish without crashing the process. \n\n" ;
546+
547+ // 1. Capture a plain string error (no user context)
548+ echo "1. Capturing anonymous string error... \n" ;
549+ PostHog::captureException ('Something went wrong during startup ' );
550+ echo " -> sent with auto-generated distinct_id, \$process_person_profile=false \n\n" ;
551+
552+ // 2. Capture an exception for a known user
553+ echo "2. Capturing exception for a known user... \n" ;
554+ try {
555+ throw new \RuntimeException ('Database connection failed ' );
556+ } catch (\RuntimeException $ e ) {
557+ PostHog::captureException ($ e , 'user-123 ' );
558+ }
559+ echo " -> sent as \$exception event with stacktrace \n\n" ;
560+
561+ // 3. Capture with additional context properties
562+ echo "3. Capturing exception with request context... \n" ;
563+ try {
564+ throw new \InvalidArgumentException ('Invalid email address provided ' );
565+ } catch (\InvalidArgumentException $ e ) {
566+ PostHog::captureException ($ e , 'user-456 ' , [
567+ '$current_url ' => 'https://example.com/signup ' ,
568+ '$request_method ' => 'POST ' ,
569+ 'form_field ' => 'email ' ,
570+ ]);
571+ }
572+ echo " -> sent with URL and request context \n\n" ;
573+
574+ // 4. Capture a chained exception (cause + wrapper both appear in \$exception_list)
575+ echo "4. Capturing chained exception... \n" ;
576+ try {
577+ try {
578+ throw new \PDOException ('SQLSTATE[HY000]: General error: disk full ' );
579+ } catch (\PDOException $ cause ) {
580+ throw new \RuntimeException ('Failed to save user record ' , 0 , $ cause );
581+ }
582+ } catch (\RuntimeException $ e ) {
583+ PostHog::captureException ($ e , 'user-789 ' );
584+ }
585+ echo " -> sent with 2 entries in \$exception_list (cause + wrapper) \n\n" ;
586+
587+ // 5. Capture a PHP Error (not just Exception)
588+ echo "5. Capturing a TypeError (PHP Error subclass)... \n" ;
589+ try {
590+ $ result = array_sum ('not-an-array ' );
591+ } catch (\TypeError $ e ) {
592+ PostHog::captureException ($ e , 'user-123 ' );
593+ }
594+ echo " -> any Throwable (Error or Exception) is accepted \n\n" ;
595+
596+ PostHog::flush ();
597+ echo "Flushed all events. \n" ;
598+ echo "Check your PostHog dashboard -> Error Tracking to see the captured exceptions. \n" ;
599+ }
600+
501601function runAllExamples ()
502602{
503603 identifyAndCaptureExamples ();
@@ -510,6 +610,9 @@ function runAllExamples()
510610 echo "\n" . str_repeat ("- " , 60 ) . "\n" ;
511611
512612 contextManagementExamples ();
613+ echo "\n" . str_repeat ("- " , 60 ) . "\n" ;
614+
615+ errorTrackingExamples ();
513616
514617 echo "\n🎉 All examples completed! \n" ;
515618 echo " (ETag polling skipped - run separately with option 5) \n" ;
@@ -533,13 +636,16 @@ function runAllExamples()
533636 etagPollingExamples ();
534637 break ;
535638 case '6 ' :
536- runAllExamples ();
639+ errorTrackingExamples ();
537640 break ;
538641 case '7 ' :
642+ runAllExamples ();
643+ break ;
644+ case '8 ' :
539645 echo "👋 Goodbye! \n" ;
540646 exit (0 );
541647 default :
542- echo "❌ Invalid choice. Please run the script again and choose 1-7 . \n" ;
648+ echo "❌ Invalid choice. Please run the script again and choose 1-8 . \n" ;
543649 exit (1 );
544650}
545651
0 commit comments