web-dev-qa-db-fra.com

puis-je passer des arguments à ma fonction via add_action?

puis-je faire quelque chose comme ça? passer des arguments à ma fonction? J'ai déjà étudié add_action doc mais je ne savais pas comment le faire. À quoi ressemblerait la syntaxe exacte à utiliser pour passer deux arguments? En particulier, comment passer les arguments text & integer.

function recent_post_by_author($author,$number_of_posts) {
  some commands;
}
add_action('thesis_hook_before_post','recent_post_by_author',10,'author,2')

METTRE À JOUR

il me semble que cela se fait d'une manière ou d'une autre par do_action mais comment? :-)

29
Radek

puis-je faire quelque chose comme ça? passer des arguments à ma fonction?

Oui, vous pouvez! Le truc est vraiment de savoir quel type de fonction vous passez à add_action et ce que vous attendez de do_action .

  • 'Nom_fonction_m'
  • tableau (instance, 'nom_fonction_instance')
  • 'StaticClassName :: a_function_on_static_class'
  • anonyme
  • lambda
  • fermeture

Nous pouvons le faire avec un fermeture .

// custom args for hook

$args = array (
    'author'        =>  6, // id
    'posts_per_page'=>  1, // max posts
);

// subscribe to the hook w/custom args

add_action('thesis_hook_before_post', 
           function() use ( $args ) { 
               recent_post_by_author( $args ); });


// trigger the hook somewhere

do_action( 'thesis_hook_before_post' );


// renders a list of post tiles by author

function recent_post_by_author( $args ) {

    // merge w/default args
    $args = wp_parse_args( $args, array (
        'author'        =>  -1,
        'orderby'       =>  'post_date',
        'order'         =>  'ASC',
        'posts_per_page'=>  25
    ));

    // pull the user's posts
    $user_posts = get_posts( $args );

    // some commands
    echo '<ul>';
    foreach ( $user_posts as $post ) {
        echo "<li>$post->post_title</li>";
    }
    echo '</ul>';
}

Voici un exemple simplifié de fermeture fonctionnant

$total = array();

add_action('count_em_dude', function() use (&$total) { $total[] = count($total); } );

do_action ('count_em_dude' );
do_action ('count_em_dude' );
do_action ('count_em_dude' );
do_action ('count_em_dude' );
do_action ('count_em_dude' );
do_action ('count_em_dude' );
do_action ('count_em_dude' );

echo implode ( ', ', $total ); // 0, 1, 2, 3, 4, 5, 6

Anonyme vs fermeture

add_action ('custom_action', function(){ echo 'anonymous functions work without args!'; } ); //

add_action ('custom_action', function($a, $b, $c, $d){ echo 'anonymous functions work but default args num is 1, the rest are null - '; var_dump(array($a,$b,$c,$d)); } ); // a

add_action ('custom_action', function($a, $b, $c, $d){ echo 'anonymous functions work if you specify number of args after priority - '; var_dump(array($a,$b,$c,$d)); }, 10, 4 ); // a,b,c,d

// CLOSURE

$value = 12345;
add_action ('custom_action', function($a, $b, $c, $d) use ($value) { echo 'closures allow you to include values - '; var_dump(array($a,$b,$c,$d, $value)); }, 10, 4 ); // a,b,c,d, 12345

// DO IT!

do_action( 'custom_action', 'aa', 'bb', 'cc', 'dd' ); 

Classe de fonctions proxy

class ProxyFunc {
    public $args = null;
    public $func = null;
    public $location = null;
    public $func_args = null;
    function __construct($func, $args, $location='after', $action='', $priority = 10, $accepted_args = 1) {
        $this->func = $func;
        $this->args = is_array($args) ? $args : array($args);
        $this->location = $location;
        if( ! empty($action) ){
            // (optional) pass action in constructor to automatically subscribe
            add_action($action, $this, $priority, $accepted_args );
        }
    }
    function __invoke() {
        // current arguments passed to invoke
        $this->func_args = func_get_args();

        // position of stored arguments
        switch($this->location){
            case 'after':
                $args = array_merge($this->func_args, $this->args );
                break;
            case 'before':
                $args = array_merge($this->args, $this->func_args );
                break;
            case 'replace':
                $args = $this->args;
                break;
            case 'reference':
                // only pass reference to this object
                $args = array($this);
                break;
            default:
                // ignore stored args
                $args = $this->func_args;
        }

        // trigger the callback
        call_user_func_array( $this->func, $args );

        // clear current args
        $this->func_args = null;
    }
}

Exemple d'utilisation n ° 1

$proxyFunc = new ProxyFunc(
    function() {
        echo "<pre>"; print_r( func_get_args() ); wp_die();
    },
    array(1,2,3), 'after'
);

add_action('TestProxyFunc', $proxyFunc );
do_action('TestProxyFunc', 'Hello World', 'Goodbye'); // Hello World, 1, 2, 3

Exemple d'utilisation n ° 2

$proxyFunc = new ProxyFunc(
    function() {
        echo "<pre>"; print_r( func_get_args() ); wp_die();
    },                  // callback function
    array(1,2,3),       // stored args
    'after',            // position of stored args
    'TestProxyFunc',    // (optional) action
    10,                 // (optional) priority
    2                   // (optional) increase the action args length.
);
do_action('TestProxyFunc', 'Hello World', 'Goodbye'); // Hello World, Goodbye, 1, 2, 3
30
jgraup

Au lieu de:

add_action('thesis_hook_before_post','recent_post_by_author',10,'author,2')

cA devrait etre:

add_action('thesis_hook_before_post','recent_post_by_author',10,2)

... où 2 est le nombre d'arguments et 10 la priorité dans laquelle la fonction sera exécutée. Vous ne listez pas vos arguments dans add_action. Cela m'a tout d'abord fait trébucher. Votre fonction ressemble alors à ceci:

function function_name ( $arg1, $arg2 ) { /* do stuff here */ }

Add_action et function vont tous deux dans functions.php et vous spécifiez vos arguments dans le fichier de modèle (page.php par exemple) avec do_action comme ceci:

do_action( 'name-of-action', $arg1, $arg2 );

J'espère que cela t'aides.

28
Bart

Construire des fonctions WP personnalisées avec des classes

C'est facile avec les classes, car vous pouvez définir des variables d'objet avec le constructeur et les utiliser dans n'importe quelle méthode de classe. Donc, pour un exemple, voici comment l'ajout de boîtes de méta pourrait fonctionner dans les classes ...

// Array to pass to class
$data = array(
    "meta_id" => "custom_wp_meta",
    "a" => true,
    "b" => true,
    // etc...
);

// Init class
$var = new yourWpClass ($data);

// Class
class yourWpClass {

    // Pass $data var to class
    function __construct($init) {
        $this->box = $init; // Get data in var
        $this->meta_id = $init["meta_id"];
        add_action( 'add_meta_boxes', array(&$this, '_reg_meta') );
    }
    public function _reg_meta() {
        add_meta_box(
            $this->meta_id,
            // etc ....
        );
    }
}

Si vous considérez que __construct($arg) est identique à function functionname($arg), vous devriez pouvoir éviter les variables globales et transmettre toutes les informations nécessaires aux fonctions de l'objet de classe.

Ces pages semblent être de bons points de référence lors de la construction de meta/plugins wordpress ->

16
reekogi

Fondamentalement, le do_action est placé à l'endroit où l'action doit être exécutée et nécessite un nom ainsi que vos paramètres personnalisés. 

Lorsque vous appelez la fonction avec add_action, transmettez le nom de votre do_action() en tant que premier argument et le nom de la fonction en tant que second. Donc, quelque chose comme:

function recent_post_by_author($author,$number_of_posts) {
  some commands;
}
add_action('get_the_data','recent_post_by_author',10,'author,2');

C'est là qu'il est exécuté

do_action('get_the_data',$author,$number_of_posts);

Si tout va bien travailler.

6
hollsk

J'utilise la fermeture pour PHP 5.3+. Je peux alors passer les valeurs par défaut et les miennes sans globales. (exemple pour add_filter)

...
$tt="try this";

add_filter( 'the_posts', function($posts,$query=false) use ($tt) {
echo $tt;
print_r($posts);
return  $posts;
} );
2
Miguel

J'ai rencontré le même problème et l'ai résolu en utilisant des variables globales. Ainsi:

global $myvar;
$myvar = value;
add_action('hook', 'myfunction');

function myfunction() {
    global $myvar;
}

Un peu bâclé mais ça marche.

2
LukeSideris

C'est vieux, mais il n'y a pas de réponse acceptée. Réanimer pour que les internautes de Google aient un peu d'espoir.

Si vous avez un appel add_action existant qui n'accepte pas les arguments tels que ceux-ci:

function my_function() {
  echo 100;
}

add_action('wp_footer', 'my_function');

Vous pouvez passer un argument à cette fonction en utilisant une fonction anonyme comme rappel comme ceci:

function my_function($number) {
  echo $number;
}

$number = 101;
add_action('wp_footer', function() { global $number; my_function($number); });

En fonction de votre cas d'utilisation, vous devrez peut-être utiliser différentes formes de rappel, voire utiliser des fonctions correctement déclarées, car vous pourriez parfois rencontrer des problèmes avec la portée.

2
Sam Bauers

J'ai écrit un plugin wordpress il y a longtemps, mais je suis allé à Wordpress Codex et je pense que c'est possible: http://codex.wordpress.org/Function_Reference/add_action

<?php add_action( $tag, $function_to_add, $priority, $accepted_args ); ?> 

Je pense que vous devriez les passer comme un tableau. Regardez dans les exemples "prendre des arguments".

Au revoir

1
dierre

Si vous souhaitez passer des paramètres à la fonction appelable, vous pouvez appeler une fonction anonyme à la place de la fonction do_action. Exemple:

// Route Web Requests
add_action('shutdown', function() {
    Router::singleton()->routeRequests('app.php');
});

Vous voyez que do_action('shutdown') n'accepte aucun paramètre, mais routeRequests le fait.

0
Lucas Bustamante