Une version mobile de mon site avec le Zend Framework

Comment détecter qu'un visiteur utilise une tablette ou un téléphone ?

02 octobre 2011

Le but de ce tutoriel est de détecter si un visiteur utilise un appareil mobile et de proposer une version mobile du site.

Quelques définitions

  • layout : Le fichier de mise en page contient principalement les éléments récurrents des pages web afin d'éviter la duplication de code.
  • WURFL : Wireless Universal Resource FiLe est une bibliothèque contenant toutes les caractéristiques des appareils mobiles du marché. Bien qu'elle ne soit pas installée par défaut dans le Zend Framework, elle est indispensable à l'utilisation du composant Zend_Http_UserAgent. Etant donné que le but de ce tutoriel est simplement de détecter si un appareil est mobile, j'ai trouvé un peu lourd d'utiliser WURFL. Néanmoins, si vous préférez cette méthode la documentation du Zend Framework indique comment l'installer. Documentation de Zend_Http_UserAgent.

Détecter si le client est un mobile

Ce qu'il nous faut, vous vous en doutez, c'est une fonction qui détecte les appareils mobiles et renvoie un booléen (true si l'appareil est mobile, false dans le cas contraire). Pour ça il suffit de tester les champs d'en-tête HTTP concernés.

/library/Nico/Plugins/Mobile.php

public static function isMobile()
{
       if (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))
               return true;
       
       if (isset ($_SERVER['HTTP_ACCEPT']))
       {
               $accept = strtolower($_SERVER['HTTP_ACCEPT']);
               if (strpos($accept, 'wap') !== false)
                       return true;
       }
       
       if (isset ($_SERVER['HTTP_USER_AGENT']))
       {
               if (strpos ($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false)
                       return true;
       
               if (strpos ($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false)
                       return true;
       }
       
       return false;
}
	

Pour l'instant je n'ai pas croisé de cas pour lequel cette méthode ne fonctionne pas. Bien sûr si vous trouvez une faille, les commentaires sont là pour ça...

Création d'un plugin de changement de layout

Si vous êtes attentif, vous avez remarqué que le code précédent était situé dans le dossier Plugins de ma bibliothèque personnelle. La modularité est l'une des grandes forces d'un framework et permet au code de garder toute sa souplesse. Nous allons donc créer un plugin qui sera exécuté avant le système de MVC.

Ce plugin doit contenir notre méthode précédente et la méthode preDispatch (je pense que ça fonctionne aussi avec dispatchLoopStartup). La méthode preDispatch imposera un nouveau layout dans le cas ou l'on est en présence d'un appareil mobile.

/library/Nico/Plugins/Mobile.php

class Nico_Plugins_Mobile extends Zend_Controller_Plugin_Abstract 
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
    	$mobile = self::isMobile();
        
        if ($mobile === true)
        	Zend_Layout::getMvcInstance()->setLayout('mobile');
	/* Il faut bien sûr avoir créé mobile.phtml */
    }
    
    public static function isMobile()
	{
       if (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))
               return true;
       
       if (isset ($_SERVER['HTTP_ACCEPT']))
       {
               $accept = strtolower($_SERVER['HTTP_ACCEPT']);
               if (strpos($accept, 'wap') !== false)
                       return true;
       }
       
       if (isset ($_SERVER['HTTP_USER_AGENT']))
       {
               if (strpos ($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false)
                       return true;
       
               if (strpos ($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false)
                       return true;
       }
       
       return false;
	}
}
	

Il faut maintenant faire connaître notre plugin au reste de l'application.

/application/configs/application.ini

resources.frontController.plugins.Mobile = "Nico_Plugins_Mobile"
	

Pour l'instant nous avons une solution qui change le layout et donc l'affichage final. Cette solution fonctionne correctement, mais je suis presque sûr que certaines actions que vous exécutiez dans votre layout habituel ne sont plus utiles avec le layout mobile (par exemple un menu latéral). Il est évident qu'exécuter des actions devenues inutiles c'est le mal absolu de la programmation. Ne connaissant pas l'architecture de votre application je ne peux pas vous aider sur ce point, mais il est important que vous ne le négligiez pas.


Une astuce pour développer votre version mobile : avec Safari allez dans Développement / Agent d'utilisateur. Enjoy


Vous savez maintenant comment réaliser une version mobile de votre site. Si certains d'entre vous l'ont fait d'une autre manière, je serai heureux de partager leur expérience dans les commentaires .

Par
Créateur et administrateur.

Dans la même catégorie

Formater un tableau pour CURLOPT_POSTFIELDS
Email avec pièce jointe en PHP
PHP : modifier les attributs privés d'un objet
Tester l'existence d'un fichier dans l'include path
Convertir récursivement un objet PHP en tableau
PHP : formater un tableau en CSV
Comment envoyer un mail en ligne de commande ?
RSYNC : Comment synchroniser des fichiers à travers une connexion ssh ?
Exécuter un code PHP en ligne de commande
Doctrine 2 : générer les classes PHP depuis la base de données
Comment catcher les erreurs en PHP ?
Doctrine 2 : comment afficher la requête SQL ?
Comment construire une URL sans caractères spéciaux en PHP ?
Comment lister les fichiers PHP inclus sur ma page ?
Les fonctions anonymes récursives en PHP
Requête HTTP asynchrone en PHP
La résolution statique à la volée ou Late Static Bindings
Trouver les jours fériés français en PHP
Comment allumer son ordinateur à distance en PHP ?
Comment utiliser la balise meta viewport ?
Doctrine et le Zend Framework : Présentation, intégration et utilisation
Créer son flux RSS simplement avec Zend_Feed
Appliquer un layout sur un mail avec le Zend Framework
Comment lancer une requête multi-bases avec les fonctions MySQL ?
Implode / Explode : Du tableau à la chaine de caractères, de la chaine de caractères au tableau

Commentaire(s)