Capturing Named Arguments in PHP

By Jérôme Vieilledent, on May 31, 2021

Arguments Capturing is one of the most powerful features in Blackfire Profiler. It enables you to control how the call-graph is rendered, depending on functions arguments values. As an example, thanks to this feature SQL queries are extracted from your application, since these are actual arguments passed to e.g. PDOStatement::execute().

Capturing Arguments

Let’s consider the following example:

<?php

function soup(string $vegetable, string $spice = 'no spice', string $cheese = 'no cheese', array $extra = []): string {
    // Let's introduce a performance issue on purpose...
    usleep(1000);

    $recipe = "Making soup with $vegetable, $spice and $cheese";
    foreach ($extra as $level => $ingredients) {
        foreach ($ingredients as $ingredient) {
            $recipe .= " +$ingredient ($level)";
        }
    }

    return "$recipe\n";
}

echo soup('carrot', 'no spice', 'kiri');
echo soup('cucumber', 'mint');
echo soup('onion', 'no spice', 'gruyere', [
    'required' => ['bread'],
    'optional' => ['wine'],
]);

Profiling this tiny script without using Argument Capturing, the 3 calls to the soup() function are aggregated to a single node:

You can enable Argument Capturing by defining a metric:

# .blackfire.yaml
metrics:
    soup:
        label: My Yummy Soup
        matching_calls:
            php:
                - callee:
                    selector: '=soup'
                    argument:
                        1: '*'
                        2: '*'

With this metric, the call-graph renders separate nodes per combination of arguments passed to the soup() function.

Note that the metric above is using 1-indexed positional arguments.

Named Arguments

As you may be aware, PHP 8.0 introduced the possibility to use named arguments, providing more flexibility when calling functions, and dealing with default values.

Well, the good news is that as of version 1.56 of the Probe, Blackfire Profiler now supports named arguments in PHP!

Let’s update our example:

<?php

// Now let's call our soup() function using named arguments!
echo soup('carrot', cheese: 'kiri');
echo soup(spice: 'mint', vegetable: 'cucumber');
echo soup(cheese: 'gruyere', vegetable: 'onion', extra: [
    'required' => ['bread'],
    'optional' => ['wine'],
]);
# .blackfire.yaml
metrics:
    soup:
        label: My Yummy Soup
        matching_calls:
            php:
                - callee:
                    selector: '=soup'
                    argument:
                    	# Now using named arguments!
                        vegetable: '*'
                        spice: '*'

Icing On The Cake

If you don’t call all your functions with named arguments, that’s OK too! You may use the same syntax to capture the functions’ arguments 😉.

Oh, and one more thing: even though you are not running on PHP 8 yet, you can still use named arguments capturing with PHP 7! How cool is that!?

Give Blackfire a try!

Metrics and arguments capturing are available for all paid plans (Profiler, Premium, and Enterprise plans). Play with the demo or subscribe now!

Happy Profiling!

Jérôme Vieilledent

As a Developer Advocate, Jérôme is all about spreading the love! His technical/development background enable him to talk as a peer to peers with our developer users. You’ll read his tips and advices on performance management with Blackfire. And he’ll support you as a day-to-day user.