Implémentation de wrappers de fonction add_ * avancés
-
-
Puisque cela auraplusieurs réponses «correctes»,je pense que vous devriezen faire une question de communauté-wiki?Since this will have multiple 'correct' answers, i think you should make it a community-wiki question?
- 1
- 2011-03-05
- wyrfel
-
@wyrfel a du sens,maisje n'aipas la capacité de -par lesmécanismes actuels,seuls lesmodérateurspeuvent créer des questions wiki.L'un d'eux le convertiraprobablementen wikiplustard,le samediest unejournée lente.:)@wyrfel makes sense, but I have no capability to - by current mechanics only moderators can create wiki questions. One of them will most likely convert it to wiki down the road, Saturday is slow day. :)
- 0
- 2011-03-05
- Rarst
-
5 réponses
- votes
-
- 2011-04-01
J'avaispubliémon codeen tant quebibliothèque API Advanced Hooks .
Quelquesexemples:
add_action_with_arguments('test', 'printf', 10, 'boo%s', '<br />'); do_action('test'); // boo add_filter_return('test2',10,'boo'); echo apply_filters('test2','not boo') . '<br />'; // boo add_filter_append('test3',10,' and boo'); echo apply_filters('test3','boo') . '<br />'; // boo and boo add_filter_prepend('test4',10,'boo and '); echo apply_filters('test4','boo') . '<br />'; // boo and boo add_filter_replace('test5','boo','you thought...'); echo apply_filters('test5','boo'); // you thought...
I had released my code as Advanced Hooks API library.
Some examples:
add_action_with_arguments('test', 'printf', 10, 'boo%s', '<br />'); do_action('test'); // boo add_filter_return('test2',10,'boo'); echo apply_filters('test2','not boo') . '<br />'; // boo add_filter_append('test3',10,' and boo'); echo apply_filters('test3','boo') . '<br />'; // boo and boo add_filter_prepend('test4',10,'boo and '); echo apply_filters('test4','boo') . '<br />'; // boo and boo add_filter_replace('test5','boo','you thought...'); echo apply_filters('test5','boo'); // you thought...
-
Je le renommeraisen `add_action_with_args ()` car les utilisateurs doivent l'écrireplus d'unefois :)I'd rename it to `add_action_with_args()` as users have to write this more than once :)
- 0
- 2011-08-14
- kaiser
-
- 2011-03-05
Pour des cas simples comme les retours rapides d'une seule ligne,ilfaut se rappeler qu'ilestpossible de raccorder unefonction anonyme directement dans l'appel d'ajout defiltre,parexemple:
add_filter('some_filter_hook', function($v){return str_replace('..', '.', $v);}); add_action('some_action_hook', function(){echo '....';});
For simple cases like quick one-liner returns one should remember that it's possible to hook an anonymous function directly in the add filter call, e.g:
add_filter('some_filter_hook', function($v){return str_replace('..', '.', $v);}); add_action('some_action_hook', function(){echo '....';});
-
Oui,mais celane rendpas vraiment le codebeaucoupplus compact ouplusfacile à lire -il contient simplement lamême quantitéen une seule ligne.Deplus,ilnécessite PHP 5.3+ (anciennesfonctions anonymes avec `create_function ()` suck),quin'estmalheureusementpastoujours disponible.Yep, but it doesn't really make code considerably more compact or easier to read - it merely packs about same amount in single line. Also it requires PHP 5.3+ (older anonymous functions with `create_function()` suck), which is sadly not always available.
- 1
- 2011-03-05
- Rarst
-
Cependant,celaprésente un léger avantageen ce qu'ilne polluepas lesespaces denoms,en particulier lorsque vosfonctionsne sontpas dans une classepour une raison quelconque.It does yield a slight advantage, though, in that it doesn't pollute namespaces, particularly when your functions are not within a class for whatever reason.
- 0
- 2011-03-05
- wyrfel
-
- 2011-03-06
Vous voudrezpeut-êtreexaminer les méthodes de classemagiqueet la surchargeen PHP qui aura lenom de lafonction appeléepasséen paramètre.Ensuite,vouspouvezprendre des décisionsbasées sur lenom de lafonction comme
return__some_string
Jepin-up un codeexemplaireet nontesté:class magiCall { public static function __callStatic ( string $name , array $arguments ) { // your code here, $name is the function name called. } } add_filter('hookname', 'magiCall::return__the_string');
Jepense que cetexemplemontre assezbien l'idée.
Celui-ciest PHP 5.3.x vouspouvez rendre ce PHP 5.2 compatibleen utilisant laméthodemagique
__call
et si vous avez unefonctionpublique statiquepour renvoyer le rappel,vouspourrezpeut-être écrireil comparable simplifié.Voir le lien vers lemanuelphp ci-dessus.You might want to look into magic class methods and overloading in PHP which will have the function name called passed as a parameter. Then you can make decisions based on the function name like
return__some_string
I pin-up some exemplary and untested code:class magiCall { public static function __callStatic ( string $name , array $arguments ) { // your code here, $name is the function name called. } } add_filter('hookname', 'magiCall::return__the_string');
I think that example pretty much shows the idea.
This one is PHP 5.3.x you can make this PHP 5.2 compatible by using the
__call
magic method and if you have a static public function to return the callback, then you might be able to write it comparable simplified. See the link to the php manual above.-
Intéressant,va l'examiner.Interesting, will look into it.
- 0
- 2011-03-06
- Rarst
-
- 2011-03-05
Pour les valeurs de retour simples,vousn'avezpasbesoin debeaucoup defonctions supplémentaires. Ilexiste le
current_filter()
. Vouspouvez l'utiliser dans vospropresfonctions.Exemple
<?php # -*- coding: utf-8 -*- /* Plugin Name: Filter System From Mail Description: Sets the WP from mail address to the first admin’s mail and the from name to blog name. Version: 1.1 Author: Thomas Scholz Author URI: http://toscho.de License: GPL */ if ( ! function_exists( 'filter_system_from_mail' ) ) { /** * First admin's e-mail address or blog name depending on current filter. * * @return string */ function filter_system_from_mail() { return get_option( 'wp_mail_from' == current_filter() ? 'admin_email' : 'blogname' ); } add_filter( 'wp_mail_from', 'filter_system_from_mail' ); add_filter( 'wp_mail_from_name', 'filter_system_from_mail' ); }
Ou… ai-jemal lu votre question?
For simple return values you don’t need a lot of extra functions. There is the handy
current_filter()
. You can use that inside of your own functions.Example
<?php # -*- coding: utf-8 -*- /* Plugin Name: Filter System From Mail Description: Sets the WP from mail address to the first admin’s mail and the from name to blog name. Version: 1.1 Author: Thomas Scholz Author URI: http://toscho.de License: GPL */ if ( ! function_exists( 'filter_system_from_mail' ) ) { /** * First admin's e-mail address or blog name depending on current filter. * * @return string */ function filter_system_from_mail() { return get_option( 'wp_mail_from' == current_filter() ? 'admin_email' : 'blogname' ); } add_filter( 'wp_mail_from', 'filter_system_from_mail' ); add_filter( 'wp_mail_from_name', 'filter_system_from_mail' ); }
Or … did I misread your question?
-
Oui,cela signifiait une approche unpeu différente.Exemple ajouté.Yep, meant a bit different approach. Added example.
- 0
- 2011-03-05
- Rarst
-
- 2011-08-14
Fonctions anonymes ou lambda) Danstous les cas,je les éviterais,car vousne connaîtrezpas lenom oun'obtiendrezpas une sortie assez cryptique si vousinspectez un hookplustard. Le débogage seraitpénible.
Annoncez votre A) L'approcheestintéressanteet offre une API assez simple (+1).
Ad @hakre A) J'utilise àpeuprès lamêmefonction [1] dans lenoyau demonframework - étenduepar "set_" & amp; uneexception -pour définiret obtenir des variables à la volée. De cettefaçon,je n'ai qu'à étendre cette classe avec une classeenfant qui ressemble à uneinterface "variable seulement" (celles qui seront disponibles). C'est une approche agréableet organisée quine conserve que les éléments dans lesfichiers quine servent qu'une seuletâche. Avec quelque chose comme ça,vouspouvezpeut-être éviter d'écrire desfonctions spécifiquespour chaquetâche comme "_replace",etc.
[1] Code - Je l'exécutetout letempspour que vouspuissiez l'appeler "testé -et fonctionne"
/** * Magic getter/setter method * Guesses for a class variable & calls/fills it or throws an exception. * Note: Already defined methods override this method. * * Original @author Miles Keaton <[email protected]> * on {@link http://www.php.net/manual/de/language.oop5.overloading.php#48440} * The function was extended to also allow 'set' tasks/calls and throws an exception. * * @param (string) $name | Name of the property * @param unknown_type $args | arguments the function can take */ function __call( $name, $args ) { $_get = false; // See if we're calling a getter method & try to guess the variable requested if( substr( $val, 0, 4 ) == 'get_' ) { $_get = true; $varname = substr( $val, 4 ); } elseif( substr( $val, 0, 3 ) == 'get' ) { $_get = true; $varname = substr( $val, 3 ); } // See if we're calling a setter method & try to guess the variable requested if( substr( $val, 0, 4 ) == 'set_' ) { $varname = substr( $val, 4 ); } elseif( substr( $val, 0, 3 ) == 'set' ) { $varname = substr( $val, 3 ); } if ( ! isset( $varname ) ) return new Exception( sprintf( __( "The method %1$s doesn't exist" ), "<em>{$val}</em>" ) ); // Now see if that variable exists: foreach( $this as $class_var => $class_var_value ) { if ( strtolower( $class_var ) == strtolower( $varname ) ) { // GET if ( $_get ) { return $this->{$class_var}; } // SET else { return $this->{$class_var} = $x[0]; } } } return false; }
Ad anonymous or lambda functions) In every case I would avoid these, as you won't know the name or get a pretty cryptic output if you inspect a hook later. Debugging would be a pain.
Ad your A) The approach looks nice and offers a pretty simple API (+1).
Ad @hakre A) I use pretty much the same function[1] in my frameworks core - extended by "set_" & an exception - to set and get variables on the fly. This way I only have to extend this class with a child class that looks like a "variable only"-interface (those which shall be available). It's a nice and organized approach that only keeps stuff in the files that serves a single task. With something like this you can maybe avoid writing specific functions for each and every taks like "_replace", etc.
[1] Code - I run this all the time so you can call it "tested - and works"
/** * Magic getter/setter method * Guesses for a class variable & calls/fills it or throws an exception. * Note: Already defined methods override this method. * * Original @author Miles Keaton <[email protected]> * on {@link http://www.php.net/manual/de/language.oop5.overloading.php#48440} * The function was extended to also allow 'set' tasks/calls and throws an exception. * * @param (string) $name | Name of the property * @param unknown_type $args | arguments the function can take */ function __call( $name, $args ) { $_get = false; // See if we're calling a getter method & try to guess the variable requested if( substr( $val, 0, 4 ) == 'get_' ) { $_get = true; $varname = substr( $val, 4 ); } elseif( substr( $val, 0, 3 ) == 'get' ) { $_get = true; $varname = substr( $val, 3 ); } // See if we're calling a setter method & try to guess the variable requested if( substr( $val, 0, 4 ) == 'set_' ) { $varname = substr( $val, 4 ); } elseif( substr( $val, 0, 3 ) == 'set' ) { $varname = substr( $val, 3 ); } if ( ! isset( $varname ) ) return new Exception( sprintf( __( "The method %1$s doesn't exist" ), "<em>{$val}</em>" ) ); // Now see if that variable exists: foreach( $this as $class_var => $class_var_value ) { if ( strtolower( $class_var ) == strtolower( $varname ) ) { // GET if ( $_get ) { return $this->{$class_var}; } // SET else { return $this->{$class_var} = $x[0]; } } } return false; }
add_action()
etadd_filter()
sont desfonctionsmajeures. Cependant,dans certains scénarios, ajoutez unefonction supplémentaireet accrochez-la quelquepart l'approche devientencombranteet peupratique.J'avais déterminépourmoi-mêmeplusieurs cas d'utilisation quipeuvent rationaliser le code avec des wrappersen plus desfonctions
add_*
. Des choses qui sontmieuxgérées avec une seule ligne qu'unefonction supplémentaire à chaquefois.Ajouter un retour defiltre arbitraire . Ilexiste déjà desfonctions
__return_*
maiselles sonttrès limitéespar définition. Pourquoine pas simplementpasser ce que vous voulez dans lefiltre. Sauvegarde d'unemyriade defunction return_stuff(){return 'stuff';}
Remplacez Xpar Y dans lefiltre . Sauvegarde d'unemyriade de
function replace_stuff(){return str_replace();}
Ajouter une action avec des arguments arbitraires . Les actions se déclenchent avec des arguments,passéesen hook. Maisparfois,vousne vous souciezpas de celaet vous voulez simplementexécuter votrefonction avec vospropres arguments à un hook spécifique. Sauvegarde àpartir d'unemyriade de
function echo_stuff(){echo 'stuff'};
et plus.Alors ...
Y a-t-il d'autres cas d'utilisation que vous souhaitezet/ou utiliser dans lapratique?
Commentimplémenteriez-vous detels wrappers? Ilexiste denombreuses approchespossibles (fermetures,variablesglobalespour conserver des arguments supplémentaires,passer des objetsen callback,etc.).
PS J'ai déjà quelquesimplémentations différentespour (1) et (3) et (comme suggéré)publierai desmorceaux demon code quelquetempsplustardpourne pasgâcher leplaisir. :)
<₹Example
Chemin actuel:
Emballage: