A simple command-line todo application built with plain PHP (no framework) demonstrating PostHog integration for CLIs, scripts, data pipelines, and non-web PHP applications.
This example serves as:
- Verification that the context-mill wizard works for plain PHP projects
- Reference implementation of PostHog best practices for non-framework PHP code
- Working example you can run and modify
- SDK initialization - Uses
PostHog::init(...)once with environment-based configuration - Event tracking - Captures user actions with
distinctIdand properties - User identification - Associates properties with users via
PostHog::identify(...) - Error tracking - Enables automatic PHP error tracking and manually captures handled exceptions
- Proper flushing - Calls
PostHog::flush()before CLI exit
composer install# Copy environment template
cp .env.example .env
# Edit .env and add your PostHog project token
# POSTHOG_PROJECT_TOKEN=phc_your_project_token_here
# POSTHOG_HOST=https://us.i.posthog.com# Add a todo
php todo.php add "Buy groceries"
# List all todos
php todo.php list
# Complete a todo
php todo.php complete 1
# Delete a todo
php todo.php delete 1
# Show statistics
php todo.php statsThe app tracks these events in PostHog:
| Event | Properties | Purpose |
|---|---|---|
todo_added |
todo_id, todo_length, total_todos |
When user adds a new todo |
todos_viewed |
total_todos, completed_todos |
When user lists todos |
todo_completed |
todo_id, time_to_complete_hours |
When user completes a todo |
todo_deleted |
todo_id, was_completed |
When user deletes a todo |
stats_viewed |
total_todos, completed_todos, pending_todos |
When user views stats |
$exception |
exception details and command context | When handled errors occur |
basics/php/
├── todo.php # Main CLI application
├── composer.json # PHP dependencies
├── .env.example # Environment variable template
├── .gitignore # Git ignore rules
└── README.md # This file
PostHog::init($projectToken, [
'host' => $host,
'error_tracking' => [
'enabled' => true,
],
]);PostHog::capture([
'distinctId' => 'user_123',
'event' => 'event_name',
'properties' => ['key' => 'value'],
]);PostHog::identify([
'distinctId' => 'user_123',
'properties' => ['app_language' => 'php'],
]);try {
riskyOperation();
} catch (Throwable $e) {
PostHog::captureException($e, 'user_123', [
'command' => 'example_command',
]);
}PostHog::flush();The app works fine without PostHog configured - it simply won't track analytics. You'll see a warning message but the app continues to function normally.
- Modify
todo.phpto experiment with PostHog tracking - Add new commands and track their usage
- Explore feature flags:
PostHog::isFeatureEnabled('flag-name', 'user_id') - Check your PostHog dashboard to see tracked events