web-dev-qa-db-fra.com

Comment inclure une classe/instance sans utiliser de variables globales

Je voudrais ajouter http://mobiledetect.net/ class à mon modèle. Quelle est la meilleure approche pour utiliser cette classe de manière dynamique dans chaque partie de mon modèle?

Pour le moment je viens de charger la classe dans functions.php comme ceci

    function devicecontrol() {
    require_once '_/inc/md/Mobile_Detect.php';
}
add_action('wp_loaded', 'devicecontrol', '1');

mais pour l'utiliser, je dois d'abord créer une instance dans chaque modèle de page

$detect = new Mobile_Detect;

Je sais que les variables globales ne sont pas une bonne solution. Quelle est donc la meilleure approche pour inclure de telles classes?

1
Andrea Puiatti

les variables globales ne sont pas une bonne solution

Oui, j'ai souvent entendu cette phrase, mais comme vous l'avez constaté, il est parfois nécessaire d'accéder à certaines variables partout.

Certains PHP frameworks modernes implémentent des modèles avancés tels que IOC qui aident dans ce type de choses, mais wordpress en manque, et c'est la raison pour laquelle WP utilise beaucoup de variables globales.

De manière générale, en PHP, les solutions sont les suivantes:

  1. Sigleton . Beaucoup de codeurs (spécialement ceux issus de langages autres que PHP) disent que singleton est nul car ils sont une sorte demasked/ globals. À mon avis, lorsque vous ne pouvez pas compter sur une implémentation d'IOC, les singleton sont meilleurs que les globals "purs", mais pour des tâches simples, il n'est pas nécessaire d'implémenter ce modèle.
  2. Globales. Dans PHP, les mots-clés global permettent aux vars globaux de sentir un peu moins. Si vous faites un usage réfléchi, les globals ne sont pas si nuls. Par exemple. les utiliser à l'intérieur des fonctions n'est pas une très mauvaise solution.

Strictement lié à votre cas, une méthode statique suffira comme alternative aux globals, si vous les détestez.

class MyDetect {

  static $detect = NULL;
  static $deviceType = NULL;

  static function detect() {
    if ( is_null(self::$detect) ) {
      require_once '_/inc/md/Mobile_Detect.php';
      self::$detect = new Mobile_Detect;
      self::$deviceType = ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'phone') : 'computer'); 
    }
  }

}

Exigez le fichier contenant la classe dans votre plugin, puis

add_action('wp_loaded', array('MyDetect', 'detect') );

et lorsque vous avez besoin de la variable $detect (instance de détection de mobile), utilisez MyDetect::$detect et lorsque vous avez besoin de la variable $deviceType, utilisez MyDetect::$devicType

Edit: un exemple d'utilisation

function add_mobile_scripts() {
   wp_enqueue_script('my_script_for_mobiles', 'the_script_url_here' );
}

function add_phone_scripts() {
   wp_enqueue_script('my_script_for_phones', 'the_script_url_here' );
}

function add_tablet_scripts() {
   wp_enqueue_script('my_script_for_tablets', 'the_script_url_here' );
}

function add_desktop_scripts() {
   wp_enqueue_script('my_script_for_desktops', 'the_script_url_here' );
}

function addDevicesScripts() { 
  if ( MyDetect::$deviceType == 'phone' || MyDetect::$detect == 'tablet' ) {
    add_mobile_scripts();
    if ( MyDetect::$deviceType=='phone' ) {
      add_phone_scripts();
    } else {
      add_tablet_scripts();
    }  
  } else {
     add_desktop_scripts();
  }
}

add_action( 'wp_enqueue_scripts', 'addDevicesScripts' );
4
gmazzap