Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • SensioLabs Professional services to help you with Symfony
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. Documentation
  3. The BrowserKit Component
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • Installation
  • Basic Usage
    • Creating a Client
    • Making Requests
    • Clicking Links
    • Submitting Forms
  • Cookies
    • Retrieving Cookies
    • Looping Through Cookies
    • Setting Cookies
  • History
  • Making External HTTP Requests
    • Dealing with HTTP responses
  • Learn more

The BrowserKit Component

Edit this page

Warning: You are browsing the documentation for Symfony 4.4, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

The BrowserKit Component

The BrowserKit component simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically.

Note

In Symfony versions prior to 4.3, the BrowserKit component could only make internal requests to your application. Starting from Symfony 4.3, this component can also make HTTP requests to any public site when using it in combination with the HttpClient component.

Installation

1
$ composer require symfony/browser-kit

Note

If you install this component outside of a Symfony application, you must require the vendor/autoload.php file in your code to enable the class autoloading mechanism provided by Composer. Read this article for more details.

Basic Usage

See also

This article explains how to use the BrowserKit features as an independent component in any PHP application. Read the Symfony Functional Tests article to learn about how to use it in Symfony applications.

Creating a Client

The component only provides an abstract client and does not provide any backend ready to use for the HTTP layer. To create your own client, you must extend the AbstractBrowser class and implement the doRequest() method.

4.3

In Symfony 4.3 and earlier versions, the AbstractBrowser class was called Client (which is now deprecated).

The doRequest() method accepts a request and should return a response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace Acme;

use Symfony\Component\BrowserKit\AbstractBrowser;
use Symfony\Component\BrowserKit\Response;

class Client extends AbstractBrowser
{
    protected function doRequest($request)
    {
        // ... convert request into a response

        return new Response($content, $status, $headers);
    }
}

For a simple implementation of a browser based on the HTTP layer, have a look at the HttpBrowser provided by this component. For an implementation based on HttpKernelInterface, have a look at the Client provided by the HttpKernel component.

Making Requests

Use the request() method to make HTTP requests. The first two arguments are the HTTP method and the requested URL:

1
2
3
4
use Acme\Client;

$client = new Client();
$crawler = $client->request('GET', '/');

The value returned by the request() method is an instance of the Crawler class, provided by the DomCrawler component, which allows accessing and traversing HTML elements programmatically.

The xmlHttpRequest() method, which defines the same arguments as the request() method, is a shortcut to make AJAX requests:

1
2
3
4
5
use Acme\Client;

$client = new Client();
// the required HTTP_X_REQUESTED_WITH header is added automatically
$crawler = $client->xmlHttpRequest('GET', '/');

Clicking Links

The AbstractBrowser is capable of simulating link clicks. Pass the text content of the link and the client will perform the needed HTTP GET request to simulate the link click:

1
2
3
4
5
6
use Acme\Client;

$client = new Client();
$client->request('GET', '/product/123');

$crawler = $client->clickLink('Go elsewhere...');

If you need the Link object that provides access to the link properties (e.g. $link->getMethod(), $link->getUri()), use this other method:

1
2
3
4
// ...
$crawler = $client->request('GET', '/product/123');
$link = $crawler->selectLink('Go elsewhere...')->link();
$client->click($link);

Submitting Forms

The AbstractBrowser is also capable of submitting forms. First, select the form using any of its buttons and then override any of its properties (method, field values, etc.) before submitting it:

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
use Acme\Client;

$client = new Client();
$crawler = $client->request('GET', 'https://github.com/login');

// find the form with the 'Log in' button and submit it
// 'Log in' can be the text content, id, value or name of a <button> or <input type="submit">
$client->submitForm('Log in');

// the second optional argument lets you override the default form field values
$client->submitForm('Log in', [
    'login' => 'my_user',
    'password' => 'my_pass',
    // to upload a file, the value must be the absolute file path
    'file' => __FILE__,
]);

// you can override other form options too
$client->submitForm(
    'Log in',
    ['login' => 'my_user', 'password' => 'my_pass'],
    // override the default form HTTP method
    'PUT',
    // override some $_SERVER parameters (e.g. HTTP headers)
    ['HTTP_ACCEPT_LANGUAGE' => 'es']
);

If you need the Form object that provides access to the form properties (e.g. $form->getUri(), $form->getValues(), $form->getFields()), use this other method:

1
2
3
4
5
6
7
8
9
// ...

// select the form and fill in some values
$form = $crawler->selectButton('Log in')->form();
$form['login'] = 'symfonyfan';
$form['password'] = 'anypass';

// submit that form
$crawler = $client->submit($form);

Cookies

Retrieving Cookies

The AbstractBrowser implementation exposes cookies (if any) through a CookieJar, which allows you to store and retrieve any cookie while making requests with the client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
use Acme\Client;

// Make a request
$client = new Client();
$crawler = $client->request('GET', '/');

// Get the cookie Jar
$cookieJar = $client->getCookieJar();

// Get a cookie by name
$cookie = $cookieJar->get('name_of_the_cookie');

// Get cookie data
$name       = $cookie->getName();
$value      = $cookie->getValue();
$rawValue   = $cookie->getRawValue();
$isSecure   = $cookie->isSecure();
$isHttpOnly = $cookie->isHttpOnly();
$isExpired  = $cookie->isExpired();
$expires    = $cookie->getExpiresTime();
$path       = $cookie->getPath();
$domain     = $cookie->getDomain();
$sameSite   = $cookie->getSameSite();

Note

These methods only return cookies that have not expired.

Looping Through Cookies

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
use Acme\Client;

// Make a request
$client = new Client();
$crawler = $client->request('GET', '/');

// Get the cookie Jar
$cookieJar = $client->getCookieJar();

// Get array with all cookies
$cookies = $cookieJar->all();
foreach ($cookies as $cookie) {
    // ...
}

// Get all values
$values = $cookieJar->allValues('http://symfony.com');
foreach ($values as $value) {
    // ...
}

// Get all raw values
$rawValues = $cookieJar->allRawValues('http://symfony.com');
foreach ($rawValues as $rawValue) {
    // ...
}

Setting Cookies

You can also create cookies and add them to a cookie jar that can be injected into the client constructor:

1
2
3
4
5
6
7
8
9
10
use Acme\Client;

// create cookies and add to cookie jar
$cookie = new Cookie('flavor', 'chocolate', strtotime('+1 day'));
$cookieJar = new CookieJar();
$cookieJar->set($cookie);

// create a client and set the cookies
$client = new Client([], null, $cookieJar);
// ...

History

The client stores all your requests allowing you to go back and forward in your history:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Acme\Client;

$client = new Client();
$client->request('GET', '/');

// select and click on a link
$link = $crawler->selectLink('Documentation')->link();
$client->click($link);

// go back to home page
$crawler = $client->back();

// go forward to documentation page
$crawler = $client->forward();

You can delete the client's history with the restart() method. This will also delete all the cookies:

1
2
3
4
5
6
7
use Acme\Client;

$client = new Client();
$client->request('GET', '/');

// reset the client (history and cookies are cleared too)
$client->restart();

Making External HTTP Requests

So far, all the examples in this article have assumed that you are making internal requests to your own application. However, you can run the exact same examples when making HTTP requests to external web sites and applications.

First, install and configure the HttpClient component. Then, use the HttpBrowser to create the client that will make the external HTTP requests:

1
2
3
4
use Symfony\Component\BrowserKit\HttpBrowser;
use Symfony\Component\HttpClient\HttpClient;

$browser = new HttpBrowser(HttpClient::create());

You can now use any of the methods shown in this article to extract information, click links, submit forms, etc. This means that you no longer need to use a dedicated web crawler or scraper such as Goutte:

1
2
3
4
5
6
7
8
$browser = new HttpBrowser(HttpClient::create());

$browser->request('GET', 'https://github.com');
$browser->clickLink('Sign in');
$browser->submitForm('Sign in', ['login' => '...', 'password' => '...']);
$openPullRequests = trim($browser->clickLink('Pull requests')->filter(
    '.table-list-header-toggle a:nth-child(1)'
)->text());

Tip

You can also use HTTP client options like ciphers, auth_basic and query. They have to be passed as the default options argument to the client which is used by the HTTP browser.

4.3

The feature to make external HTTP requests was introduced in Symfony 4.3.

Dealing with HTTP responses

When using the BrowserKit component, you may need to deal with responses of the requests you made. To do so, call the getResponse() method of the HttpBrowser object. This method returns the last response the browser received:

1
2
3
4
$browser = new HttpBrowser(HttpClient::create());

$browser->request('GET', 'https://foo.com');
$response = $browser->getResponse();

Learn more

  • Testing
  • The CssSelector Component
  • The DomCrawler Component
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:
    Be safe against critical risks to your projects and businesses

    Be safe against critical risks to your projects and businesses

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of Brian, a Symfony contributor

    Thanks Brian for being a Symfony contributor

    1 commit • 7 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony

    Search by Algolia