¿La mejor manera de finalizar la solicitud ajax de WordPress y por qué?

11

Teniendo en cuenta las solicitudes regulares de WordPress ajax como estas:

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

¿Será mejor terminar la función merrychristmas_happynewyear con die() , die(0) , wp_die() , o algo más y por qué?

    
pregunta prosti 24.12.2016 - 13:18

8 respuestas

9

Usar wp_die() es la mejor de esas opciones.

Como han señalado otros, hay muchas razones para preferir una función específica de WordPress sobre el plano die o exit :

  • Permite que otros complementos se conecten a las acciones llamadas por wp_die() .
  • Permite que un controlador especial para salir se use según el contexto (el comportamiento de wp_die() se adapta en función de si la solicitud es una solicitud de Ajax o no).
  • Hace posible probar su código.

El último es más importante, por eso Agregué esa nota a el Codex . Si desea crear pruebas de unidad / integración para su código, no podrá probar una función que llama a exit o die directamente. Terminará la secuencia de comandos, como se supone que debe hacer. La forma en que se configuran las propias pruebas de WordPress para evitar esto (para las devoluciones de llamada Ajax para las que tiene pruebas), es engancharse en las acciones activadas por wp_die() y lanzar una excepción. Esto permite que la excepción se capture dentro de la prueba y que se analice la salida de la devolución de llamada (si corresponde).

La única vez que usaría die o exit es si desea omitir cualquier manejo especial de wp_die() y terminar la ejecución inmediatamente. Hay algunos lugares donde WordPress hace esto (y otros lugares donde podría usar die directamente solo porque el manejo de wp_die() no es importante, o nadie ha intentado crear pruebas para un fragmento de código todavía, por lo que se pasó por alto ). Recuerde que esto también hace que su código sea más difícil de probar, por lo que generalmente solo se usará en código que no esté en el cuerpo de una función (como lo hace WordPress en admin-ajax.php ). Entonces, si no se desea específicamente el manejo desde wp_die() , o si está eliminando el script en un cierto punto como medida de precaución (como hace admin-ajax.php , esperando que generalmente una devolución de llamada Ajax ya haya finalizado correctamente), entonces podría considerar utilizando die directamente.

En términos de wp_die() vs wp_die( 0 ) , lo que debe usar depende de lo que maneje la respuesta de esa solicitud de Ajax en la interfaz. Si está esperando un cuerpo de respuesta particular, entonces necesita pasar ese mensaje (o entero, en este caso) a wp_die() . Si todo lo que está escuchando es que la respuesta sea exitosa (código de respuesta 200 o lo que sea), entonces no hay necesidad de pasar nada a wp_die() . Sin embargo, observaría que terminar con wp_die( 0 ) haría que la respuesta fuera indistinguible de la respuesta predeterminada admin-ajax.php . Entonces, terminar con 0 no te dice si tu devolución de llamada se conectó correctamente y si se ejecutó. Un mensaje diferente sería mejor.

Como se señaló en otras respuestas, a menudo encontrará wp_send_json() et al. para ser útil si está devolviendo una respuesta JSON, lo que generalmente es una buena idea. Esto también es superior a solo llamar a wp_die() con un código, porque puede pasar mucha más información de nuevo en un objeto JSON, si es necesario. El uso de wp_send_json_success() y wp_send_json_error() también devolverá el mensaje de éxito / error en un formato estándar que todas las funciones de ayuda de JS Ajax proporcionadas por WordPress podrán comprender (como wp.ajax ).

TL; DR: Probablemente siempre deberías usar wp_die() , ya sea en una devolución de llamada Ajax o no. Aún mejor, envíe información con wp_send_json() y amigos.

    
respondido por el J.D. 04.02.2017 - 22:51
11

Desde el códice AJAX en complementos

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
}
  

Note el uso de wp_die() , en lugar de die() o exit() . La mayoría de   el tiempo que debe utilizar wp_die() en su función de devolución de llamada Ajax. Esta   proporciona una mejor integración con WordPress y facilita la prueba   tu código.

    
respondido por el Tunji 24.12.2016 - 13:23
5

También puede usar wp_send_json() descrito en el Codex como send a JSON response back to an AJAX request, and die().

Entonces, si tiene que devolver una matriz, solo tiene que finalizar su función con wp_send_json($array_with_values); . No necesita echo o die .

También obtiene dos funciones de ayuda de ayuda wp_send_json_success() y wp_send_json_error() que agrega una clave llamada success que será true o false respectivamente.

Por ejemplo:

$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.
    
respondido por el RRikesh 25.12.2016 - 14:31
2

Esto es solo en adición a lo que otros dijeron. La razón para preferir wp_die es que el núcleo puede desencadenar acciones allí y los complementos pueden completar correctamente cosas como el seguimiento, la supervisión o el almacenamiento en caché.

En general, siempre debe preferir una llamada a la API central en lugar de una disponible, ya que es muy probable que agregue algún valor (almacenamiento en caché, integración de complementos o cualquier otro) que no obtenga de la llamada PHP directa.

    
respondido por el Mark Kaplun 03.02.2017 - 18:24
2

Para usar wordpress ajax / woo commerce, la sintaxis general de ajax es la siguiente:

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();

}

Debería usar wp_die () al final de la función. Debido a que wordpress usa internamente un filtro durante la función wp_die (). Por lo tanto, cualquier complemento que esté funcionando con ese filtro puede no funcionar si no lo hacemos. incluye el wp_die (). También die () y otras funciones eliminan inmediatamente la ejecución de PHP sin tener en cuenta ninguna función de wordpress que deba considerarse al finalizar la ejecución.

Si está utilizando wp_send_json (), dentro de usted funciona de esta manera

       function my_action_callback()
    {
    // your code goes here

      wp_send_json();

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

    }

No es necesario usar wp_die () al final si incluye wp_send_json () dentro de la función de devolución de llamada . porque wordpress usa la función wp_die () de forma segura dentro de la función wp_send_json ().

    
respondido por el Saran 06.02.2017 - 08:29
2

No aceptaré esta respuesta, esto no sería justo. Solo quería crear un esquema y posibles sugerencias sobre los elementos que considero importantes:

La definición principal 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: }

Normalmente, lo que obtenemos de la llamada ajax es algún tipo de respuesta. La respuesta puede estar codificada en json o no estar codificada en json.

En caso de que necesitemos json outupt wp_send_json o dos satélites son una gran idea.

Sin embargo, podemos devolver x-www-form-urlencoded o multipart/form-data o text/xml o cualquier otro tipo de codificación. En ese caso no usamos wp_send_json .

Podemos devolver el código HTML completo y, en ese caso, tiene sentido utilizar el primer y segundo parámetro wp_die() , de lo contrario, estos parámetros deberían estar vacíos.

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

¿Pero cuál es el beneficio de llamar a wp_die() sin parámetros?

Finalmente, si compruebas el gran núcleo de WP que puedes encontrar

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();

Ambos formatos se utilizan die() y wp_die() . ¿Puedes explicar por qué?

Finalmente, aquí está lo que admin-ajax.php devuelve die( '0' );

¿Por qué no wp_die(...) ?

    
respondido por el prosti 07.02.2017 - 14:07
1

Utilice wp_die() . Es mejor usar las funciones de WordPress tanto como puedas.

    
respondido por el Greeso 04.02.2017 - 23:05
1

Si usas echo , te obligará a usar die() o die(0) o wp_die() .

Si no usas echo , JavaScript puede manejar eso.

Entonces deberías usar una mejor manera de devolver datos: wp_send_json() .

Para enviar datos en su devolución de llamada (en formato json ), puede usar lo siguiente:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

Todos ellos morirán por ti. No hay necesidad de salir o morir después.

ACTUALIZAR

Y si no necesita json como formato de salida, debe usar:

wp_die($response)

Volverá tu respuesta antes de que muera. Según el códice:

  

La función wp_die() está diseñada para dar salida justo antes de que muera   para evitar respuestas vacías o de tiempo de espera.

Lea el artículo completo del códice aquí .

    
respondido por el Faisal Alvi 09.02.2017 - 15:26

Lea otras preguntas en las etiquetas