结束WordPress ajax请求的最佳方法,为什么?


16

考虑像这样的常规WordPress ajax请求:

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

这将是最好的结束函数merrychristmas_happynewyeardie()die(0)wp_die(),还是别的什么,为什么?

Answers:


13

使用wp_die()是这些选项中最好的。

正如其他人指出的那样,有很多理由更喜欢WordPress特有的功能,而不是普通的dieexit

  • 它允许其他插件加入调用的动作wp_die()
  • 它允许根据上下文使用退出的特殊处理程序(wp_die()根据请求是否为Ajax请求来定制的行为)。
  • 这使得测试您的代码成为可能。

最后一个更为重要,这就是为什么我将该注释添加到食典中。如果要为代码创建单元/集成测试,则将无法测试调用exitdie直接调用的函数。它将按预期终止脚本。设置WordPress自己的测试来避免这种情况的方式(针对其具有测试功能的Ajax回调)是挂接到触发的操作wp_die()并引发异常。这允许在测试中捕获异常,并分析回调的输出(如果有)。

唯一要使用的时间是,die或者exit如果您想绕过任何特殊处理wp_die()并立即终止执行。在某些地方WordPress可以做到这一点(其他地方可以die直接使用WordPress的原因仅仅是处理wp_die()不重要,或者还没有人尝试为一段代码创建测试,因此被忽略了)。请记住,这也使您的代码更加难以测试,因此通常只能将其用于不在函数体中的代码中(就像WordPress一样admin-ajax.php)。因此,如果wp_die()明确不希望使用from进行处理,或者作为预防措施,您正在某个时候终止脚本(例如admin-ajax.php这样做,并期望通常Ajax回调已经正确退出),那么您可以考虑die直接使用。

wp_die()vs方面wp_die( 0 ),您应该使用哪个取决于在前端处理该Ajax请求的响应的内容。如果期望特定的响应主体,则需要将该消息(在这种情况下为整数)传递给wp_die()。如果它仅侦听响应成功(200响应代码或其他),则无需将任何信息传递给wp_die()。不过,我要注意的是,结尾wp_die( 0 )将使响应与默认admin-ajax.php响应无法区分。因此,以结尾结尾0并不能告诉您回调是否正确连接并实际运行。一条不同的消息会更好。

正如其他答案中指出的那样,您经常会找到wp_send_json()et al。如果您要发回JSON响应,这会很有帮助,通常这是个好主意。这也比仅用wp_die()代码调用更好,因为如果需要,您可以将更多信息传递回JSON对象。使用wp_send_json_success()wp_send_json_error()还将派出以标准格式的成功/错误消息返回的是由WordPress提供任何JS AJAX辅助功能将能够理解(像wp.ajax)。

TL; DR:您可能应该始终使用wp_die(),无论是否在Ajax回调中使用。更好的是,与wp_send_json()和朋友一起发回信息。


您添加了一些好的观点。我用自己的想法更新了话题。您可以根据需要发表评论。@JD
prosti

@prosti谢谢,我添加了一段有关何时/为什么您/ WordPress可以使用die而不是的段落wp_die()
JD

我很欣赏你的努力,但是,我不明白为什么WordPress的核心有时用die(),有时wp_die()
prosti

谢谢@prosti。至于为什么WordPress有时会使用die(),有时在某些情况下它只是旧代码,或者die()在某些真正出乎意料的事情wp_die()没有被调用时被用来杀死脚本作为最后的手段。在其他情况下,没有人为一段代码创建测试,并且wp_die()不需要特别的from处理,因此它被忽略了。
JD

13

插件中的AJAX编码

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
}

注意使用wp_die()代替die()exit()。大多数时候,您应该wp_die()在Ajax回调函数中使用它。这样可以更好地与WordPress集成,并使其更易于测试代码。


您记下的ccodex很棒,但是WordPress核心并没有遵循它。那个怎么样?
prosti

3
所有仍wp_send_json_*使用的功能wp_send_json仍在调用wp_die
Tunji

但是为什么,我在这里错过了一些东西。您是否分析了这些功能并得出了结论?
prosti

1
您介意将注释添加wp_send_json到答案中吗?
Mark Kaplun

1
哪个是对的?wp_die(0)或wp_die()?
Anwer AR

5

您也可以wp_send_json()将食典中的描述用作send a JSON response back to an AJAX request, and die().

因此,如果您必须返回一个数组,则只能以结束函数wp_send_json($array_with_values);。无需echodie

您还将获得两个help helper函数wp_send_json_success()wp_send_json_error()并添加了一个名为successbe true或or 的键false

例如:

$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.

wp_json_encode如果异常可能返回false,那该怎么办?
prosti

如果第三个参数(深度)小于0
则会

因此,您认为这wp_send_json()是最好的方法吗?为什么?
prosti

@prosti 为我们wp_send_json() 做一些事情这个问题也处理wp_send_json()
RRikesh '17

这正是@RRikesh的原因,为什么我要问WP内核使用该功能。那为什么呢?这样更好吗?
prosti

3

对于使用wordpress ajax / woo Commerce ajax的一般语法如下:

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

}

你应该在函数的末尾使用wp_die(),因为wordpress内部在wp_die()函数中使用了一个过滤器,因此如果不包含wp_die(),任何使用该过滤器的插件都可能无法正常工作。同样die()和其他函数会立即终止PHP执行,而无需考虑终止执行时应考虑的任何wordpress函数。

如果您在内部使用wp_send_json(),则功能如下

       function my_action_callback()
    {
    // your code goes here

      wp_send_json();

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

    }

如果在回调函数中包含wp_send_json(),则不必在最后使用wp_die()。因为wordpress本身在wp_send_json()函数内部安全地使用wp_die()函数。


2

这只是其他人所说的补充。首选原因wp_die是核心可以在那里触发操作,插件可以正确完成诸如跟踪,监视或缓存之类的操作。

通常,如果有一个核心API调用,您应该总是更喜欢核心API调用,因为它很可能会增加一些您无法从直接PHP调用中获得的价值(缓存,插件集成或其他)。


2

我不会接受这个答案,这不公平。我只想在我认为重要的项目上创建轮廓和可能的提示:

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: }

通常,我们从ajax调用中得到的是某种响应。响应可能使用json编码,也可能未使用json编码。

万一我们需要jsonoutupt wp_send_json或两个卫星是个好主意。

但是,我们可能返回x-www-form-urlencodedmultipart/form-datatext/xml或任何其他编码类型。在这种情况下,我们不使用wp_send_json

我们可能会返回整个html,在这种情况下,可以使用wp_die()第一个和第二个参数,否则这些参数应该为空。

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

但是wp_die()没有参数调用的好处是什么?


最后,如果您查看出色的WP核心,可能会发现

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

两种格式都使用die()wp_die()。你能解释为什么吗?

最后这就是admin-ajax.php回报die( '0' );

为什么不wp_die(...)呢?


1

使用wp_die()。尽可能多地使用WordPress功能更好。


1

如果使用echo,它将迫使您使用die()die(0)wp_die()

如果您不使用echo,JavaScript可以处理。

然后,您应该使用更好的方法返回数据:wp_send_json()

要以回调形式(json格式)发送数据,可以使用以下命令:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

他们都会为你而死。之后无需退出或死亡。

更新

如果不需要json输出格式,则应使用:

wp_die($response)

它会在死亡之前返回您的回复。根据法典:

该函数wp_die()旨在在死之前提供输出,以避免空响应或超时响应。

在此处阅读完整的法典文章。


1
谢谢,您有什么建议echo呢?
prosti

1
注意,Javascript无法处理echo。为您wp_send_json_*使用echo和退出。客户端和服务器之间存在混淆。
Brian Fegter'2

@prosti wp_send_json()
Faisal Alvi

谢谢,以防万一我们不需要json输出格式?
prosti

1
@prosti比您应该使用wp_die($ response)的多,因为根据法典:函数wp_die()旨在在死之前提供输出,以避免空响应或超时响应。
Faisal Alvi'2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.