Passer un paramètre aux fonctions de filtrage et d'action
-
-
vouspouvez utiliser $ _SESSIONpour stockeret obtenir desparamètres.you can use $_SESSION to store and get parameteres.
- 0
- 2020-07-10
- Sunil Kumar
-
12 réponses
- votes
-
- 2012-03-17
Par défaut,celan'estpaspossible. Ilexiste des solutions de contournement si vousprocédez de lamanière POO.
Vouspouvez créer une classepour stocker les valeurs que vous souhaitez utiliserplustard.Exemple:
/** * Stores a value and calls any existing function with this value. */ class WPSE_Filter_Storage { /** * Filled by __construct(). Used by __call(). * * @type mixed Any type you need. */ private $values; /** * Stores the values for later use. * * @param mixed $values */ public function __construct( $values ) { $this->values = $values; } /** * Catches all function calls except __construct(). * * Be aware: Even if the function is called with just one string as an * argument it will be sent as an array. * * @param string $callback Function name * @param array $arguments * @return mixed * @throws InvalidArgumentException */ public function __call( $callback, $arguments ) { if ( is_callable( $callback ) ) return call_user_func( $callback, $arguments, $this->values ); // Wrong function called. throw new InvalidArgumentException( sprintf( 'File: %1$s<br>Line %2$d<br>Not callable: %3$s', __FILE__, __LINE__, print_r( $callback, TRUE ) ) ); } }
Vouspouvezmaintenant appeler la classe avecn'importe quellefonction de votre choix - si lafonctionexiste quelquepart,elle sera appelée avec vosparamètres stockés.
Créons unefonction de démonstration…
/** * Filter function. * @param array $content * @param array $numbers * @return string */ function wpse_45901_add_numbers( $args, $numbers ) { $content = $args[0]; return $content . '<p>' . implode( ', ', $numbers ) . '</p>'; }
…et l'utiliser unefois…
add_filter( 'the_content', array ( new WPSE_Filter_Storage( array ( 1, 3, 5 ) ), 'wpse_45901_add_numbers' ) );
…et encore…
add_filter( 'the_content', array ( new WPSE_Filter_Storage( array ( 2, 4, 6 ) ), 'wpse_45901_add_numbers' ) );
Sortie:
La cléest la réutilisabilité : vouspouvez réutiliser la classe (et dansnosexemples également lafonction).
PHP 5.3+
Si vouspouvez utiliser une version 5.3 de PHP ou une versionplus récente,fermetures fera quebeaucoupplusfacile:
$param1 = '<p>This works!</p>'; $param2 = 'This works too!'; add_action( 'wp_footer', function() use ( $param1 ) { echo $param1; }, 11 ); add_filter( 'the_content', function( $content ) use ( $param2 ) { return t5_param_test( $content, $param2 ); }, 12 ); /** * Add a string to post content * * @param string $content * @param string $string This is $param2 in our example. * @return string */ function t5_param_test( $content, $string ) { return "$content <p><b>$string</b></p>"; }
L'inconvénientest que vousne pouvezpas écrire detests unitairespour lesfermetures.
By default this is not possible. There are workarounds if you do it the OOP way.
You could create a class to store the values you want to use later.Example:
/** * Stores a value and calls any existing function with this value. */ class WPSE_Filter_Storage { /** * Filled by __construct(). Used by __call(). * * @type mixed Any type you need. */ private $values; /** * Stores the values for later use. * * @param mixed $values */ public function __construct( $values ) { $this->values = $values; } /** * Catches all function calls except __construct(). * * Be aware: Even if the function is called with just one string as an * argument it will be sent as an array. * * @param string $callback Function name * @param array $arguments * @return mixed * @throws InvalidArgumentException */ public function __call( $callback, $arguments ) { if ( is_callable( $callback ) ) return call_user_func( $callback, $arguments, $this->values ); // Wrong function called. throw new InvalidArgumentException( sprintf( 'File: %1$s<br>Line %2$d<br>Not callable: %3$s', __FILE__, __LINE__, print_r( $callback, TRUE ) ) ); } }
Now you can call the class with any function you want – if the function exists somewhere it will be called with your stored parameters.
Let’s create a demo function …
/** * Filter function. * @param array $content * @param array $numbers * @return string */ function wpse_45901_add_numbers( $args, $numbers ) { $content = $args[0]; return $content . '<p>' . implode( ', ', $numbers ) . '</p>'; }
… and use it once …
add_filter( 'the_content', array ( new WPSE_Filter_Storage( array ( 1, 3, 5 ) ), 'wpse_45901_add_numbers' ) );
… and again …
add_filter( 'the_content', array ( new WPSE_Filter_Storage( array ( 2, 4, 6 ) ), 'wpse_45901_add_numbers' ) );
Output:
The key is reusability: You can reuse the class (and in our examples also the function).
PHP 5.3+
If you can use a PHP version 5.3 or newer closures will make that much easier:
$param1 = '<p>This works!</p>'; $param2 = 'This works too!'; add_action( 'wp_footer', function() use ( $param1 ) { echo $param1; }, 11 ); add_filter( 'the_content', function( $content ) use ( $param2 ) { return t5_param_test( $content, $param2 ); }, 12 ); /** * Add a string to post content * * @param string $content * @param string $string This is $param2 in our example. * @return string */ function t5_param_test( $content, $string ) { return "$content <p><b>$string</b></p>"; }
The downside is that you cannot write unit tests for closures.
-
Non seulement vous obtenez un votepour une réponse de qualité à unproblème qui ** devrait avoir une solutionintégrée dans WP core **,vousen obtenez également unepour revenir cinqmoisplustardpourmettre àjour votre réponse avec PHP 5.3+exemple defermeture.Not only do you get an up-vote for a quality answer to a problem that **should have a built in solution within WP core**, you also get one for coming back five months later to update your answer with the PHP 5.3+ closure example.
- 19
- 2013-11-17
- Adam
-
Excellente réponse!Mais commentpuis-je supprimer cefiltre créépar cettefonction anonymeplustard?Excellent answer! But how can I do to remove this filter created by this anonymous function later?
- 1
- 2014-08-12
- Vinicius Tavares
-
@ViniciusTavares Vousne pouvezpas.Réfléchissez avant de l'utiliser.:)@ViniciusTavares You can’t. Think before you use it. :)
- 3
- 2014-08-12
- fuxia
-
Notez cependant que si vousenregistrez lafonction anonyme dans une variable (parexemple `$func=function () use ($param1) {$param1;};`et `add_action ($func,11);`) alors vouspouvez la supprimervia `remove_action ($func,11);`Note though that if you save the anonymous function to a variable (eg `$func = function() use ( $param1 ) { $param1; };` and `add_action( $func, 11);`) then you can remove it via `remove_action( $func, 11 );`
- 6
- 2015-05-02
- bonger
-
Maisiln'estpas conseillé d'utiliser desfonctions anonymes sur lesplugins ou lesthèmes que vouspubliez dans lemonde (vouspouvez les utiliser sur vospropresprojets).Leproblème avec celaest que vousne pourrezpas les décrocher.Quelle que soit l'approche que vous décidez d'adopter,elle devrait être décrochéeplustard.But its not advisable to use anonymous functions on plugins or themes you are releasing to the world (you can use them on your own projects). Problem with this is that you won't be able to unhook them. What ever approach you decide to go with should be unhook-able later.
- 1
- 2018-02-22
- Mueyiwa Moses Ikomi
-
- 2016-01-20
Créez unefonction avec les argumentsnécessaires qui renvoie unefonction.Passez cettefonction (fonction anonyme,également appeléefermeture) au hook wp.
Montréicipour un avis d'administrateur dans lebackend wordpress.
public function admin_notice_func( $message = '') { $class = 'error'; $output = sprintf('<div class="%s"><p>%s</p></div>',$class, $message); $func = function() use($output) { print $output; }; return $func; } $func = admin_notice_func('Message'); add_action('admin_notices', $func);
Create a function with the needed arguments that returns a function. Pass this function (anonymous function, also known as closure) to the wp hook.
Shown here for an admin notice in wordpress backend.
public function admin_notice_func( $message = '') { $class = 'error'; $output = sprintf('<div class="%s"><p>%s</p></div>',$class, $message); $func = function() use($output) { print $output; }; return $func; } $func = admin_notice_func('Message'); add_action('admin_notices', $func);
-
- 2016-01-23
Utilisezphp Fonctions anonymes :
$my_param = 'my theme name'; add_filter('the_content', function ($content) use ($my_param) { //$my_param is available for you now if (is_page()) { $content = $my_param . ':<br>' . $content; } return $content; }, 10, 1);
Use php Anonymous functions:
$my_param = 'my theme name'; add_filter('the_content', function ($content) use ($my_param) { //$my_param is available for you now if (is_page()) { $content = $my_param . ':<br>' . $content; } return $content; }, 10, 1);
-
- 2017-02-16
Je sais que letemps apassé,maisj'aieu unproblème avec latransmission demonpropreparamètrejusqu'à ce queje trouve que le 4èmeparamètre dans add_filterest lenombre deparamètrespassés y compris le contenu àmodifier.Donc,si vouspassez 1paramètre supplémentaire,lenombre doit être 2 et non 1 dans votre cas
add_filter('the_content', 'my_content', 10, 2, $my_param)
et en utilisant
function my_content($content, $my_param) {...}
I know time have passed, but I had some problem with passing my own parameter till I found that the the 4th parameter in add_filter is number of passed parameters including the content to change. So if you pass 1 additional parameter, number should be 2 and not 1 in your case
add_filter('the_content', 'my_content', 10, 2, $my_param)
and using
function my_content($content, $my_param) {...}
-
- 2018-10-14
Lemoyen correct,très courtet leplusefficace detransmettre lenombre d'arguments auxfiltreset actions WPest de @Wesam Alalem ici ,qui utilise lafermeture.
J'ajouterais seulement que vouspourriez le rendreencoreplus clairet beaucoupplusflexibleen séparant laméthode réelle de l'action de lafermeture anonyme. Pour cela,il vous suffit d'appeler laméthode de lafermeture comme suit (exemplemodifié de la réponse @Wesam Alalem).
De cettefaçon,vouspouvez écrire une logique aussi longue ou compliquée que vous le souhaitez lexicalementen dehors de lafermeture que vous utilisezpour appeler l'acteur réel.
// ... inside some class private function myMethod() { $my_param = 'my theme name'; add_filter('the_content', function ($content) use ($my_param) { // This is the anonymous closure that allows to pass // whatever number of parameters you want via 'use' keyword. // This is just oneliner. // $my_param is available for you now via 'use' keyword above return $this->doThings($content, $my_param); }, 10, 2); } private function doThings($content, $my_param) { // Call here some other method to do some more things // however complicated you want. $morethings = ''; if ($content = 'some more things') { $morethings = (new MoreClass())->get(); } return $my_param . ':<br>' . $content . $morethings; }
The correct, really short and most efficient way of passing whatever number of arguments to WP filters and actions is from @Wesam Alalem here, that uses the closure.
I would only add that you could make it even clearer and much more flexible by separating the actual doer method from anonymous closure. For this you just call the method from the closure as follows (modified example from @Wesam Alalem answer).
This way you can write as long or complicated logic as you wish lexically outside of the closure you use to call the actual doer.
// ... inside some class private function myMethod() { $my_param = 'my theme name'; add_filter('the_content', function ($content) use ($my_param) { // This is the anonymous closure that allows to pass // whatever number of parameters you want via 'use' keyword. // This is just oneliner. // $my_param is available for you now via 'use' keyword above return $this->doThings($content, $my_param); }, 10, 2); } private function doThings($content, $my_param) { // Call here some other method to do some more things // however complicated you want. $morethings = ''; if ($content = 'some more things') { $morethings = (new MoreClass())->get(); } return $my_param . ':<br>' . $content . $morethings; }
-
- 2020-05-07
Commementionné dans d'autres réponses,passer unparamètre à lafonction de rappeln'estpaspossiblepar défaut. La POOet lafonction anonyme PHP sont des solutions de contournement MAIS :
- Votre coden'estpeut-êtrepasen POO
- Vous devrezpeut-être supprimer cefiltre par la suite
Sitelest votre cas,ilexiste une autre solution de contournement à utiliser: utilisez lesfonctions
add_filter
etapply_filters
pour rendre disponible leparamètre que vous vouleztransmettre dans lafonction de rappel:// Workaround to "save" parameter to be passed to your callback function. add_filter( 'pass_param', function() use ( $param ){ return $param; } ); // Hook your function to filter whatever you want to filter. add_filter( 'actual_filter', 'myCallback' ); // Your callback function that actually filters whatever you want to filter. function myCallback() { // Get the param that we were not able to pass to this callback function. $param = apply_filters( 'pass_param', '' ); // Do whatever with the workarounded-passed param so it can be used to filter. return $param; }
As mentioned on other answers, passing a parameter to the callback function is not possible by default. OOP and PHP anonymous function are workarounds BUT:
- Your code might not be OOP
- You might need to remove that filter afterwards
If that is your case, there is another workaround for you to use: make yourself use of the
add_filter
andapply_filters
functions to make that parameter you want to pass available in the callback function:// Workaround to "save" parameter to be passed to your callback function. add_filter( 'pass_param', function() use ( $param ){ return $param; } ); // Hook your function to filter whatever you want to filter. add_filter( 'actual_filter', 'myCallback' ); // Your callback function that actually filters whatever you want to filter. function myCallback() { // Get the param that we were not able to pass to this callback function. $param = apply_filters( 'pass_param', '' ); // Do whatever with the workarounded-passed param so it can be used to filter. return $param; }
-
- 2015-05-14
si vous créez votrepropre hook,voici unexemple.
// lets say we have three parameters [ https://codex.wordpress.org/Function_Reference/add_filter ] add_filter( 'filter_name', 'my_func', 10, 3 ); my_func( $first, $second, $third ) { // code }
puisimplémentez le hook:
// [ https://codex.wordpress.org/Function_Reference/apply_filters ] echo apply_filters( 'filter_name', $first, $second, $third );
if you create your own hook, here is example.
// lets say we have three parameters [ https://codex.wordpress.org/Function_Reference/add_filter ] add_filter( 'filter_name', 'my_func', 10, 3 ); my_func( $first, $second, $third ) { // code }
then implement hook:
// [ https://codex.wordpress.org/Function_Reference/apply_filters ] echo apply_filters( 'filter_name', $first, $second, $third );
-
Celane transmetpas lesinformations de l'enregistrement au rappel.Ilindique simplement combien deparamètres le rappelpeut accepter.This doesn't pass information from the registration to the callback. It just says how many parameters the callback can accept.
- 0
- 2015-05-17
- fuxia
-
@fuxia,pouvez-vous suggérer un changement simplepour que lesinformations soienttransmises?Voudrait-on simplement coller sur les valeurs desparamètres après le «3»?@fuxia, can you suggest a simple change so the information does get passed? Would one just tack on the param values after the `3`?
- 0
- 2019-05-25
- SherylHohman
-
-
Celane répondpas à la question.Unefois que vous aurez une [réputation] suffisante (https://wordpress.stackexchange.com/help/whats-reputation),vouspourrez [commentern'importe quelmessage] (https://wordpress.stackexchange.com/help/privileges/commentaire);à laplace,[fournissez des réponses quine nécessitentpas de clarification de lapart du demandeur] (https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-à laplace).- [De l'avis] (/review/low-quality-posts/143498)This does not provide an answer to the question. Once you have sufficient [reputation](https://wordpress.stackexchange.com/help/whats-reputation) you will be able to [comment on any post](https://wordpress.stackexchange.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/low-quality-posts/143498)
- 0
- 2017-08-25
- cjbj
-
@cjbj Enfait,c'est le cas.La questionest de savoir si lesparamètrespeuvent êtrepassés à la "fonction" qui setrouve dans add_filter ou add_action.Iln'étaitpas clair si l'utilisateur voulait lepasser dans lafonction add_filter ou add_actionelle-même,même si c'est l'hypothèse.:)@cjbj Actually it does. The question is can parameters be passed to the "function" that is in add_filter or add_action. It wasn't clear if the user wanted to pass it in the add_filter or add_action function itself even though that is the assumption. :)
- 0
- 2017-08-25
- samjco
-
-
- 2019-10-25
Bien que vous appeliez directement unefonction,faites-le d'unemanièreplus élégante: passez unefonction anonyme comme rappel.
Parexemple:
J'ai une seulefonctionpourtraduire letitre,le contenuet l'extrait demes articles.Donc,je doispasser à cettefonctionprincipale des argumentsindiquant qui appelle.
add_filter( 'the_title', function( $text ) { return translate_text( $text, 'title', 'pl' ); }); add_filter( 'the_content', function( $text ) { return translate_text( $text, 'content', 'pl' ); }); add_filter( 'the_excerpt', function( $text ) { return translate_text( $text, 'excerpt', 'pl' ); });
Ainsi,lafonctionprincipale
translate_text
reçoit autant deparamètres queje veux,simplementparce quej'aipassé unefonction anonyme comme rappel.Despite calling a function directly, do this in a more elegant way: pass an anonymous function as a callback.
For example:
I have a single function to translate the title, content, and excerpt from my posts. So, I need to pass to this main function some arguments saying who is calling.
add_filter( 'the_title', function( $text ) { return translate_text( $text, 'title', 'pl' ); }); add_filter( 'the_content', function( $text ) { return translate_text( $text, 'content', 'pl' ); }); add_filter( 'the_excerpt', function( $text ) { return translate_text( $text, 'excerpt', 'pl' ); });
So, the main function
translate_text
receives as many parameters as I want, just because I have passed an anonymous function as a callback. -
- 2020-06-22
Je suis d'accord que la réponse defuxia ci-dessus donne les approchespréférées. Maispendant quej'essayais de comprendre la solution POO,j'aitrouvé unmoyen de lefaire qui définitpuis désactive à lafois lefiltreet une variableglobale:
function my_function() { // Declare the global variable and set it to something global $my_global; $my_global = 'something'; // Add the filter add_filter( 'some_filter', 'my_filter_function' ); // Do whatever it is that you needed the filter for echo $filtered_stuff; // Remove the filter (So it doesn't mess up something else that executes later) remove_filter( 'some_filter', 'my_filter_function' ); // Unset the global (Because we don't like globals floating around in our code) my_unset_function( 'my_global' ); } function my_filter_function( $arg ) { // Declare the global global $my_global // Use $my_global to do something with $arg $arg = $arg . $my_global; return $arg; } function my_unset_function( $var_name ) { // Declare the global $GLOBALS[$var_name]; // Unset the global unset($GLOBALS[$var_name]; }
Je suis un développeurnonforméet jetravaille strictement surmespropres sites,veuillez doncprendre cetteesquisse avec ungrain de sel. Celafonctionnepourmoi,mais s'il y a quelque chose quine vapas dans ce queje faisici,je serais reconnaissant à quelqu'un deplus compétent de le signaler.
I agree that fuxia's answer above gives the preferred approaches. But while I was trying to wrap my head around the OOP solution I hit upon a way of doing it that sets and then unsets both the filter and a global variable:
function my_function() { // Declare the global variable and set it to something global $my_global; $my_global = 'something'; // Add the filter add_filter( 'some_filter', 'my_filter_function' ); // Do whatever it is that you needed the filter for echo $filtered_stuff; // Remove the filter (So it doesn't mess up something else that executes later) remove_filter( 'some_filter', 'my_filter_function' ); // Unset the global (Because we don't like globals floating around in our code) my_unset_function( 'my_global' ); } function my_filter_function( $arg ) { // Declare the global global $my_global // Use $my_global to do something with $arg $arg = $arg . $my_global; return $arg; } function my_unset_function( $var_name ) { // Declare the global $GLOBALS[$var_name]; // Unset the global unset($GLOBALS[$var_name]; }
I'm an untrained developer and I work strictly on my own sites, so please take this sketch with a grain of salt. It works for me, but if there's something wrong with what I'm doing here I'd be grateful if someone more knowledgeable would point it out.
-
Les variablesglobalesne sontpasprotégées:n'importe quipeut les définir surn'importe quelle valeur (pensez aux collisions denoms),et elles sonttrès difficiles à déboguer.Engénéral,ils sont considérés comme unemauvaisepratique.Global variables are unprotected: anyone can set them to any value (think naming collisions), and they are very hard to debug. In general, they are seen as bad practice.
- 0
- 2020-06-22
- fuxia
-
- 2020-07-25
Dansma solution POO,j'ai simplement utilisé une variable demembre de classe quiest appelée dans lafonction de rappel. Dans cetexemple,lepost_titleestfiltrépar unterme de recherche:
class MyClass { protected $searchterm = ''; protected function myFunction() { query = [ 'numberposts' => -1, 'post_type' => 'my_custom_posttype', 'post_status' => 'publish' ]; $this->searchterm = 'xyz'; add_filter('posts_where', [$this, 'searchtermPostsWhere']); $myPosts = get_posts($query); remove_filter('posts_where', [$this, 'searchtermPostsWhere']); } public function searchtermPostsWhere($where) { $where .= ' AND ' . $GLOBALS['wpdb']->posts . '.post_title LIKE \'%' . esc_sql(like_escape($this->searchterm)) . '%\''; return $where; } }
In my OOP solution I simply used a class member variable which is called in the callback function. In this example the post_title is filtered by a searchterm:
class MyClass { protected $searchterm = ''; protected function myFunction() { query = [ 'numberposts' => -1, 'post_type' => 'my_custom_posttype', 'post_status' => 'publish' ]; $this->searchterm = 'xyz'; add_filter('posts_where', [$this, 'searchtermPostsWhere']); $myPosts = get_posts($query); remove_filter('posts_where', [$this, 'searchtermPostsWhere']); } public function searchtermPostsWhere($where) { $where .= ' AND ' . $GLOBALS['wpdb']->posts . '.post_title LIKE \'%' . esc_sql(like_escape($this->searchterm)) . '%\''; return $where; } }
-
- 2017-12-12
J'espéraisfaire lamême chosemais comme cen'estpaspossible,je suppose qu'une solution simple consiste à appeler unefonction différente
add_filter('the_content', 'my_content_filter', 10, 1);
alorsmy_content_filter ()peut simplement appelermy_content ()en passant l'argument de son choix.
I was hoping to do the same but since its not possible I guess a simple workaround is to call a different function like
add_filter('the_content', 'my_content_filter', 10, 1);
then my_content_filter() can just call my_content() passing any argument it wants.
Est unmoyen detransmettremespropresparamètres à lafonction dans
add_filter
ouadd_action
. Parexemple,regardez dans le code suivant:Puis-jetransmettremonpropreparamètre?quelque chose comme:
ou