CodeIgniter 4 integration for Perfbase.
This package is a thin adapter over perfbase/php-sdk. It wires CodeIgniter request and Spark command lifecycles into the Perfbase SDK without adding its own transport, queueing, or buffering layer.
Supported in v1:
- HTTP request profiling through a global CodeIgniter filter
- Spark CLI profiling through
pre_commandandpost_commandevents - optional authenticated user enrichment through a custom resolver or CodeIgniter Shield
- uncaught HTTP exception cleanup through a Perfbase-aware exception service
- worker-safe lifecycle cleanup for FrankenPHP worker mode
Not supported in v1:
- queue worker adapters
- scheduler adapters
- automatic profiling for third-party task runners
- custom dashboards or CodeIgniter-specific UI
- PHP
>=8.2 <8.5 - CodeIgniter
^4.3.8 - Perfbase PHP extension
perfbase/php-sdk1.0.0
Optional:
codeigniter4/shieldfor first-class authenticated user resolution
The current verified support floor is CodeIgniter 4.3.8 on PHP 8.2+.
Install the package:
composer require perfbase/codeigniter4For monorepo development, this package is already configured to use the local sibling SDK checkout via the path repository in composer.json.
- Install the package.
- Run the installer:
php spark perfbase:install- Set your API key in the environment or published config.
- Make sure the Perfbase PHP extension is installed and enabled.
- Verify the setup:
php spark perfbase:doctorThe installer:
- publishes
app/Config/Perfbase.php - registers the
perfbasefilter alias inapp/Config/Filters.php - adds
perfbaseto globalbeforeandafterfilters
If you only want the alias and do not want the command to modify global filters:
php spark perfbase:install --alias-onlyIf you prefer to publish the config manually:
php spark publish --namespace Perfbase\\CodeIgniter4After installation, configuration lives in app/Config/Perfbase.php.
The package also supports environment-backed defaults via src/Config/Perfbase.php.
public bool $enabled = false;
public bool $debug = false;
public bool $logErrors = true;
public string $apiKey = '';
public string $apiUrl = 'https://ingress.perfbase.cloud';
public float $sampleRate = 0.1;
public int $timeout = 10;
public ?string $proxy = null;
public int $flags = FeatureFlags::DefaultFlags;
public string $appVersion = '';
public ?string $userResolver = null;
public array $includeHttp = ['*'];
public array $excludeHttp = [];
public array $includeConsole = ['*'];
public array $excludeConsole = [];perfbase.enabled=true
perfbase.debug=false
perfbase.logErrors=true
perfbase.apiKey=
perfbase.apiUrl=https://ingress.perfbase.cloud
perfbase.sampleRate=0.1
perfbase.timeout=10
perfbase.proxy=
perfbase.flags=0
perfbase.appVersion=
perfbase.userResolver=
perfbase.includeHttp=*
perfbase.excludeHttp=
perfbase.includeConsole=*
perfbase.excludeConsole=<?php
namespace Config;
use Perfbase\CodeIgniter4\Config\Perfbase as BasePerfbase;
use Perfbase\SDK\FeatureFlags;
final class Perfbase extends BasePerfbase
{
public bool $enabled = true;
public bool $debug = false;
public bool $logErrors = true;
public string $apiKey = '';
public float $sampleRate = 0.2;
public int $timeout = 10;
public int $flags = FeatureFlags::DefaultFlags;
public string $appVersion = '1.0.0';
public array $excludeHttp = ['/health', '/up'];
public array $excludeConsole = ['cache:*', 'migrate:*'];
}Run:
php spark perfbase:doctorThe doctor checks:
- whether profiling is enabled
- whether an API key is configured
- whether the SDK booted successfully
- whether the Perfbase extension is available
- whether the
perfbasealias exists - whether global
beforeandafterfilters are configured - whether Shield was detected
- whether FrankenPHP worker mode is active or configured
If worker mode is detected, the doctor also prints a reminder to restart workers after config or deployment changes.
Normal package CI stays on the declared support floor. Older CodeIgniter 4 minors should be tested explicitly.
Run compatibility probes locally without depending on the host PHP version:
bin/test-compat --php 8.2 --framework 4.3.8
bin/test-compat --php 8.2 --framework 4.4.8
bin/test-compat --php 8.2 --framework 4.6.5Notes:
- The script mounts the parent
projects/directory so the local siblinglib-php-sdkpath repository continues to work inside the container. --ignore-php-platformis intended for floor exploration when the package's current declared PHP floor is higher than the probe target.- The script runs
composer update,composer run phpstan, andcomposer run testinside the selected container image.
The manual workflow in .github/workflows/compatibility.yml runs a small set of explicit PHP/CodeIgniter pairs:
- PHP
8.2/ CodeIgniter4.3.8 - PHP
8.2/ CodeIgniter4.4.8 - PHP
8.2/ CodeIgniter4.5.8 - PHP
8.2/ CodeIgniter4.6.5 - PHP
8.4/ CodeIgniter4.7.2
This workflow is manual on purpose. It is for compatibility investigation and release-floor validation, not for every pull request.
HTTP profiling is implemented by the perfbase filter.
The package:
- starts profiling in the filter
before()phase - finalizes successful requests in
after() - finalizes uncaught exception paths through the Perfbase exception service
- excludes query strings from
http_url - prefers route patterns for low-cardinality action naming
- falls back to
Controller::methodand then the sanitized path
The HTTP lifecycle sets:
source=httpactionhttp_methodhttp_urlhttp_status_codeuser_ipuser_agentuser_idwhen availablehostnameenvironmentapp_versionphp_version
http_url intentionally excludes query strings to avoid leaking secrets and to reduce cardinality.
CLI profiling is wired through pre_command and post_command events.
The package:
- starts profiling before the command runs
- records the command name as the action
- records exit codes on completion
- records thrown exceptions on failure
- always clears active command state after completion
HTTP and console include/exclude filters support:
*.*- glob patterns such as
/admin/*orcache:* - regex patterns such as
/^GET \/api\//
HTTP matching evaluates:
- request path
METHOD path- route pattern when available
METHOD routePattern- controller
- method
Controller::method
Console matching evaluates the Spark command name.
Malformed regex filters fail closed and will not match.
sampleRate must be between 0.0 and 1.0.
0.0disables profiling for that context1.0profiles every matching request or command- values between
0.0and1.0are sampled probabilistically
User resolution runs in this order:
- configured custom resolver from
$userResolver - runtime CodeIgniter Shield detection
- a request-attached
$request->userfallback
Only stable scalar identifiers are recorded.
Set userResolver to either:
- a CodeIgniter service name
- a fully-qualified class name
The resolver must implement Perfbase\CodeIgniter4\Contracts\UserResolverInterface:
namespace App\Support;
use CodeIgniter\HTTP\RequestInterface;
use Perfbase\CodeIgniter4\Contracts\UserResolverInterface;
final class PerfbaseUserResolver implements UserResolverInterface
{
public function resolve(RequestInterface $request): ?string
{
return '123';
}
}Then configure either:
public ?string $userResolver = 'perfbaseUserResolver';or:
public ?string $userResolver = App\Support\PerfbaseUserResolver::class;If Shield is installed and its auth service is available, the package will try to resolve the current user automatically. Shield is optional and is not a hard Composer dependency.
The package fails open by default.
- profiling failures must not break the host application in production
- submission failures are handled internally
- invalid runtime conditions are logged only when configured
- when
debug=true, profiling errors are rethrown to make integration problems visible
Use debug=true only while integrating or diagnosing package behavior.
The package is designed to be safe under FrankenPHP worker mode:
- request and command state is kept only in the active lifecycle registry
- successful, failed, and exceptional flows all clear active lifecycle state
- no request-specific data is cached in the client provider, error handler, or exception service
If you run CodeIgniter under FrankenPHP workers:
- restart workers after changing Perfbase config
- restart workers after changing deployment artifacts
- keep any custom user resolver stateless or request-scoped
The Perfbase PHP extension is not loaded in the PHP runtime executing CodeIgniter. Verify the extension is installed, enabled, and visible to both web and CLI SAPIs.
Run:
php spark perfbase:installIf you manage filters manually, verify that:
- the
perfbasealias exists inapp/Config/Filters.php perfbaseis present in both globalbeforeandafterfilters
Check, in order:
enabledis trueapiKeyis configured- the extension is available
- your request or command is not excluded by filters
sampleRateis not effectively disabling the context
Set:
public bool $debug = true;That makes profiling errors rethrow instead of being swallowed.
composer install
composer run test
composer run phpstan
composer run lintCurrent local verification for this package:
- PHPUnit passing
- PHPStan passing
- coverage at or above the framework guide thresholds
Full documentation is available at perfbase.com/docs.
- Docs: perfbase.com/docs
- Issues: github.com/perfbaseorg/codeigniter4/issues
- Support: support@perfbase.com
Apache-2.0. See LICENSE.txt.