Il modo migliore per iniziare una lezione in un plugin WP?
-
-
Per quanto riguarda l'ultimamodifica,se è contenutanello stessofile delplugin della classe,diventain qualchemodoinutile.Puoi ancheistanziare la classe secondoilmetodo che descrivo.Anche se èin unfile separato,è ancora unpo 'inutile.L'unico caso d'uso cheposso vedere è se vuoi creare unafunzione wrapper cheti permetta diistanziare una classe al difuori deituoifileplugin,all'interno ditemi e così via.Anche così,dovrei chiedere quale logica ci sia dietroperché un uso corretto di condizionalie hook dovrebbe consentire un controllo agranafine sull'istanziazione,permettendoti di concentrarti sull'uso delplugin.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
-
Sono unpo 'd'accordo con questo,ma hopensato che valesse lapenainserirloperché l'hotrovatoin unpaio diplugin 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 risposta
- voti
-
- 2012-10-22
Bella domanda,ci sono diversi approccie dipende da ciò che vuoi ottenere.
Lofaccio spesso;
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... }
Unesempiopiù approfonditoe approfondito che è venutofuori come risultato di alcune recenti discussioni su questo stesso argomento all'interno della chat roompuòessere vistoin questa sintesi delmembro WPSE toscho .
L'approccio del costruttore vuoto.
Ecco unestratto dei vantaggi/svantaggipresi dall'essenzaprecedente cheesemplifica completamente l'approccio del costruttore vuoto.
-
Vantaggi:
-
Gli unittestpossono crearenuoveistanze senza attivare alcun hook automaticamente. Nessun singleton.
-
Nessuna variabileglobalenecessaria.
-
Chiunque voglia lavorare con l'istanza delpluginpuò semplicemente chiamare T5_Plugin_Class_Demo ::get_instance ().
-
Facile da disattivare.
-
OOP ancora reale:nessunmetodo di lavoro è statico.
-
-
Svantaggio:
- Forse èpiù difficile da leggere?
Lo svantaggio secondome è debole,motivoper cui dovrebbeessereilmio approcciopreferito,manon l'unico che uso. Ineffetti molti altripesimassimiinterverranno senza dubbio su questo argomento con la loropresa sull'argomento abreveperché ci sono alcunebuone opinioni su questo argomento che dovrebberoessereespresse.
nota: hobisogno ditrovare l'esempioessenziale da toscho che ha superato 3 o 4 confronti su comeistanziare una classe all'interno di unplug-in che haesaminatoi proei contro di ciascuno,cheil collegamento sopraerailmodopreferitoperfarlo,magli altriesempiforniscono unbuon contrasto con questo argomento. Si spera che toscho lo abbia ancorain archivio.Nota: Risposta WPSE a questo argomento conesempie confrontipertinenti. Anche lamigliore soluzioneperesempio una classein 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! } }
-
quale sarebbe la differenzatra add_action ('plugins_loaded',...);e add_action ('load-plugins.php',...);L'esempio che hopreso ha utilizzato quest'ultimowhat 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
-
Nonne sono sicuro,ma considerandoi nomi direi che l'hook `plugins_loaded` è una coda che vieneeseguita dopo chei plug-in sono stati caricati,mentre l'hook` load-plugins.php` aggancia la coda di caricamento delplugin.Praticamentenonfamolta differenza,mateoricamentepotrebbe causareproblemi se si richiamanometodi quandonontuttii plugin sono caricati.Eccoperchépreferirei "plugins_loaded".Dinuovo,sto solointerpretandoi loronomi.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.
-
Da quanto ho capito load-plugins.php,sebbenefunzioni,è associato alfile core `update.php`e nonfaparte delle solite azionipredefinite su cuifare affidamento quando sitratta della sequenza dieventi che si attivano duranteper questomotivopreferisco usare quegli hook che si applicano,in questo caso `plugins_loaded`.Questo è ciò a cuimi riferisco spesso come una rapidaistantanea di ciò che accade quando [Action Reference] (http://codex.wordpress.org/Plugin_API/Action_Reference).Lamia spiegazionenon è completanella suainterezza.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
-
Stai cercando [questa risposta] (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 Sì,è così.Ricordo che lo stavamoguardandoin chat,ma anche sottoforma di Gist.Ma unonella stessa.Grazieper quello!@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
-
Molto utile,e add_shortcode () sembraessere unmodomoltopiù sempliceperincludere l'output di unaparteparticolare di quella classe,piuttosto che recuperare un'istanzaper dire.Èpossibile utilizzare uno shortcodenei filemodello oltre chenell'editor di 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 Se uno shotcode si adatta altuo caso d'uso,allora sì,`echo do_shortcode ('[my-shortcode]');`nella suaformapiù semplice,perché quando vuoi chiamare uno shortcode al difuori dellatradizionale schermata dell'editor deipostfaràiltrucco.@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
-
Mipiace questo approccio da singleton.Tuttavia,mi chiedo l'utilizzo diplugins_loaded come hook di azione diinizializzazione.Questo hook èpensatoperessereeseguito __dopo chetuttii plugin sono stati caricati.Collegandoti dopo,staiin qualchemodo dirottando quell'hooke potresti divertirtiin conflitti oproblemi di sequenza di avvio con altriplugin otemi che si collegano aplugins_loaded.Nonmi collegherei ad alcuna azionepereseguireiltuometodo diinizializzazione.L'architettura delplugin è stataprogettataperessereeseguitain linea,non su un'azione.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
-
Mi aggancio a `init` lamaggiorparte delle volte,ma capiscoiltuopunto con`plugins_loaded`,haperfettamente senso.Ha anche senso se latuaintenzioneera di dirottare quelgancioper quello scopo.Non vedo l'utilizzo degli hook allo stessomodoperi plugin comefaitu,ma sareiinteressato a saperne dipiù sullatuaposizione sull'argomento se hai qualche lettura consigliata?Collegamenti?Ulterioriesempi di qualitipi diproblemi di sequenzapotremmoincontrare?Grazie compagno..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,capiscoperfettamenteiltuopunto di vista sul caricamento utilizzando l'hookplugins_loaded.Sarebbemeglio usareilprimometodonella domandaperiniziare una lezione,o seproponi unmetodo alternativo,potrestiincluderloin una risposta?@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
-
Nota che se usi [`register_activation_hook ()`] (http://codex.wordpress.org/Function_Reference/register_activation_hook) devi chiamare quellafunzioneprima che l'azione `plugins_loaded` sia stata attivata.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'accordo,ho scoperto che questi hook di attivazione dovevano ancoraessereinseritiin __construct@Geert, agreed, I found that these activation hooks still had to go in __contruct
- 0
- 2012-11-02
- kalpaitch
-
Comeinformazioni aggiuntive,vedi questopost di @mikeschinkele il dicussnei commenti.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 Grazieperil collegamento,leggo.Sembra unabella discussione!@bueltge Thanks for the link, shall read. Looks like a good discussion!
- 0
- 2013-01-03
- Adam
-
- 2012-10-22
Uso la seguente struttura:
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( ) { } }
Note:
- ha definitoilpostoper le cose che devonoessereeseguiteimmediatamente
- disabilitare/ignorare lemodifiche èfacile (sgancia unmetodo
init
) - Non credo di avermai usato/necessario un oggetto della classeplugin - richiede ditenernetraccia,ecc; questo è davvero uno spazio deinomifalsoper scopo,non OOP (lamaggiorparte delle volte)
Disclaimer Non uso ancoragli unittest ( cosìtante cose sumyplate )e ho sentito cheper loro staticopuòesseremenopreferibile. Fai latua ricerca su questo se haibisogno ditestarlo.
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.
-
So che lepersoneesperte ditest unitarinon amano davvero le soluzioni statiche/singleton.Penso che se comprendi appieno ciò che staitentando di ottenere usando staticoe sei almeno consapevole delle ramificazioni difarlo,allora vabenissimoimplementaretalimetodi.Buoni argomenti su questo argomentoin [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
-
Questomi hafatto davveropensare.Alloraperché usare a Classese nontornare semplicemente a semplicifunzioni conprefisso.Lofacciamo soloper averenomi difunzioni/metodipiùpuliti?Voglio dire averli annidati con unb4 "statico" èmoltopiù leggibile?Lapossibilità di avere un conflitto dinomi èpiù omeno la stessa di un singolonome di classe se si utilizzanoprefissipropper omi manca qualcosa?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 sì,i metodi completamente statici sonoper lopiù solofunzioni con uno spazio deinomifalso come quelli usatiin WP.Tuttavia le classi hanno alcuni vantaggi rispetto allefunzionipure anchein questo caso,comeil caricamento automaticoe l'ereditarietà.Ultimamente sonopassato dametodi statici a oggetti realiistanziati organizzati da container di dependencyinjection.@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
Tutto dipende dallafunzionalità.
Una volta ho creato unplugin che registravagli script quando è stato chiamatoil costruttore,quindi ho dovuto agganciarlo all'hook
wp_enqueue_scripts
.Se vuoi chiamarlo quandoiltuofile
functions.php
è caricato,potresti anche creare un'istanzatu stesso$class_instance = new ClassName();
cometumenzionato.Potrestiprenderein considerazione la velocitàe l'utilizzo dellamemoria.Nonne sono a conoscenza,mapossoimmaginare chein alcuni casi ci sianogancinon chiamati.Creando latuaistanza su quell'hookpotresti risparmiare alcune risorse del server.
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.
-
Grazieper questo,suppongo che ci siano duepunti anchenella domandaprecedente.L'altro è se __construct è adatto o seinit () è unmodomiglioreperinizializzare 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
-
Bene,sceglierei unmetodo statico "init ()"in modo che l'istanza della classe venga chiamatanell'ambito della classeinvece di un altro ambitoin cui èpossibile sovrascrivere le variabiliesistenti.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
So che ha unpaio di anni,manelfrattempo php 5.3 supportametodi anonimi ,quindi hopensato a questo:
add_action( 'plugins_loaded', function() { new My_Plugin(); } );
e in qualchemodomi piace dipiù.Posso usare costruttori regolarie non hobisogno di definire alcunmetodo "init" o "on_load" che rovini lemie strutture OOP.
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.
Ho creato unplugine,ovviamente,essendome,volevo adottare unbel approccio OO. Quello che hofatto ora è creare questa classee poi subito sotto creare un'istanza di questa classe:
Presumo che ci sia unmodopiù WPper avere questa classeiniziata,e poimi sonoimbattutoin persone che dicono chepreferiscono avere unafunzione
init()
piuttosto che una__construct()
uno. Allo stessomodo hotrovato alcunepersone che usanoil seguente hook:Qual ègeneralmente consideratoilmodomiglioreper creare un'istanza di classe WP al caricamentoe averla come variabile accessibile a livelloglobale?
NOTA: comepunto amargineinteressante,honotato chementre
register_activation_hook()
puòessere chiamato dall'interno di__construct
,nonpuòessere chiamato dall'interno diinit()
utilizzandoil secondoesempio. Forse qualcunopotrebbeilluminarmi su questopunto.Modifica: graziepertutte le risposte,c'è chiaramente unbelpo 'di dibattito su comegestire l'inizializzazione all'interno della classe stessa,mapenso che ci siageneralmente unbuon consenso sulfatto che
add_action( 'plugins_loaded', ...);
èilmodomiglioreperiniziareeffettivamente ...Modifica: soloper confondere le cose,ho visto anche questo usato (anche senon lo usereiio stessoperchétrasformare unabella classe OOin unafunzione sembra vanificarneil senso ):