Le meilleur moyen de mettre fin à la demande WordPress ajax et pourquoi?

16

Considérant les demandes ajax WordPress régulières comme celles-ci:

add_action( 'wp_ajax_merrychristmas_happynewyear', array( $this, 'merrychristmas_happynewyear' ) );
add_action( 'wp_ajax_nopriv_merrychristmas_happynewyear', array( $this, 'merrychristmas_happynewyear' ) );

Sera - ce le mieux à la fonction fin merrychristmas_happynewyearavec die(), die(0), wp_die()ou autre chose et pourquoi?

prosti
la source

Réponses:

13

L'utilisation wp_die()est la meilleure de ces options.

Comme d'autres l'ont noté, il existe de nombreuses raisons de préférer une fonction spécifique à WordPress plutôt que la simple dieou exit:

  • Il permet à d'autres plugins de se connecter aux actions appelées par wp_die().
  • Il permet d'utiliser un gestionnaire spécial de sortie en fonction du contexte (le comportement de wp_die()est personnalisé selon que la demande est une demande Ajax ou non).
  • Il permet de tester votre code.

La dernière est plus importante, c'est pourquoi j'ai ajouté cette note au Codex . Si vous souhaitez créer des tests unitaires / d'intégration pour votre code, vous ne pourrez pas tester une fonction qui appelle exitou diedirectement. Cela mettra fin au script, comme il est censé le faire. La façon dont les tests de WordPress sont configurés pour éviter cela (pour les rappels Ajax pour lesquels il a des tests), consiste à se connecter aux actions déclenchées par wp_die()et à lever une exception. Cela permet de détecter l'exception dans le test et d'analyser la sortie du rappel (le cas échéant).

La seule fois que vous utiliseriez dieou exitest si vous souhaitez contourner toute manipulation spéciale wp_die()et tuer l'exécution immédiatement. Il y a des endroits où WordPress fait cela (et d'autres endroits où il pourrait utiliser diedirectement juste parce que la manipulation de wp_die()n'est pas importante, ou que personne n'a encore tenté de créer des tests pour un morceau de code, donc cela a été ignoré). N'oubliez pas que cela rend également votre code plus difficile à tester, donc il ne serait généralement utilisé que dans du code qui n'est pas dans un corps de fonction de toute façon (comme WordPress le fait admin-ajax.php). Donc, si la manipulation de wp_die()n'est spécifiquement pas souhaitée, ou si vous tuez le script à un certain point par précaution (commeadmin-ajax.php, en s'attendant à ce qu'un rappel Ajax se soit déjà correctement terminé), alors vous pourriez envisager d'utiliser diedirectement.

En termes de wp_die()vs wp_die( 0 ), que vous devez utiliser dépend de ce qui gère la réponse de cette demande Ajax sur le front-end. S'il attend un corps de réponse particulier, vous devez transmettre ce message (ou entier, dans ce cas) à wp_die(). Si tout ce qu'il écoute est la réponse réussie ( 200code de réponse ou autre), il n'est pas nécessaire de transmettre quoi que ce soit à wp_die(). Je noterais, cependant, que la fin de wp_die( 0 )rendrait la réponse impossible à distinguer de la admin-ajax.phpréponse par défaut . Donc, terminer par 0ne vous dit pas si votre rappel a été correctement connecté et s'est réellement exécuté. Un message différent serait mieux.

Comme indiqué dans d'autres réponses, vous trouverez souvent wp_send_json()et al. être utile si vous renvoyez une réponse JSON, ce qui est généralement une bonne idée. Ceci est également supérieur à un simple appel wp_die()avec un code, car vous pouvez transmettre beaucoup plus d'informations dans un objet JSON, si nécessaire. L'utilisation wp_send_json_success()et wp_send_json_error()enverra également le message de réussite / d'erreur dans un format standard que toutes les fonctions d'assistance JS Ajax fournies par WordPress pourront comprendre (comme wp.ajax).

TL; DR: Vous devriez probablement toujours utiliser wp_die(), que ce soit dans un rappel Ajax ou non. Encore mieux, renvoyez les informations à wp_send_json()vos amis.

JD
la source
Vous avez ajouté de bons points de vue. J'ai mis à jour le fil avec mes pensées. Vous pouvez commenter si vous le souhaitez. @JD
prosti
@prosti Merci, j'ai ajouté un paragraphe sur quand et pourquoi vous / WordPress pourriez utiliser à la dieplace de wp_die().
JD
J'apprécie vos efforts, cependant, je ne comprends pas pourquoi le noyau WordPress est parfois utilisé die()et parfois wp_die().
prosti
Merci @prosti. Quant à savoir pourquoi WordPress utilise parfois die(), dans certains cas, il s'agit simplement de code hérité, ou die()est utilisé pour tuer le script en dernier recours quand quelque chose de vraiment inattendu s'est produit et wp_die()n'a pas été appelé. Dans d'autres cas, personne n'a créé de tests pour un morceau de code, et la gestion spéciale de wp_die()n'est pas spécifiquement nécessaire, donc elle a été négligée.
JD
13

Du codex AJAX dans les plugins

add_action( 'wp_ajax_my_action', 'my_action_callback' );

function my_action_callback() {
    global $wpdb; // this is how you get access to the database

    $whatever = intval( $_POST['whatever'] );

    $whatever += 10;

        echo $whatever;

    wp_die(); // this is required to terminate immediately and return a proper response
}

Remarquez l'utilisation de wp_die(), au lieu de die()ou exit(). La plupart du temps, vous devriez utiliser wp_die()votre fonction de rappel Ajax. Cela permet une meilleure intégration avec WordPress et facilite le test de votre code.

Tunji
la source
le ccodex que vous avez noté est génial, mais le noyau WordPress ne le suit pas. Et ça?
prosti
3
Toutes les wp_send_json_*fonctions utilisent toutes wp_send_jsonce qui appelle toujourswp_die
Tunji
Mais pourquoi, il me manque quelque chose ici. Avez-vous analysé ces fonctions et tiré des conclusions?
prosti
1
cela vous dérange d'ajouter la note sur wp_send_jsondans la réponse?
Mark Kaplun
1
qui est correct? wp_die (0) ou wp_die ()?
Anwer AR
5

Vous pouvez également utiliser wp_send_json()décrit dans le Codex commesend a JSON response back to an AJAX request, and die().

Donc, si vous devez retourner un tableau, vous n'avez qu'à terminer votre fonction avec wp_send_json($array_with_values);. Pas besoin echoou die.

Vous obtenez également deux fonctions d'aide d'aide wp_send_json_success()et wp_send_json_error()qui ajoute une clé nommée successqui sera trueou falserespectivement.

Par exemple:

$array_val = range( 1,10 );
var_dump( wp_send_json_error( $array_val ) ); # Output: {"success":false,"data":[1,2,3,4,5,6,7,8,9,10]}
echo 'Hey there'; # Not executed because already died.
RRikesh
la source
wp_json_encodeen cas d'exception peut retourner faux, que faire dans ce cas?
prosti
Il lève une exception si le troisième argument (profondeur) est inférieur à 0.
RRikesh
Vous croyez donc que wp_send_json()c'est la meilleure façon? Pourquoi?
prosti
@prosti wp_send_json() fait des choses pour nous. Cette question traite également wp_send_json().
RRikesh
C'est exactement @RRikesh pourquoi je demande au noyau WP d'utiliser cette fonction. Alors pourquoi ça? Est-ce mieux ainsi?
prosti
3

Pour utiliser wordpress ajax / woo commerce ajax, la syntaxe générale est la suivante:

add_action( 'wp_ajax_my_action', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
function my_action_callback()
{
// your code goes here

wp_die();

}

Vous devez utiliser wp_die () à la fin de la fonction.Parce que wordpress utilise en interne un filtre pendant la fonction wp_die (). Ainsi, tout plugin qui fonctionne avec ce filtre peut ne pas fonctionner si nous n'incluons pas wp_die (). De plus, die () et d'autres fonctions tuent immédiatement l'exécution PHP sans considérer aucune fonction wordpress qui devrait être prise en compte lors de la fin de l'exécution.

Si vous utilisez wp_send_json () à l'intérieur, vous fonctionne comme ceci

       function my_action_callback()
    {
    // your code goes here

      wp_send_json();

    //wp_die(); not necessary to use wp_die();

    }

Il n'est pas nécessaire d'utiliser wp_die () à la fin si vous incluez wp_send_json () dans la fonction de rappel . parce que wordpress lui-même utilise la fonction wp_die () en toute sécurité à l'intérieur de la fonction wp_send_json ().

Saran
la source
2

C'est juste en plus de ce que d'autres ont dit. La raison de préférer wp_dieest que le noyau peut y déclencher des actions et que les plug-ins peuvent compléter correctement des choses comme le traçage, la surveillance ou la mise en cache.

En général, vous devriez toujours préférer un appel d'API de base à celui qui est disponible car il ajoute très probablement une certaine valeur (mise en cache, intégration de plug-in ou autre) que vous n'obtenez pas de l'appel PHP direct.

Mark Kaplun
la source
2

Je n'accepterai pas cette réponse, ce ne serait pas juste. Je voulais juste créer un plan et des conseils possibles sur les éléments que je trouve importants:

La définition principale de wp-die ()

File: wp-includes/functions.php
2607: /**
2608:  * Kill WordPress execution and display HTML message with error message.
2609:  *
2610:  * This function complements the `die()` PHP function. The difference is that
2611:  * HTML will be displayed to the user. It is recommended to use this function
2612:  * only when the execution should not continue any further. It is not recommended
2613:  * to call this function very often, and try to handle as many errors as possible
2614:  * silently or more gracefully.
2615:  *
2616:  * As a shorthand, the desired HTTP response code may be passed as an integer to
2617:  * the `$title` parameter (the default title would apply) or the `$args` parameter.
2618:  *
2619:  * @since 2.0.4
2620:  * @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept
2621:  *              an integer to be used as the response code.
2622:  *
2623:  * @param string|WP_Error  $message Optional. Error message. If this is a WP_Error object,
2624:  *                                  and not an Ajax or XML-RPC request, the error's messages are used.
2625:  *                                  Default empty.
2626:  * @param string|int       $title   Optional. Error title. If `$message` is a `WP_Error` object,
2627:  *                                  error data with the key 'title' may be used to specify the title.
2628:  *                                  If `$title` is an integer, then it is treated as the response
2629:  *                                  code. Default empty.
2630:  * @param string|array|int $args {
2631:  *     Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
2632:  *     as the response code. Default empty array.
2633:  *
2634:  *     @type int    $response       The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
2635:  *     @type bool   $back_link      Whether to include a link to go back. Default false.
2636:  *     @type string $text_direction The text direction. This is only useful internally, when WordPress
2637:  *                                  is still loading and the site's locale is not set up yet. Accepts 'rtl'.
2638:  *                                  Default is the value of is_rtl().
2639:  * }
2640:  */
2641: function wp_die( $message = '', $title = '', $args = array() ) {
2642: 
2643:   if ( is_int( $args ) ) {
2644:       $args = array( 'response' => $args );
2645:   } elseif ( is_int( $title ) ) {
2646:       $args  = array( 'response' => $title );
2647:       $title = '';
2648:   }
2649: 
2650:   if ( wp_doing_ajax() ) {
2651:       /**
2652:        * Filters the callback for killing WordPress execution for Ajax requests.
2653:        *
2654:        * @since 3.4.0
2655:        *
2656:        * @param callable $function Callback function name.
2657:        */
2658:       $function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
2659:   } elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
2660:       /**
2661:        * Filters the callback for killing WordPress execution for XML-RPC requests.
2662:        *
2663:        * @since 3.4.0
2664:        *
2665:        * @param callable $function Callback function name.
2666:        */
2667:       $function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );
2668:   } else {
2669:       /**
2670:        * Filters the callback for killing WordPress execution for all non-Ajax, non-XML-RPC requests.
2671:        *
2672:        * @since 3.0.0
2673:        *
2674:        * @param callable $function Callback function name.
2675:        */
2676:       $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler' );
2677:   }
2678: 
2679:   call_user_func( $function, $message, $title, $args );
2680: }

wp_send_json

File: wp-includes/functions.php
3144: /**
3145:  * Send a JSON response back to an Ajax request.
3146:  *
3147:  * @since 3.5.0
3148:  * @since 4.7.0 The `$status_code` parameter was added.
3149:  *
3150:  * @param mixed $response    Variable (usually an array or object) to encode as JSON,
3151:  *                           then print and die.
3152:  * @param int   $status_code The HTTP status code to output.
3153:  */
3154: function wp_send_json( $response, $status_code = null ) {
3155:   @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
3156:   if ( null !== $status_code ) {
3157:       status_header( $status_code );
3158:   }
3159:   echo wp_json_encode( $response );
3160: 
3161:   if ( wp_doing_ajax() ) {
3162:       wp_die( '', '', array(
3163:           'response' => null,
3164:       ) );
3165:   } else {
3166:       die;
3167:   }
3168: }

wp_doing_ajax

File: wp-includes/load.php
1044: /**
1045:  * Determines whether the current request is a WordPress Ajax request.
1046:  *
1047:  * @since 4.7.0
1048:  *
1049:  * @return bool True if it's a WordPress Ajax request, false otherwise.
1050:  */
1051: function wp_doing_ajax() {
1052:   /**
1053:    * Filters whether the current request is a WordPress Ajax request.
1054:    *
1055:    * @since 4.7.0
1056:    *
1057:    * @param bool $wp_doing_ajax Whether the current request is a WordPress Ajax request.
1058:    */
1059:   return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
1060: }

Généralement, ce que nous obtenons de l'appel ajax est une sorte de réponse. La réponse peut être codée en json ou ne pas être codée en json.

Au cas où nous jsonaurions besoin d'une interruption wp_send_jsonou deux satellites sont une excellente idée.

Cependant, nous pouvons retourner x-www-form-urlencodedou multipart/form-dataou text/xmlou tout autre type d'encodage. Dans ce cas, nous n'utilisons pas wp_send_json.

Nous pouvons renvoyer l'intégralité du code HTML et dans ce cas, il est judicieux d'utiliser les wp_die()premier et deuxième paramètres, sinon ces paramètres doivent être vides.

 wp_die( '', '', array(
      'response' => null,
 ) );

Mais quel est l'avantage d'appeler wp_die()sans paramètres?


Enfin, si vous vérifiez le grand noyau WP que vous pouvez trouver

File: wp-includes/class-wp-ajax-response.php
139:    /**
140:     * Display XML formatted responses.
141:     *
142:     * Sets the content type header to text/xml.
143:     *
144:     * @since 2.1.0
145:     */
146:    public function send() {
147:        header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) );
148:        echo "<?xml version='1.0' encoding='" . get_option( 'blog_charset' ) . "' standalone='yes'?><wp_ajax>";
149:        foreach ( (array) $this->responses as $response )
150:            echo $response;
151:        echo '</wp_ajax>';
152:        if ( wp_doing_ajax() )
153:            wp_die();
154:        else
155:            die();

Les deux formats sont utilisés die()et wp_die(). Pouvez-vous expliquer pourquoi?

Enfin voici ce qui admin-ajax.phprevientdie( '0' );

Pourquoi pas wp_die(...)?

prosti
la source
1

Utilisez wp_die(). Il est préférable d'utiliser autant que possible les fonctions WordPress.

Greeso
la source
1

Si vous utilisez echo, cela vous obligera à utiliser die()ou die(0)ou wp_die().

Si vous n'utilisez pas echo, JavaScript peut gérer cela.

Ensuite , vous devez utiliser une meilleure façon de renvoyer des données: wp_send_json().

Pour envoyer des données dans votre rappel (au jsonformat), vous pouvez utiliser les éléments suivants:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

Ils mourront tous pour vous. Pas besoin de sortir ou de mourir après.

MISE À JOUR

Et si vous n'avez pas besoin jsonde format de sortie, vous devez utiliser:

wp_die($response)

Il retournera votre réponse avant sa mort. Selon le codex:

La fonction wp_die()est conçue pour fournir une sortie juste avant sa mort afin d'éviter les réponses vides ou de temporisation.

Veuillez lire l'article complet du codex ici .

Faisal Alvi
la source
1
Merci, que proposez-vous à la place echo?
prosti
1
À noter, Javascript ne gère pas echo. wp_send_json_*utilise echoet sort pour vous. Il y a confusion ici entre le client et le serveur.
Brian Fegter
@prosti wp_send_json ()
Faisal Alvi
Merci, et au cas où nous n'aurions pas besoin jsonde format de sortie?
prosti
1
@prosti que vous devriez utiliser wp_die ($ response) car selon le codex: La fonction wp_die () est conçue pour donner une sortie juste avant sa mort pour éviter les réponses vides ou de time-out.
Faisal Alvi