Goutte

Goutte is a screen scraping and web crawling library for PHP. Integrating Blackfire with Goutte lets you profile programmatically your websites, HTTP APIs, or web services.

Installation

First, add Blackfire PHP SDK as a dependency on your project and be sure to require Goutte as well:

1
composer require fabpot/goutte

Profiling

Profiling with Goutte is as easy as it can get, add the X-Blackfire-Query HTTP header before doing any HTTP request you want to profile with Blackfire:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
use Goutte\Client as GoutteClient;
use Blackfire\Client as BlackfireClient;

$blackfire = new BlackfireClient();

$client = new GoutteClient();

// as we want to profile the next request, add the Blackfire header
$profileRequest = $blackfire->createRequest('Blog Home');
$client->setHeader('X-Blackfire-Query', $profileRequest->getToken());

$crawler = $client->request('GET', 'https://www.symfony.com/blog/');

// get the profile for the request
$profile = $blackfire->getProfile($profileRequest->getUuid());

$link = $crawler->selectLink('Security Advisories')->link();

// also works before clicking on a link or submitting a form
$client->setHeader('X-Blackfire-Query', $blackfire->createRequest('Security Advisories')->getToken());
$crawler = $client->click($link);

Caution

Never re-use a token for different HTTP requests.

If you execute this script, two profiles will be created on your Blackfire account (tests defined in .blackfire.yml will be executed as well if any).

You can also take several samples of the same page to get more accurate results as done by default by the Blackfire CLI or the Companion:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$blackfire = new BlackfireClient();

// the number of samples to take
$samples = 10;

$config = new \Blackfire\Profile\Configuration();
$config->setSamples($samples);

$client = new GoutteClient();
$config->setTitle('Blog Home');
$profileRequest = $blackfire->createRequest($config);
$client->setHeader('X-Blackfire-Query', $profileRequest->getToken());

// requests the target $samples times
for ($i = 1; $i <= $samples; $i++) {
    $crawler = $client->request('GET', 'https://www.symfony.com/blog/');
}

// get the profile for the request
$profile = $blackfire->getProfile($profileRequest->getUuid());

When running this script, you will get one profile which will be the aggregation of the 10 HTTP requests executed.

Learn more about profiling configuration settings in the PHP SDK documentation.

Builds

Note

This feature is only available to our Premium and Enterprise users.

As Goutte provides great support for HTTP, you can create almost any HTTP request you can think of, but more importantly, you can simulate complex user interactions. Writing scenarios with Goutte is a powerful alternative to the scenarios defined in a .blackfire.yml file.

To generate a report from a scenario created with Goutte, store all profiles in a build:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
use Goutte\Client as GoutteClient;
use Blackfire\Client as BlackfireClient;

$client = new GoutteClient();

$blackfire = new BlackfireClient();

// create a build
$build = $blackfire->createBuild('Symfony Prod', array('title' => 'Build from Goutte'));

// create a configuration
$config = new \Blackfire\Profile\Configuration();
$config->setBuild($build);

// set the Profile and Job name
$config->setTitle('Blog Home');

// make a profiled request
$profileRequest = $blackfire->createRequest($config);
$client->setHeader('X-Blackfire-Query', $profileRequest->getToken());
$crawler = $client->request('GET', 'https://www.symfony.com/blog/');

// get the profile for the request
$profile = $blackfire->getProfile($profileRequest->getUuid());

// click on a link, generate another profile in the build
$link = $crawler->selectLink('Security Advisories')->link();
$config->setTitle('Security Advisories');
$client->setHeader('X-Blackfire-Query', $blackfire->createRequest($config)->getToken());
$crawler = $client->click($link);

// end the build and fetch the report
// the build contains two profiles
$report = $blackfire->endBuild($build);

Note that createRequest() received a Configuration tied to the build.