Attaching Browser Information to a Symfony2 Request Object


PHP has a function to get the visitors browser information. It will return a lot of information and you can read more about it at php.net/get_browser. In this example I will show you how to set this up in your symfony2 project without the need to edit your php.ini file.

First you need to install garetjax/phpbrowscap

php composer.phar require garetjax/phpbrowscap:dev-master

The above command will install the code needed.

Next up, we want to hook into the kernel.request event so we can add some extra information.

<?php
// src/Acme/AppBundle/EventListener/RequestListener.php
namespace Acme\AppBundle\EventListener;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use phpbrowscap\Browscap;

/**
 * This class will listen for the kernel.request event and add some extra attributes
 * to the request related to the browser.
 */
class RequestListener extends ContainerAware
{

    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * @param GetResponseEvent $event
     */
    public function onKernelRequest(GetResponseEvent $event)
    {
        $bc = new Browscap($this->container->getParameter('kernel.cache_dir'));
        $event->getRequest()->attributes->set('_browser', $bc->getBrowser());
    }
}

Now for the services.xml file

<!-- src/Acme/AppBundle/Resources/config/services.xml -->
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="acme_app.request_listener" class="Acme\AppBundle\EventListener\RequestListener">
            <argument type="service" id="service_container" />
            <tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" />
        </service>
    </services>
</container>

That’s all the code that is required. Now let’s look at an example of how to get the information from the controller.

<?php
// src/Acme/AppBundle/Controller/DefaultController.php
namespace Acme\AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        $browser = $this->getRequest()->attributes->get('_browser');
        die(var_dump($browser));
    }
}

Here’s what it looks like in the profiler.

References and Resources

  • https://github.com/GaretJax/phpbrowscap/wiki/QuickStart
  • http://php.net/get_browser
  • http://symfony.com/doc/master/book/internals.html#kernel-request-event
  • http://symfony.com/doc/master/reference/dic_tags.html#kernel-event-listener