Install XHProf Extension
Ensure the PHP xhprof extension is installed and enabled in your environment.
pecl install xhprof + add extension=xhprof.so to php.inipecl install xhprof or via MacPorts (sudo port install php-xhprof)php -m | grep xhprof.Install the Bundle Add the bundle to your project:
composer require cristiansitov/xhprof-bundle
Or manually clone into src/Jns/Bundle/XhprofBundle.
Enable the Bundle
Register in config/bundles.php:
return [
// ...
Jns\Bundle\XhprofBundle\JnsXhprofBundle::class => ['all' => true],
];
Configure the Bundle
Add to config/packages/xhprof.yaml:
jns_xhprof:
enabled: true
output_dir: '%kernel.project_dir%/var/log/xhprof'
show_in_toolbar: true
First Use Case Trigger profiling in a controller:
use Jns\Bundle\XhprofBundle\Xhprof\Xhprof;
public function indexAction()
{
Xhprof::start('my_profile_session');
// Your code here...
$data = Xhprof::stop('my_profile_session');
return $this->render('...', ['profile_data' => $data]);
}
View results in the Symfony Profiler toolbar or via the generated HTML UI in var/log/xhprof.
Profiling Critical Paths
Use Xhprof::start() at the beginning of long-running actions (e.g., API endpoints, batch jobs) and Xhprof::stop() at the end. Example:
public function processOrderAction()
{
Xhprof::start('order_processing');
$order = $this->orderService->process();
Xhprof::stop('order_processing');
return $this->json($order);
}
Conditional Profiling Enable/disable profiling dynamically based on environment or user role:
if ($this->container->getParameter('kernel.environment') === 'prod') {
Xhprof::start('prod_request');
}
Integration with Symfony Events Profile event listeners or subscribers:
public function onKernelRequest(GetResponseEvent $event)
{
if ($event->isMasterRequest()) {
Xhprof::start('request_' . uniqid());
}
}
Generating Reports Use the built-in HTML UI or extend it to create custom reports:
$profiler = new \Jns\Bundle\XhprofBundle\Xhprof\Profiler();
$profiler->generateReport($data, 'var/log/xhprof/report.html');
show_in_toolbar: true to view profiling data alongside other Symfony profiler panels.Extension Not Loaded
xhprof is enabled in phpinfo() and restart the web server.Permission Issues
output_dir.www-data) has write permissions:
chmod -R 775 var/log/xhprof
chown -R www-data:www-data var/log/xhprof
High Overhead
enabled: false) or use a feature flag:
jns_xhprof:
enabled: '%kernel.debug%'
Memory Limits
memory_limit: 512M) or reduce profiling scope.Symfony Cache Conflicts
debug:config to verify bundle registration.var/log/xhprof for raw JSON files. Use jq to parse:
jq '.' var/log/xhprof/cj_12345.json
APP_DEBUG=true) to catch bundle initialization errors.Profile Specific Routes Use middleware to profile only high-traffic routes:
public function onKernelRequest(Request $event)
{
if (str_starts_with($event->getRequest()->getPathInfo(), '/api')) {
Xhprof::start('api_request');
}
}
Compare Profiles
Use tools like tideways/xhprof to diff profiles across versions.
Extend the Bundle Override the profiler class to add custom logic:
// src/Xhprof/ExtendedProfiler.php
class ExtendedProfiler extends \Jns\Bundle\XhprofBundle\Xhprof\Profiler
{
public function generateReport($data, $outputFile)
{
// Custom logic here...
parent::generateReport($data, $outputFile);
}
}
Register in services.yaml:
Jns\Bundle\XhprofBundle\Xhprof\Profiler: '@app.xhprof.extended_profiler'
Exclude Vendor Code
Filter out profiling data from third-party libraries by modifying the Xhprof service configuration.
Use with Blackfire Combine XHProf with Blackfire for deeper insights (though avoid running both simultaneously).
How can I help you explore Laravel packages today?