ostrolucky/polyfill-newrelic
Composer polyfill that defines New Relic PHP agent newrelic_* functions when the New Relic extension isn’t installed. Helps apps run on PHP setups without the extension while keeping calls to the agent API compatible.
Installation Add the package via Composer:
composer require ostrolucky/polyfill-newrelic
No additional configuration is required if using the default autoloader.
First Use Case
Replace direct newrelic_* function calls with the polyfill's static methods. Example:
use OstroLucky\PolyfillNewrelic\NewRelic;
// Instead of:
// newrelic_add_custom_parameters(['key' => 'value']);
// Use:
NewRelic::addCustomParameters(['key' => 'value']);
Where to Look First
OstroLucky\PolyfillNewrelic\NewRelicnewrelic_* functions are mirrored as static methods (e.g., addCustomParameters, setTransactionName, incrementCounter).Conditional Polyfill Usage Use a helper function or service to toggle between the polyfill and native extension:
if (!extension_loaded('newrelic')) {
NewRelic::addCustomParameters($params);
} else {
newrelic_add_custom_parameters($params);
}
Service Provider Binding Bind the polyfill to Laravel's container for dependency injection:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(NewRelic::class, function () {
return new NewRelic();
});
}
Inject NewRelic into controllers/services:
public function __construct(private NewRelic $newRelic) {}
Middleware for Global Metrics Use middleware to auto-instrument requests with New Relic:
// app/Http/Middleware/NewRelicMetrics.php
public function handle($request, Closure $next)
{
$this->newRelic->setTransactionName($request->route()->getName());
return $next($request);
}
Testing Mock the polyfill in tests to avoid dependency on the New Relic extension:
$this->mock(NewRelic::class)->shouldReceive('incrementCounter');
Method Signature Mismatches
Some newrelic_* functions have PHP-specific behaviors (e.g., newrelic_notice_error expects a backtrace). Verify method signatures in the source.
No Extension Features The polyfill does not replicate:
newrelic_set_appname may not persist across requests).Thread Safety
The polyfill is not designed for multi-threaded environments (e.g., Laravel queues with ignore_failure workers). Use native extension if threading is required.
Verify Polyfill Activation
Check if the polyfill is being used by inspecting the NewRelic class methods in your codebase. Native calls will fail silently if the extension is missing.
Logging Fallbacks Add debug logs to confirm polyfill usage:
NewRelic::addCustomParameters(['debug' => true]);
// Log: "Using PolyfillNewRelic for addCustomParameters"
Performance Overhead The polyfill adds minimal overhead, but avoid excessive calls in loops or critical paths. Profile with:
NewRelic::recordCustomMetric('polyfill_overhead', microtime(true));
Custom Polyfill Logic
Extend the NewRelic class to add domain-specific metrics:
class ExtendedNewRelic extends NewRelic
{
public static function trackLaravelEvent(string $event, array $data)
{
self::addCustomParameters(['laravel_event' => [$event => $data]]);
}
}
Configuration
Add a config file (config/polyfill-newrelic.php) to centralize polyfill behavior:
return [
'enabled' => !extension_loaded('newrelic'),
'default_transaction' => 'laravel.default',
];
Fallback to Native Extension Dynamically switch based on config:
$usePolyfill = config('polyfill-newrelic.enabled');
$newRelic = $usePolyfill ? new NewRelic() : null;
How can I help you explore Laravel packages today?