Le meilleur moyen d'initier une classe dans un plugin WP?

90

J'ai créé un plugin, et bien sûr, étant moi-même, je voulais utiliser une approche OO agréable. Maintenant, ce que j'ai fait est de créer cette classe puis juste en dessous de créer une instance de cette classe:

class ClassName {

    public function __construct(){

    }
}

$class_instance = new ClassName();  

Je suppose qu'il y a plus de moyens de faire en sorte que cette classe soit initiée par un groupe de travail, puis j'ai rencontré des personnes disant qu'elles préféraient une init()fonction à une __construct()autre. Et de même, j'ai trouvé quelques personnes utilisant le crochet suivant:

class ClassName {

    public function init(){

    }
}
add_action( 'load-plugins.php', array( 'ClassName', 'init' ) );

Qu'est-ce qui est généralement considéré comme le meilleur moyen de créer une instance de classe WP lors du chargement et de la considérer comme une variable accessible de manière globale?

NOTE: En tant que point intéressant, j'ai remarqué que, même s'il register_activation_hook()peut être appelé de l'intérieur __construct, il ne peut pas être appelé de l'intérieur init()du deuxième exemple. Peut-être que quelqu'un pourrait m'éclairer sur ce point.

Edit: Merci pour toutes les réponses, il y a clairement pas mal de débats sur la manière de gérer l'initialisation au sein de la classe elle-même, mais je pense qu'il y a généralement un très bon consensus qui add_action( 'plugins_loaded', ...);est le meilleur moyen de commencer réellement ...

Edit: Juste pour confondre les choses, j’ai aussi vu cela utilisé (bien que je n’utiliserais pas cette méthode moi-même, car transformer une classe OO en fonction semble contrecarrer son objectif):

// Start up this plugin
add_action( 'init', 'ClassName' );
function ClassName() {
    global $class_name;
    $class_name = new ClassName();
}
Kalpaitch
la source
1
En ce qui concerne la dernière édition, si elle est contenue dans le même fichier de plugin que la classe, cela devient quelque peu inutile. Vous pouvez aussi instancier la classe selon la méthode que je décris. Même si cela se trouve dans un fichier séparé, cela reste un peu inutile. Le seul cas d'utilisation que je puisse voir est si vous souhaitez créer une fonction d'encapsuleur qui vous permet d'instancier une classe en dehors de vos fichiers de plug-in, dans des thèmes, etc. Néanmoins, je devrais demander quelle logique sous-tendait cela, car une utilisation appropriée des conditionnels et des hooks devrait permettre un contrôle précis du grain lors de l'instanciation, ce qui vous permettrait de vous concentrer sur l'utilisation du plug-in.
Adam
Je suis plutôt d’accord avec ça, mais j’ai pensé que ça valait la peine de le mettre car je l’ai trouvé dans quelques plugins WP.
Kalpaitch

Réponses:

60

Bonne question, il existe un certain nombre d'approches et cela dépend de ce que vous voulez réaliser.

Je fais souvent;

add_action( 'plugins_loaded', array( 'someClassy', 'init' ));

class someClassy {

    public static function init() {
        $class = __CLASS__;
        new $class;
    }

    public function __construct() {
           //construct what you see fit here...
    }

    //etc...
}

Un exemple plus complet, approfondi, résultant de discussions récentes sur ce sujet dans la salle de discussion, peut être vu ici par le membre du WPSE, toscho .

L'approche constructeur vide.

Voici un extrait des avantages / inconvénients tirés de l’essentiel ci-dessus, qui illustre parfaitement l’approche constructeur vide.

  • Avantages:

    • Les tests unitaires peuvent créer de nouvelles instances sans activer aucun hook automatiquement. Pas de Singleton.

    • Aucune variable globale nécessaire.

    • Quiconque veut travailler avec l'instance du plugin peut simplement appeler T5_Plugin_Class_Demo :: get_instance ().

    • Facile à désactiver.

    • OO toujours réel: aucune méthode de travail n'est statique.

  • Désavantage:

    • Peut-être plus difficile à lire?

À mon avis, l’inconvénient est faible, c’est pourquoi il faudrait que ce soit mon approche privilégiée, même si ce n’est pas la seule que j’utilise. En fait, plusieurs autres poids lourds vont sans aucun doute entrer dans le vif du sujet, car ils le feront sous peu car il y a de bonnes opinions sur ce sujet qui méritent d'être exprimées.


Remarque: je dois trouver l’essentiel de l’exemple de toscho qui a comparé 3 ou 4 comparaisons sur la façon d’instancier une classe dans un plugin qui examine les avantages et les inconvénients de chaque classe. les autres exemples contrastent bien avec ce sujet. Espérons que toscho l’a toujours dans son dossier.

Remarque: La réponse WPSE à ce sujet avec des exemples et des comparaisons pertinents. Aussi la meilleure solution par exemple une classe dans WordPress.

add_shortcode( 'baztag', array( My_Plugin::get_instance(), 'foo' ) );
class My_Plugin {

    private $var = 'foo';

    protected static $instance = NULL;

    public static function get_instance() {

        // create an object
        NULL === self::$instance and self::$instance = new self;

        return self::$instance; // return the object
    }

    public function foo() {

        return $this->var; // never echo or print in a shortcode!
    }
}
Adam
la source
quelle serait la différence entre add_action ('plugins_loaded', ...); et add_action ('load-plugins.php', ...); L'exemple que j'ai pris utilisait ce dernier
kalpaitch
1
D'après ce que je comprends, load-plugins.php, bien que cela fonctionne, est associé au update.phpfichier core et ne fait pas partie des actions par défaut habituelles sur lesquelles il convient de s'appuyer lorsqu'il est question de la séquence d'événements qui se déclenchent lors de l'initialisation. C'est pourquoi je préfère d'utiliser les crochets qui s'appliquent, dans ce cas plugins_loaded. C’est ce que j’appelle souvent un instantané rapide de ce qui se passe lorsque Action Reference . Mon explication n'est pas complète dans son intégralité.
Adam
4
J'aime cette approche singleton. Cependant, je pose la question de l’utilisation de plugins_loaded en tant que votre crochet d’initialisation. Ce hook est destiné à être exécuté après le chargement de tous les plugins. Si vous vous connectez après cela, vous détournerez ce crochet et risquerez de vous amuser dans des conflits ou des problèmes de séquence de démarrage avec d'autres plugins ou thèmes liés à plugins_loaded. Je n'accepterais aucune action pour exécuter votre méthode d'initialisation. L'architecture du plugin a été conçue pour s'exécuter en ligne, pas sur une action.
Tom Auger
2
Notez que si vous utilisez, register_activation_hook()vous devez appeler cette fonction avant que l’ plugins_loadedaction ne soit déclenchée.
Geert
1
Comme information supplémentaire, voir ce post de @mikeschinkel et la discussion dans les commentaires. hardcorewp.com/2012/…
bueltge le
79

En arrivant ici exactement 2 ans après que la question initiale a été posée, il y a quelques points que je voudrais souligner. (Ne me demandez pas de souligner beaucoup de choses , jamais).

Crochet approprié

Pour instancier une classe de plug-in, le hook approprié doit être utilisé. Il n’ya pas de règle générale, car cela dépend de ce que fait la classe.

Utiliser un hook très précoce comme "plugins_loaded"souvent n'a pas de sens car un tel hook est déclenché pour les requêtes admin, frontend et AJAX, mais très souvent, un hook plus récent est bien meilleur car il permet d'instancier les classes de plug-in uniquement lorsque cela est nécessaire.

Par exemple, une classe qui fait des choses pour les modèles peut être instanciée "template_redirect".

De manière générale, il est très rare qu'une classe ait besoin d'être instanciée avant "wp_loaded"d'être renvoyée.

Aucune classe de Dieu

La plupart des classes utilisées comme exemples dans les réponses plus anciennes utilisent une classe nommée comme "Prefix_Example_Plugin"ou "My_Plugin"... Cela indique qu'il existe probablement une classe principale pour le plugin.

Bien, à moins qu'un plugin ne soit créé par une seule classe (auquel cas le nommer après le nom du plugin est absolument raisonnable), pour créer une classe qui gère l'intégralité du plugin (par exemple, ajouter tous les points d'ancrage dont un plugin a besoin ou instancier toutes les autres classes du plugin. ) peut être considéré comme une mauvaise pratique, à titre d'exemple d' objet divin .

Dans le code de programmation orienté objet, le code devrait avoir tendance à être SOLID, le "S" signifiant "Principe de responsabilité unique" .

Cela signifie que chaque classe devrait faire une seule chose. Dans le développement de plugins WordPress, cela signifie que les développeurs devraient éviter d'utiliser un seul hook pour instancier une classe de plugin principale , mais différents hooks doivent être utilisés pour instancier différentes classes, en fonction de la responsabilité de la classe.

Éviter les crochets dans le constructeur

Cet argument a été introduit dans d'autres réponses ici, cependant, je voudrais faire remarquer ce concept et lier cette autre réponse là où il a été assez largement expliqué dans le domaine des tests unitaires.

Presque 2015: PHP 5.2 est pour les zombies

Depuis le 14 août 2014, PHP 5.3 est arrivé en fin de vie . C'est définitivement mort. PHP 5.4 sera supporté pour tout 2015, cela signifie pour une autre année au moment où j'écris.

Cependant, WordPress supporte toujours PHP 5.2, mais personne ne devrait écrire une seule ligne de code prenant en charge cette version, en particulier si le code est OOP.

Il y a différentes raisons:

  • PHP 5.2 est mort depuis longtemps, aucun correctif de sécurité n'a été publié, ce qui signifie qu'il n'est pas sécurisé.
  • PHP 5.3 a ajouté de nombreuses fonctionnalités à PHP, des fonctions anonymes et des espaces de noms über alles
  • les nouvelles versions de PHP sont beaucoup plus rapides . PHP est gratuit. La mise à jour est gratuite. Pourquoi utiliser une version plus lente et peu sûre si vous pouvez en utiliser une gratuitement plus rapide et plus sécurisée?

Si vous ne voulez pas utiliser le code PHP 5.4+, utilisez au moins 5.3+

Exemple

À ce stade, il est temps de passer en revue les réponses précédentes en fonction de ce que j’avais dit jusqu’ici.

Une fois que nous n’avons plus à nous soucier de la version 5.2, nous pouvons et devrions utiliser des espaces de noms.

Afin de mieux expliquer le principe de responsabilité unique, mon exemple utilisera 3 classes, une qui fait quelque chose sur le frontend, une sur le backend et une troisième utilisée dans les deux cas.

Classe Admin:

namespace GM\WPSE\Example;

class AdminStuff {

   private $tools;

   function __construct( ToolsInterface $tools ) {
     $this->tools = $tools;
   }

   function setup() {
      // setup class, maybe add hooks
   }

}

Classe frontend:

namespace GM\WPSE\Example;

class FrontStuff {

   private $tools;

   function __construct( ToolsInterface $tools ) {
     $this->tools = $tools;
   }

   function setup() {
      // setup class, maybe add hooks
   }

}

Interface des outils:

namespace GM\WPSE\Example;

interface ToolsInterface {

   function doSomething();

}

Et une classe Tools, utilisée par les deux autres:

namespace GM\WPSE\Example;

class Tools implements ToolsInterface {

   function doSomething() {
      return 'done';
   }

}

Ayant ces classes, je peux les instancier avec les hooks appropriés. Quelque chose comme:

require_once plugin_dir_path( __FILE__ ) . 'src/ToolsInterface.php';
require_once plugin_dir_path( __FILE__ ) . 'src/Tools.php';

add_action( 'admin_init', function() {

   require_once plugin_dir_path( __FILE__ ) . 'src/AdminStuff.php';
   $tools = new GM\WPSE\Example\Tools;
   global $admin_stuff; // this is not ideal, reason is explained below
   $admin_stuff = new GM\WPSE\Example\AdminStuff( $tools ); 
} );

add_action( 'template_redirect', function() {

   require_once plugin_dir_path( __FILE__ ) . 'src/FrontStuff.php';
   $tools = new GM\WPSE\Example\Tools;
   global $front_stuff; // this is not ideal, reason is explained below
   $front_stuff = new GM\WPSE\Example\FrontStuff( $tools );    
} );

Inversion de dépendance et injection de dépendance

Dans l'exemple ci-dessus, j'ai utilisé des espaces de noms et des fonctions anonymes pour instancier différentes classes à différents hooks, mettant en pratique ce que j'ai dit ci-dessus.

Notez comment les espaces de noms permettent de créer des classes nommées sans préfixe.

J'ai appliqué un autre concept qui a été indirectement mentionné ci-dessus: Injection de dépendance , c'est une méthode pour appliquer le principe d'inversion de dépendance , le "D" dans l'acronyme SOLID.

La Toolsclasse est "injectée" dans les deux autres classes lorsqu'elles sont instanciées, ce qui permet de séparer les responsabilités.

De plus, AdminStuffet les FrontStuffclasses utilisent le type hinting de déclarer qu'ils ont besoin d' une classe qui implémente ToolsInterface.

De cette manière, nous ou les utilisateurs de notre code pouvons utiliser différentes implémentations de la même interface, ce qui fait que notre code n'est pas couplé à une classe concrète mais à une abstraction: c'est exactement ce que dit le principe d'inversion de dépendance.

Cependant, l'exemple ci-dessus peut être encore amélioré. Voyons comment.

Autochargeur

Un bon moyen d'écrire du code POO mieux lisible est de ne pas mélanger la définition des types (interfaces, classes) avec un autre code et de mettre chaque type dans son propre fichier.

Cette règle fait également partie des normes de codage PSR-1 1 .

Cependant, avant de pouvoir utiliser une classe, il faut avoir besoin du fichier qui la contient.

Cela peut être accablant, mais PHP fournit des fonctions utilitaires pour charger automatiquement une classe lorsque cela est nécessaire, en utilisant un rappel qui charge un fichier en fonction de son nom.

Utiliser les espaces de noms devient très simple, car il est maintenant possible de faire correspondre la structure des dossiers à la structure des espaces de noms.

C'est non seulement possible, mais c'est aussi un autre standard PSR (ou mieux 2: PSR-0 maintenant obsolète et PSR-4 ).

En respectant ces normes, il est possible d'utiliser différents outils de gestion du chargement automatique, sans avoir à coder un chargeur automatique personnalisé.

Je dois dire que les normes de codage WordPress ont des règles différentes pour nommer les fichiers.

Ainsi, lors de l'écriture de code pour le noyau WordPress, les développeurs doivent suivre les règles WP, mais lors de l'écriture de code personnalisé, c'est un choix pour les développeurs, mais l'utilisation de la norme PSR est plus facile à utiliser avec les outils déjà écrits 2 .

Modèles d'accès global, de registre et de localisateur de services.

L’un des plus gros problèmes lors de l’instanciation des classes de plugins dans WordPress est de savoir comment y accéder depuis différentes parties du code.

WordPress lui-même utilise l' approche globale : les variables sont enregistrées dans une portée globale, ce qui les rend accessibles partout. Chaque développeur WP tape le mot des globalmilliers de fois dans sa carrière.

C’est aussi l’approche que j’ai utilisée pour l’exemple ci-dessus, mais c’est un mal .

Cette réponse est déjà beaucoup trop longue pour me permettre d'expliquer davantage pourquoi, mais la lecture des premiers résultats du SERP pour «variables globales mauvaises» constitue un bon point de départ.

Mais comment est-il possible d'éviter les variables globales?

Il y a différentes manières.

Certaines des réponses plus anciennes ici utilisent l' approche d'instance statique .

public static function instance() {

  if ( is_null( self::$instance ) ) {
    self::$instance = new self;
  }

  return self::$instance;
}

C'est facile et très bien, mais cela oblige à mettre en œuvre le modèle pour chaque classe à laquelle nous voulons accéder.

De plus, cette approche est souvent mise à mal, car les développeurs rendent accessible une classe principale à l' aide de cette méthode, puis l'utilisent pour accéder à toutes les autres classes.

J'ai déjà expliqué à quel point une classe de dieu est mauvaise. L'approche d'instance statique est donc un bon choix lorsqu'un plugin n'a besoin que de rendre accessible une ou deux classes.

Cela ne signifie pas qu'il ne peut être utilisé que pour des plugins n'ayant que quelques classes. En fait, lorsque le principe d'injection de dépendance est utilisé correctement, il est possible de créer des applications assez complexes sans avoir à rendre globalement accessible un grand nombre d'objets.

Cependant, parfois, les plugins doivent rendre certaines classes accessibles , et dans ce cas, l'approche d'instance statique est écrasante.

Une autre approche possible consiste à utiliser le modèle de registre .

Ceci est une implémentation très simple:

namespace GM\WPSE\Example;

class Registry {

   private $storage = array();

   function add( $id, $class ) {
     $this->storage[$id] = $class;
   }

   function get( $id ) {
      return array_key_exists( $id, $this->storage ) ? $this->storage[$id] : NULL;
   }

}

À l'aide de cette classe, il est possible de stocker des objets dans l'objet de registre à l'aide d'un identifiant. Vous avez donc accès à un registre. Vous pouvez également accéder à tous les objets. Bien sûr, lorsqu'un objet est créé pour la première fois, il doit être ajouté au registre.

Exemple:

global $registry;

if ( is_null( $registry->get( 'tools' ) ) ) {
  $tools = new GM\WPSE\Example\Tools;
  $registry->add( 'tools', $tools );
}

if ( is_null( $registry->get( 'front' ) ) ) {
  $front_stuff = new GM\WPSE\Example\FrontStuff( $registry->get( 'tools' ) );    
  $registry->add( 'front', front_stuff );
}

add_action( 'wp', array( $registry->get( 'front' ), 'wp' ) );

L'exemple ci-dessus montre clairement que, pour être utile, le registre doit être accessible de manière globale. Une variable globale pour le registre unique n'est pas très mauvaise, cependant, pour les puristes non globaux, il est possible d'implémenter l'approche d'instance statique pour un registre, ou peut-être une fonction avec une variable statique:

function gm_wpse_example_registry() {
  static $registry = NULL;
  if ( is_null( $registry ) ) {
    $registry = new GM\WPSE\Example\Registry;
  }
  return $registry;
}

La première fois que la fonction est appelée, elle instanciera le registre, elle sera simplement renvoyée lors d'appels suivants.

Une autre méthode spécifique à WordPress pour rendre une classe accessible globalement renvoie le retour d'une instance d'objet à partir d'un filtre. Quelque chose comme ça:

$registry = new GM\WPSE\Example\Registry;

add_filter( 'gm_wpse_example_registry', function() use( $registry ) {
  return $registry;
} );

Après cela, le registre est nécessaire partout:

$registry = apply_filters( 'gm_wpse_example_registry', NULL );

Un autre modèle pouvant être utilisé est le modèle de localisation de service . Il est similaire au modèle de registre, mais les localisateurs de service sont transmis à différentes classes à l'aide de l'injection de dépendance.

Le principal problème de ce modèle est qu’il masque les dépendances des classes, ce qui rend le code plus difficile à maintenir et à lire.

Conteneurs DI

Quelle que soit la méthode utilisée pour rendre le registre ou le localisateur de services accessible à l’ensemble du monde, les objets doivent y être stockés et, avant d’être stockés, ils doivent être instanciés.

Dans les applications complexes, où il y a beaucoup de classes et beaucoup d'entre elles ont plusieurs dépendances, l'instanciation des classes nécessite beaucoup de code, donc la possibilité de bogues augmente: le code qui n'existe pas ne peut pas avoir de bogues.

Il est apparu ces dernières années des bibliothèques PHP qui aident les développeurs PHP à instancier et à stocker facilement des instances d’objets, en résolvant automatiquement leurs dépendances.

Ces bibliothèques sont appelées conteneurs d'injection de dépendances car elles sont capables d'instancier des classes résolvant des dépendances et également de stocker des objets et de les renvoyer si nécessaire, agissant de la même manière pour un objet de registre.

Habituellement, lors de l'utilisation de conteneurs DI, les développeurs doivent configurer les dépendances pour chaque classe de l'application, puis la première fois qu'une classe est nécessaire dans le code, elle est instanciée avec les dépendances appropriées et la même instance est renvoyée à plusieurs reprises lors de requêtes ultérieures. .

Certains conteneurs DI sont également capables de détecter automatiquement les dépendances sans configuration, mais en utilisant la réflexion PHP .

Certains conteneurs DI bien connus sont:

et plein d'autres.

Je tiens à souligner que pour les plugins simples, qui impliquent seulement quelques classes et que les classes n'ont pas beaucoup de dépendances, l'utilisation de conteneurs DI ne vaut probablement pas la peine: la méthode de l'instance statique ou un registre accessible mondial sont de bonnes solutions, mais pour les plugins complexes l'avantage d'un conteneur DI devient évident.

Bien entendu, même les objets de conteneur DI doivent être accessibles pour pouvoir être utilisés dans l'application. Pour cela, il est possible d'utiliser l'une des méthodes décrites ci-dessus, variable globale, variable d'instance statique, renvoyer un objet via un filtre, etc.

Compositeur

Utiliser un conteneur DI signifie souvent utiliser un code tiers. De nos jours, en PHP, lorsque nous devons utiliser une bibliothèque externe (donc non seulement les conteneurs DI, mais tout code ne faisant pas partie de l'application), le télécharger et le placer dans notre dossier d'application n'est pas considéré comme une bonne pratique. Même si nous sommes les auteurs de cet autre morceau de code.

Découpler un code d'application des dépendances externes est le signe d'une meilleure organisation, d'une meilleure fiabilité et d'une meilleure santé du code.

Composer , est le standard de facto de la communauté PHP pour gérer les dépendances PHP. Loin d’être aussi courant dans la communauté WP, c’est un outil que tous les développeurs PHP et WordPress devraient au moins connaître, sinon utiliser.

Cette réponse a déjà la taille d'un livre pour permettre une discussion plus approfondie. Discuter de Composer ici est probablement hors sujet, elle n'a été mentionnée que par souci d'exhaustivité.

Pour plus d'informations, visitez le site Composer et lisez également ce minisite organisé par @Rarst .


1 PSR sont les règles standards de PHP publiées par le Framework PHP Interop Group

2 Composer (une bibliothèque qui sera mentionnée dans cette réponse) contient entre autres un utilitaire de chargement automatique.

gmazzap
la source
1
Une note supplémentaire, que PHP 5.3 est également en fin de vie. Un hôte responsable proposera au moins 5.4 comme option sinon un défaut
Tom J Nowell
2
"Depuis le 14 août 2014, PHP 5.3 est arrivé en fin de vie. Il est définitivement mort." Est-ce que la première ligne sous "PHP 5.2 est pour les zombies" @TomJNowell
gmazzap
3
Je me demandais simplement à quoi ressemblerait "beaucoup de choses" ? ;-)
MikeSchinkel
Dans les efforts pour éviter les variables globales, j'aime bien l'idée du modèle de registre avec fonction et variable statique. La première fois que la fonction est appelée, elle instanciera le registre, elle sera simplement renvoyée lors d'appels suivants.
Michael Ecklund
10

J'utilise la structure suivante:

Prefix_Example_Plugin::on_load();

/**
 * Example of initial class-based plugin load.
 */
class Prefix_Example_Plugin {

    /**
     * Hooks init (nothing else) and calls things that need to run right away.
     */
    static function on_load() {

        // if needed kill switch goes here (if disable constant defined then return)

        add_action( 'init', array( __CLASS__, 'init' ) );
    }

    /**
     * Further hooks setup, loading files, etc.
     *
     * Note that for hooked methods name equals hook (when possible).
     */
    static function init(  ) {


    }
}

Remarques:

  • a défini un lieu pour les choses qui doivent fonctionner tout de suite
  • désactiver / annuler les réglages est facile (décrocher une initméthode)
  • Je ne pense pas avoir déjà utilisé / eu besoin d'un objet de la classe plugin - nécessite de garder une trace de celui-ci, etc. c'est vraiment un faux espacement de nom par but, pas de POO (la plupart du temps)

Déni de responsabilité Je n'utilise pas encore de tests unitaires ( tant de choses sur ma plaque ) et j'entends dire que l'électricité statique peut être moins préférable pour eux. Faites vos recherches à ce sujet si vous devez le tester à l'unité.

Rarst
la source
3
Je connais des gens qui s’intéressent beaucoup aux tests unitaires n’aiment pas les solutions statiques / singleton. Je pense que si vous comprenez parfaitement ce que vous essayez d’atteindre en utilisant l’électricité statique et si vous êtes au moins conscient des conséquences que cela peut avoir, il est alors tout à fait possible d’appliquer de telles méthodes. Bons sujets entourant ce sujet à Stack Overflow
Adam
Cela m'a fait vraiment réfléchir. Alors pourquoi utiliser une classe alors et ne pas simplement revenir à de simples fonctions préfixées. Faisons-nous cela simplement pour avoir des noms de fonction / méthode plus propres? Je veux dire que les avoir imbriqués avec un "statique" b4 est-il beaucoup plus lisible? Les risques de conflit de nom sont à peu près les mêmes que pour un nom de classe unique si vous utilisez des préfixes propper ou si je manque quelque chose?
James Mitch
1
@JamesMitch Oui, les méthodes entièrement statiques consistent principalement en des fonctions avec un faux espace de nom utilisé dans WP. Cependant, même dans ce cas, les classes présentent certains avantages par rapport aux fonctions pures, telles que le chargement automatique et l'héritage. Dernièrement, je me suis déplacé des méthodes statiques vers les objets instanciés réels organisés par le conteneur d'injection de dépendance.
Rarst
3

Tout dépend de la fonctionnalité.

Une fois, j’ai créé un plugin qui enregistrait les scripts lors de l’appel du constructeur, il a donc fallu l’accrocher au wp_enqueue_scriptscrochet.

Si vous souhaitez l'appeler lorsque votre functions.phpfichier est chargé, vous pouvez également créer vous-même une instance, $class_instance = new ClassName();comme vous l'avez mentionné.

Vous voudrez peut-être prendre en compte la vitesse et l'utilisation de la mémoire. Je ne suis au courant d'aucun, mais je peux imaginer qu'il y a des hooks non appelés dans certains cas. En créant votre instance à ce raccordement, vous économiserez peut-être certaines ressources du serveur.

Tim S.
la source
Cool merci pour cela, je suppose qu'il y a aussi deux points à la question ci-dessus. L'autre étant si __construct convient ou si init () est un meilleur moyen d'initialiser la classe.
Kalpaitch
1
Je choisirais une init()méthode statique afin que l'instance de la classe soit appelée dans la portée de la classe au lieu d'une autre portée dans laquelle vous pourriez éventuellement écraser des variables existantes.
Tim S.
0

Je sais que cela fait quelques années, mais en attendant php 5.3 supporte les méthodes anonymes , alors je suis venu avec ceci:

add_action( 'plugins_loaded', function() { new My_Plugin(); } );

et de toute façon je l'aime le plus. Je peux utiliser des constructeurs normaux et je n'ai pas besoin de définir de méthode "init" ou "on_load" qui gâche mes structures de POO.

Basti
la source