How to detect mobile devices in Symfony 3

How to detect mobile devices in Symfony 3

Nowadays the people use their mobile devices a lot more often than they used to for a simple reason, Internet, that means that your website should be optimized and able to provide an awesome experience for such devices in the same way your website does in the desktop. Although many developers prefer to work with responsive design on their websites to optimize SEO and other reasons, there are other developers that works with subdomains for the same version of the website however optimized for different devices (e.g www.t.yourweb.com for tablet or www.m.yourweb.com for phones). The difference between the responsive design is that you don't need to mess with things on your server like creating new domains and configuring them correctly but just change the source code, however if you decide to work with subdomain you need to mess with both (source code to detected wheter the visitor uses a mobile device or a desktop computer and then configure the domains).

On a Symfony project, this task is pretty easier if you use the right tool. In order to detect the platform that uses your visitor to see your website, we recommend you to use the Mobile Detect Bundle. This bundle relies on the Mobile Detect project. Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets). It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.

In this article you will learn how to install and implement the Mobile Detect Bundle in your Symfony 3 project.

1. Install MobileDetectBundle

MobileDetectBundle is a Symfony compatible 2.4.x and 3.0.x bundle for detect mobile devices, manage mobile view and redirect to the mobile and tablet version. It provides the following features:

  • Detect the various mobile devices by Name, OS, browser User-Agent.
  • Manages site views for the various mobile devices (mobile, tablet, full).
  • Redirects to mobile and tablet sites.

To install this bundle in your project open a new terminal, switch to the directory of your project and run the following composer command:

composer require suncat/mobile-detect-bundle

Alternatively you can modify your composer.json file and add the library manually as a dependency:

{
    "require": {
        "suncat/mobile-detect-bundle": "^1.0"
    },
}

Then run composer install on the directory. Once the installation of the library via composer finishes, proceed to enable the bundle in your AppKernel.php:

<?php
    
public function registerBundles()
{
    $bundles = [
        // ...
        // Enable MobileDetectBundle
        new SunCat\MobileDetectBundle\MobileDetectBundle(),
        // ...
    ];

    // ... //
}

Clear the cache of your project and you will be ready to use the library on your project. If you need more information about this bundle, please visit the official repository in Github here.

2. Using Mobile Detect Bundle manually from controllers and views

The first and most useful thing on this bundle is that you can use separately many of the functions that it offers without effort and you don't need to create custom Twig functions to verify wheter an user navigates from an Android Device or other explorers from your views. This comes in handy when you want to display certain ads to your user according to the platform they visit.

Check for type of device generally

In most of the cases, you will only need to check wheter your user is navigating from a mobile device, tablet or a desktop computer. You can achieve easily with a conditional statement according to the result of methods like isTablet or isMobile:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        // Retrieve the mobile detector service
        $mobileDetector = $this->get('mobile_detect.mobile_detector');
        
        // Create a flag string to returns as response
        $responseText = "Another kind of device";

        // Verify from the controller if is a tablet
        if($mobileDetector->isTablet()){
            $responseText = "You're using a tablet, our system works only in Desktop computers";

        // Verify if it's a mobile device (tablet is a mobile device too)
        }else if($mobileDetector->isMobile()){
            $responseText = "You're using a mobile device, our system works only in Desktop computers";
        }
        
        return new Response($responseText);
    }
}

In other cases, you won't need to check this information from your controllers but on your views using Twig. Fortunately, with this bundle you won't need to expose custom functions to Twig as it already offers custom functions ready to use in your views:

{% extends 'base.html.twig' %}

{% block body %}
    {% if is_mobile() %}
        {# Tablets are mobile devices too #}
        <h1>Is a Mobile device</h1>
    {% endif %}

    {% if is_tablet() %}
        <h1>Is a Tablet</h1>
    {% endif %}
{% endblock %}

In this way you can verify more complex device patterns or send certain information according to the platform without need to redirect to another website.

Checking for operative system

You can check which operative system is currently using your user by using the is* (where the wildcard is the operative system identifier) function:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        // Retrieve the mobile detector service
        $mobileDetector = $this->get('mobile_detect.mobile_detector');
        
        // Check for different mobile operative systems
        // They return a boolean (true if match)
        $mobileDetector->isAndroidOS();
        $mobileDetector->isBlackBerryOS();
        $mobileDetector->isPalmOS();
        $mobileDetector->isSymbianOS();
        $mobileDetector->isWindowsMobileOS();
        $mobileDetector->isiOS();
        $mobileDetector->isbadaOS();

        return new Response("Some response text");
    }
}

In the same way, you can use those functions in Twig (Only iOS and Android):

{% extends 'base.html.twig' %}

{% block body %}

    {% if is_android_os() %}
        <h1>Android</h1>
    {% endif %}

    {% if is_ios() %}
        <h1>iOS</h1>
    {% endif %}

{% endblock %}

Check for mobile browser User-Agent

You can check what kind of browser is using your visitor in your controller:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; 

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        $mobileDetector = $this->get('mobile_detect.mobile_detector');

        /*
         * Returns a boolean (true in case the browser matches)
         */
        $mobileDetector->isChrome();
        $mobileDetector->isSafari();
        $mobileDetector->isDolfin();
        $mobileDetector->isOpera();
        $mobileDetector->isSkyfire();
        $mobileDetector->isIE();
        $mobileDetector->isFirefox();
        $mobileDetector->isBolt();
        $mobileDetector->isTeaShark();
        $mobileDetector->isBlazer();
        $mobileDetector->isSafari();
        $mobileDetector->isMidori();
        $mobileDetector->isGenericBrowser();

        return new Response("");
    }
}

3. Configuring Mobile Detect Bundle automatically

This step can be a little bit messy and tricky. If you use instead multiple domains for your website for mobile devices and desktop, then you can configure your main project to redirect to another URL or even use the same Symfony project for the same website but located on different domain.

To achieve this, follow these steps:

1. Configure redirection in your config.yml

As first step, you want to redirect the users that visit your website (www.yourweb.com) from a mobile device to the mobile domain instead (www.m.yourweb.com) by adding the proper configuration in your config.yml. The following snippet will simply redirect all the users that visit your website from mobile devices (tablets and phones) to the mobile domain:

mobile_detect:
    redirect:
        mobile:
            is_enabled: true
            host: http://m.ourcodeworld.com
            status_code: 301
            action: redirect
        tablet: ~
    switch_device_view: ~

Note that this is just an example, you can even redirect to a tablet domain. Read the full configuration area in the documentation for more information.

2. Create a new app file

As you know, in production the file app.php located in yourapp/web is the entry point of your application. In order to create the mobile entry for your application, copy the app.php file and paste it into the same directory with the new name app_mobile.php. Now search for the following line (around the 9th line):

$kernel = new AppKernel('prod', false);

This line specifies the type of (there are 2 app files originally app.php and app_dev.php) environment that should be used for your app. Now in the copied file (app_mobile.php) modify the environment from prod to mobile:

$kernel = new AppKernel('mobile', false);

Save the changes on the file and proceed with the next step.

3. Create the new config file

Now create a new config_mobile.yml file in yourapp/app/config folder and add the following content inside:

imports:
    - { resource: parameters.yml }

framework:
    secret: "%secret%"
    router:
        resource: "%kernel.root_dir%/config/routing_mobile.yml"

mobile_detect:
    redirect:
        mobile:
            is_enabled: false
        tablet: ~
        full:
            is_enabled: true
            host: http://ourcodeworld.com
    switch_device_view: ~

What we're doing is create a custom configuration file with the most basic settings, framework and mobile_detect. In the mobile_detect area we'll indicate that if someone visits the mobile website from the mobile, it should be redirected to the desktop version (full) and the mobile version will be disabled on the redirect action.

4. Configure your mobile domain to target the app_mobile.php file

The final step is up to you and it will vary according to your server. You need to specify that your mobile domain (www.m.yourweb.com) targets to the app_mobile.php file instead of the app.php file. After you have restarted your http server everything should work. Also remember to clear the cache if you do changes to configs or you might end to get frustrated for nothing.

Happy coding !

Become a more social person