当前位置: 首页>>技术解读>>正文


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

webfans 技术解读 , 去评论

问题描述

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

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

最好用die()die(0)wp_die()或其他什么来结束功能merrychristmas_happynewyear,为什么?

最佳解决方法

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

正如其他人所指出的那样,有很多理由比普通的dieexit更喜欢WordPress-specific功能:

  • 它允许其他插件挂钩到wp_die()调用的操作中。

  • 它允许基于上下文使用退出的特殊处理程序(wp_die()的行为是根据请求是否是Ajax请求而定制的)。

  • 它可以测试您的代码。

最后一个更重要,这就是为什么I added that note to the Codex。如果您想使用create unit/integration tests作为代码,则无法直接测试调用exitdie的函数。它将终止脚本,就像它应该的那样。设置WordPress自己的测试以避免这种情况(对于它测试的Ajax回调)的方式是挂钩由wp_die()触发的操作并抛出异常。这允许在测试中捕获异常,并且分析回调的输出(如果有的话)。

您唯一一次使用dieexit就是如果您想绕过wp_die()的任何特殊处理并立即终止执行。在某些地方,WordPress会这样做(以及其他可能直接使用die的地方只是因为wp_die()的处理并不重要,或者没有人试图为一段代码创建测试,所以它被忽略了)。请记住,这也使您的代码更难以测试,因此它通常只用于不在函数体中的代码(如WordPress在admin-ajax.php中所做的那样)。因此,如果特别不希望来自wp_die()的处理,或者您在某个时刻要杀死脚本作为预防措施(如admin-ajax.php那样,期望通常Ajax回调已经正常退出),那么您可以考虑直接使用die

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

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

长话短说:你应该总是使用wp_die(),无论是否在Ajax回调中。更好的是,用wp_send_json()和朋友发回信息。

次佳解决方法

来自codex AJAX in 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
}

Notice the use of wp_die(), instead of die() or exit(). Most of the time you should be using wp_die() in your Ajax callback function. This provides better integration with WordPress and makes it easier to test your code.

第三种解决方法

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

因此,如果您必须返回一个数组,那么您只能使用wp_send_json($array_with_values);结束您的功能。无需echodie

您还可以获得两个帮助辅助功能wp_send_json_success()wp_send_json_error(),它们分别添加一个名为success的密钥,分别为truefalse

例如:

$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_die的原因是核心可以在那里触发操作,插件可以正确完成跟踪,监视或缓存等操作。

一般情况下,如果有可用的话,你应该总是更喜欢核心API调用,因为它最有可能添加一些你从直接PHP调用中得不到的值(缓存,插件集成或其他)。

第五种方法

对于使用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_die()函数安全地在 wp_send_json()函数内部。

第六种方法

我不接受这个答案,这不公平。我只想创建一个大纲,并对我认为重要的项目提供可能的提示:

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编码。

如果我们需要json outupt 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(...)

参考资料

本文由朵颐IT整理自网络, 文章地址: https://duoyit.com/article/2177.html,转载请务必附带本地址声明。