Meilleur moyen d'initier une classe dans un plugin WP?
-
-
En ce qui concerne la dernière édition,sielleest contenue dans lemêmefichier deplugin que la classe,cela devient quelquepeuinutile.Vouspouvez égalementinstancier la classe selon laméthode queje décris.Même si c'est dans unfichier séparé,c'estencore quelquepeuinutile.Le seul cas d'utilisation queje peux voirest si vous souhaitez créer unefonction wrapper qui vouspermet d'instancier une classeen dehors de vosfichiers deplug-in,dans desthèmes,etc.Même dans ce cas,je devrais demander quelle logique se cache derrière cela,car une utilisation correcte des conditionset des crochets devraitpermettre un contrôleprécis de l'instanciation,vouspermettant de vous concentrer sur l'utilisation duplugin à laplace.Regarding last edit, if that's contained in the same plugin file as the class, it becomes somewhat useless. You may as well instantiate the class as per the method I describe. Even if its in a separate file, its still somewhat pointless. Only use case I can see is if you want to create a wrapper function that enables you to instantiate a class outside of your plugin files, within themes and so on. Even so, I'd have to ask what logic lay behind that because proper use of conditionals and hooks should allow fine grain control over instantiation allowing you to focus on using the plugin instead.
- 1
- 2012-10-23
- Adam
-
Je suis unpeu d'accord avec cela,maisj'aipensé que cela valait lapeine de lemettre carje l'aitrouvé dans quelquesplugins WP.I kinda agree with this, but I thought it worth putting in as I found it in a couple of WP plugins.
- 0
- 2012-10-24
- kalpaitch
-
4 réponses
- votes
-
- 2012-10-22
Bonne question,ilexiste un certainnombre d'approcheset cela dépend de ce que vous voulez réaliser.
Je lefais 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... }
Unexempleplus approfondiet plus détaillé résultant de discussions récentes sur ce sujet dans la salle de chatpeut être vu dans l'essentiel par lemembre WPSE toscho .
L'approche du constructeur vide.
Voici unextrait des avantages/inconvénientstirés de l'essentiel ci-dessus quiillustrepleinement l'approche du constructeur vide.
-
Avantages:
-
Lestests unitairespeuvent créer denouvellesinstances sans activer de hooks automatiquement. Pas de singleton.
-
Aucune variableglobalenécessaire.
-
Quiconque souhaitetravailler avec l'instance dupluginpeut simplement appeler T5_Plugin_Class_Demo ::get_instance ().
-
Facile à désactiver.
-
Encore une vraie POO: aucuneméthode detravailn'est statique.
-
-
Inconvénient:
- Peut-êtreplus difficile à lire?
L'inconvénient àmon avisestfaible,c'estpourquoiilfaudrait que ce soitmon approchepréférée,maispas la seule quej'utilise. Enfait,plusieurs autrespoids lourdsinterviendront sans aucun doute sur ce sujet avec leur opinion sur le sujet souspeu,caril y a debonnes opinions sur ce sujet qui devraient êtreexprimées.
note:je doistrouver l'exemple debase de toscho qui a duré 3 ou 4 des comparaisons sur lafaçon d'instancier une classe dans unplugin quiexaminait les avantageset lesinconvénients de chacun,dont le lien ci-dessus était lemoyenprivilégiépour lefaire,mais les autresexemples offrent unbon contraste avec ce sujet. Espérons que toscho l'atoujours dans sesfichiers.Remarque: Le WPSE Répondez à ce sujet avec desexemplespertinentset des comparaisons. Aussi lameilleure solution,parexemple 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! } }
Good question, there are a number of approaches and it depends on what you want to achieve.
I often do;
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... }
A more thorough an indepth example which came about as a result of some recent discussions on this very topic within the chat room can be seen in this gist by WPSE member toscho.
The empty constructor approach.
Here is an excerpt of advantages/disadvantages taken from the above gist which exemplifies the empty constructor approach in full.
Advantages:
Unit tests can create new instances without activating any hooks automatically. No Singleton.
No global variable needed.
Whoever wants to work with the plugin instance can just call T5_Plugin_Class_Demo::get_instance().
Easy to deactivate.
Still real OOP: no working methods are static.
Disadvantage:
- Maybe harder to read?
The disadvantage in my opinion is a weak one at that which is why it would have to be my favored approach, however not the only one I use. In fact several other heavy weights will no doubt chime in on this topic with their take on the subject shortly because there are some good opinions surrounding this topic that should be voiced.
note: I need to find the gist example from toscho that ran through 3 or 4 comparisons of how to instantiate a class within a plugin that looked at the pros and cons of each, which the above link was the favored way to do it, but the other examples provide a good contrast to this topic. Hopefully toscho still has that on file.Note: The WPSE Answer to this topic with relevant examples and comparisons. Also the best solution for instance a class in 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! } }
-
quelle serait la différenceentre add_action ('plugins_loaded',...);et add_action ('load-plugins.php',...);L'exemple quej'aipris utilisait ce dernierwhat would be the difference between add_action('plugins_loaded',...); and add_action('load-plugins.php',...); The example I took used the latter
- 0
- 2012-10-22
- kalpaitch
-
Jene suispas sûr,mais comptetenu desnoms,je dirais que le hook `plugins_loaded`est unefile d'attente quiestexécutée après le chargement desplugins,alors que le hook` load-plugins.php` accrocherait lafile d'attente de chargement duplugin.Enpratique,celane faitpasbeaucoup de différence,maisthéoriquement,celapourrait causer desproblèmes si vous appelez desméthodes alors quetous lespluginsne sontpas chargés.C'estpourquoije préférerais `plugins_loaded`.Encore unefois,j'interprète simplement leursnoms.I'm not sure, but considering the names I would say that the `plugins_loaded` hook is a queue that is run after the plugins are loaded where as the `load-plugins.php` hook would hook the actual plugin loading queue. Practically it doesn't make much of a difference, but theoretically it could cause issues if you are calling methods when not all plugins are loaded. That's why I would prefer `plugins_loaded`. Again, I am just interpreting their names.
- 0
- 2012-10-22
- Tim S.
-
D'après ce queje comprends,load-plugins.php,bien que celafonctionne,est associé aufichierprincipal `update.php`et nefaitpaspartie des actionspar défaut habituelles sur lesquellesilfaut sefieren ce qui concerne la séquence d'événements qui se déclenchent lors de l'initialisationpour cette raison,je préfère utiliser les hooks qui s'appliquent,dans ce cas `plugins_loaded`.C'est ce quej'appelle souvent un aperçu rapide de ce qui sepasse lorsque [Action Reference] (http://codex.wordpress.org/Plugin_API/Action_Reference).Monexplicationn'estpas complète dans sonintégralité.From what I understand load-plugins.php, although it works, is associated with the core `update.php` file and is not part of the usual default actions that should be relied upon when concerning the sequence of events that fire during initialization and for that reason I prefer to use those hooks that do apply, in this case `plugins_loaded`. This is what I often refer to as a quick snapshot of what happens when [Action Reference](http://codex.wordpress.org/Plugin_API/Action_Reference). My explanation is not complete in its entirety.
- 1
- 2012-10-22
- Adam
-
Vous recherchez [cette réponse] (http://wordpress.stackexchange.com/questions/61437/php-error-with-shortcode-handler-from-a-class/61440#61440)?You are looking for [this answer](http://wordpress.stackexchange.com/questions/61437/php-error-with-shortcode-handler-from-a-class/61440#61440)?
- 0
- 2012-10-22
- fuxia
-
@toscho Ouais,c'esttout.Jeme souviens quenous regardions cela dans le chatmais aussi sous laforme d'un Gist.Mais un dans lemême.Mercipour ça!@toscho Yep, that's it. I remember we were looking at that in chat but in the form of a Gist also. But one in the same. Thanks for that!
- 0
- 2012-10-22
- Adam
-
Très utile,et add_shortcode () semble être unmoyenbeaucoupplus simple d'inclure la sortie d'unepartieparticulière de cette classe,plutôt que de récupérer uneinstanceen soi.Est-ilpossible d'utiliser un shortcode dans lesfichiers demodèle ainsi que dans l'éditeur WordPress?Very helpful, and the add_shortcode() seems to be a much simpler way to include the output of a particular part of that class, rather than fetching an instance per say. Is it possible to use a shortcode in the template files as well as in the WordPress Editor?
- 0
- 2012-10-22
- kalpaitch
-
@kalpaitch Si un shotcode correspond à votre cas d'utilisation,alors oui,`echo do_shortcode ('[my-shortcode]');` dans saforme laplusbasique,car lorsque vous voulez appeler un shortcodeen dehors de l'écrantraditionnel de l'éditeur depublicationtour.@kalpaitch If a shotcode fits your use case, then yes, `echo do_shortcode('[my-shortcode]');` in its most basic form, for when wanting to call a shortcode outside of the traditional post editor screen will do the trick.
- 0
- 2012-10-22
- Adam
-
J'aime cette approche detype singleton.Cependant,je remetsen question l'utilisation deplugins_loaded comme crochet d'action d'initialisation.Ce hookest destiné à êtreexécuté __after__tous lesplugins ont été chargés.En vous connectant après cela,vous détournezen quelque sorte ce hooket vouspouvez vous amuser dans des conflits ou desproblèmes de séquence de démarrage avec d'autresplugins outhèmes qui se connectent àplugins_loaded.Jene me connecterais à aucune actionpourexécuter votreméthode d'initialisation.L'architecture duplugin a été conçuepour s'exécuteren ligne,pas sur une action.I like this singleton-like approach. However, I question using plugins_loaded as your initializing action hook. This hook is meant to be run __after__ all plugins have loaded. By hooking in after it, you are kind of hijacking that hook, and may fun into conflicts or startup-sequence issues with other plugins or themes that hook into plugins_loaded. I wouldn't hook into any action to run your initialization method. The plugin architecture was designed to run inline, not on an action.
- 4
- 2012-10-23
- Tom Auger
-
Jem'accroche à `init` laplupart dutemps,maisje comprends votrepoint de vue avec`plugins_loaded`,c'estparfaitement logique.Cela a également du sens si votreintention était de détourner ce crochet à cettefin.Jene voispas l'utilisation des hooks de lamêmemanière que vouspour lesplugins,maisje seraisintéressé d'en savoirplus sur votreposition sur le sujet si vous avez des lectures recommandées?Liens?D'autresexemples destypes deproblèmes de séquence quenouspourrions rencontrer?Mercimonpote..I hook onto `init` the majority of the time, but I get your point with `plugins_loaded`, makes perfect sense. It also makes sense if your intention was to hijack that hook for that purpose. I don't view using hooks the same way for plugins as you do but I'd be interested to learn more about your position on the topic if you have some recommended reading? Links? Further examples of what kinds of sequence issues we might encounter? Thanks mate..
- 0
- 2012-10-23
- Adam
-
@Tom Auger,je comprendsparfaitement votrepoint de vue sur le chargement à l'aide du hookplugins_loaded.Serait-ilpréférable d'utiliser lapremièreméthode dans la questionpour lancer un cours,ou si vousproposez uneméthode alternative,pourriez-vous s'il vousplaîtinclure dans une réponse?@Tom Auger, I completely see your point about loading using the hook plugins_loaded. Would it be better to use the first method in the question for initiating a class, or if you propose an alternative method, could you please include in an answer?
- 0
- 2012-10-24
- kalpaitch
-
Notez que si vous utilisez [`register_activation_hook ()`] (http://codex.wordpress.org/Function_Reference/register_activation_hook) vous devez appeler cettefonction avant que l'action `plugins_loaded`ne soit déclenchée.Note that if you use [`register_activation_hook()`](http://codex.wordpress.org/Function_Reference/register_activation_hook) you need to call that function before the `plugins_loaded` action has been triggered.
- 2
- 2012-10-31
- Geert
-
@Geert,d'accord,j'aitrouvé que ces hooks d'activation devaientencore aller dans __construct@Geert, agreed, I found that these activation hooks still had to go in __contruct
- 0
- 2012-11-02
- kalpaitch
-
Pourplus d'informations,consultez cepost de @mikeschinkelet la discussion dans les commentaires.http://hardcorewp.com/2012/using-classes-as-code-wrappers-for-wordpress-plugins/#comment-149As additional information, see this post from @mikeschinkel and the dicuss in the comments. http://hardcorewp.com/2012/using-classes-as-code-wrappers-for-wordpress-plugins/#comment-149
- 1
- 2013-01-03
- bueltge
-
@bueltge Mercipour le lien,doit lire.On dirait unebonne discussion!@bueltge Thanks for the link, shall read. Looks like a good discussion!
- 0
- 2013-01-03
- Adam
-
- 2012-10-22
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 uneplacepour les choses qui doivent êtreexécutéesimmédiatement
- désactiver/remplacerpour les ajustementsestfacile (décrocher uneméthode
init
) - Jene pensepas avoirjamais utilisé/nécessaire un objet de la classe deplugin -nécessite d'engarder unetrace,etc.il s'agit vraiment d'unfauxespace denomspar objectif,pas de POO (laplupart dutemps)
Clause denon-responsabilité Jen'utilisepasencore detests unitaires (tant de choses surmyplate )et j'entends dire que la statiquepeut êtremoinspréférablepoureux. Faites vos recherches à ce sujet si vous avezbesoin de letester unitaire.
I use following structure:
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( ) { } }
Notes:
- has defined place for things that need to run right away
- disable/override for tweaks is easy (unhook one
init
method) - I don't think I ever used/needed object of plugin class - requires keeping track of it, etc; this is really fake namespacing by purpose, not OOP (most of the time)
Disclaimer I don't use unit tests yet (so many things on myplate) and I hear that static can be less preferable for them. Do your research on this if you need to unit test it.
-
Je sais que lesgenspassionnéspar lestests unitairesn'aiment vraimentpas les solutions statiques/singleton.Jepense que si vous comprenezparfaitement ce que vousessayez de réaliseren utilisant statiqueet que vous êtes aumoins conscient des ramifications de lefaire,alorsilestparfaitementbien demettreen œuvre detellesméthodes.Bons sujets à ce sujet à [SO]I know people big on unit testing really don't like static / singleton solutions. I think if you fully understand what you are attempting to achieve by using static and are at least aware of the ramifications of doing so then its perfectly fine to implement such methods. Good topics surrounding this over at [SO]
- 3
- 2012-10-22
- Adam
-
Celam'a vraimentfait réfléchir.Alorspourquoi utiliser une classeet pas simplement revenir à de simplesfonctionspréfixées.Faisons-nous celajustepour avoir desnoms defonctions/méthodespluspropres?Je veux dire les avoirimbriqués avec unb4 "statique",est-cebeaucoupplus lisible?Le risque d'avoir un conflit denomest àpeuprès lemême quepour unnom de classe unique si vous utilisez despréfixes appropriés ou sije manque quelque chose?This made me really think. So why use a Classes then and not just go back to simple prefixed functions. Do we do this just to have cleaner function/method names? I mean having them nested with a "static" b4 them is it that much more readable? The chance of having a name conflict is about the same as for a single class name if you use propper prefixes or am I missing something?
- 0
- 2013-05-28
- James Mitch
-
@JamesMitch Oui,lesméthodesentièrement statiquesne sontprincipalement que desfonctions avec unfauxespace denomstel qu'utilisé dans WP.Cependant,les classes ont certains avantagespar rapport auxfonctionspures,même dans ce cas,comme le chargement automatiqueet l'héritage.Dernièrement,je suispassé deméthodes statiques à de vrais objetsinstanciés organiséspar conteneur d'injection de dépendances.@JamesMitch yes, all-static methods is mostly just functions with fake namespace as used in WP. However classes do have some advantages over pure functions even in this case, such as autoload and inheritance. Lately I have been moving from static methods and towards real instantiated objects organized by dependency injection container.
- 1
- 2013-05-28
- Rarst
-
- 2012-10-22
Tout dépend de lafonctionnalité.
Unefois,j'ai créé unplugin quienregistrait des scripts lorsque le constructeur était appelé,je devais donc l'accrocher au hook
wp_enqueue_scripts
.Si vous souhaitez l'appeler lorsque votrefichier
functions.php
est chargé,vouspouvez aussibien créer uneinstance vous-même$class_instance = new ClassName();
que vousmentionné.Vous voudrezpeut-êtretenir compte de la vitesseet de l'utilisation de lamémoire.Jen'en connais aucun,maisje peuximaginer qu'il y a des crochetsnon appelés dans certains cas.En créant votreinstance à ce hook,vouspourriez économiser certaines ressources du serveur.
It all depends on functionality.
I once made a plugin that registered scripts when the constructor was called so I had to hook it at the
wp_enqueue_scripts
hook.If you want to call it when your
functions.php
file is loaded, you might as well create an instance yourself$class_instance = new ClassName();
as you mentioned.You might want to consider speed and memory usage. I'm not aware of any, but I can imagine there are uncalled hooks in some cases. By creating your instance at that hook you might save some server resources.
-
Coolmercipour cela,je suppose qu'il y a également deuxpoints à la question ci-dessus.L'autre étant de savoir si __construct convient ou siinit ()est unmeilleurmoyen d'initialiser la classe.Cool thanks for that, I suppose there are two points to the above question as well. The other being whether __construct is suitable or whether init() is a better way to initialize the class.
- 0
- 2012-10-22
- kalpaitch
-
Ehbien,je choisirais uneméthode statique `init ()`pour que l'instance de classe soit appelée dans laportée de la classe au lieu d'une autreportée où vouspourriez éventuellement écraser les variablesexistantes.Well I'd go for an static `init()` method so the class instance is called in the class' scope instead of another scope where you could possibly overwrite existing variables.
- 1
- 2012-10-22
- Tim S.
-
- 2017-09-25
Je sais que cela date de quelques années,maisen attendant,php 5.3prenden charge lesméthodes anonymes ,alorsj'aitrouvé ceci:
add_action( 'plugins_loaded', function() { new My_Plugin(); } );
et je l'aime leplus.Jepeux utiliser des constructeurs standardset jen'aipasbesoin de définir deméthodes "init" ou "on_load" quigâchentmes structures POO.
I know this is a couple years old, but meanwhile php 5.3 supports anonymous methods, so I came up with this:
add_action( 'plugins_loaded', function() { new My_Plugin(); } );
and somehow I like it the most. I can use regular constructors and don't need to define any "init" or "on_load" methods that mess up my OOP structures.
J'ai créé unplugin,et bien sûr étantmoi,je voulais aller avec unebelle approche OO. Maintenant,ce quej'aifaitest de créer cette classe,puisjusteen dessous de créer uneinstance de cette classe:
Je suppose qu'il y a unmoyenplus WP d'initier cette classe,puisje suistombé sur desgens disant qu'ilspréfèrent avoir unefonction
init()
plutôt qu'une__construct()
un. Et demême,j'aitrouvé quelquespersonnes utilisant le crochet suivant:Quelleestgénéralement considérée comme lameilleurefaçon de créer uneinstance de classe WP au chargementet de l'avoir comme variableglobalement accessible?
REMARQUE: Enguise de complémentintéressant,j'ai remarqué que si
register_activation_hook()
peut être appelé àpartir de__construct
,ilne peutpas être appelé depuisinit()
en utilisant le deuxièmeexemple. Quelqu'unpourraitpeut-êtrem'éclairer sur cepoint.Modifier: Mercipourtoutes les réponses,il y a clairement unpeu de débat sur lafaçon degérer l'initialisation au sein de la classeelle-même,maisje pense qu'il y agénéralement un assezbon consensus que
add_action( 'plugins_loaded', ...);
est lemeilleurmoyen de démarrer réellement ...Edit: Justepour confondre les choses,j'ai également vu cela utilisé (même sije n'utiliseraispas cetteméthodemoi-même cartransformer une classebien OOen unefonction semble vaincre l'intérêt de celle-ci ):