Cách tốt nhất để kết thúc yêu cầu ajax WordPress và tại sao?


16

Xem xét các yêu cầu ajax WordPress thường xuyên như sau:

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

Nó sẽ là tốt nhất để chức năng cuối merrychristmas_happynewyearvới die(), die(0), wp_die(), hay cái gì khác và tại sao?

Câu trả lời:


13

Sử dụng wp_die()là tốt nhất của những lựa chọn.

Như những người khác đã lưu ý, có nhiều lý do để thích một chức năng cụ thể của WordPress hơn là đơn giản diehoặc exit:

  • Nó cho phép các plugin khác móc vào các hành động được gọi bởi wp_die().
  • Nó cho phép một trình xử lý đặc biệt để thoát ra được sử dụng dựa trên ngữ cảnh (hành vi của wp_die() được điều chỉnh dựa trên việc yêu cầu có phải là yêu cầu Ajax hay không).
  • Nó làm cho nó có thể kiểm tra mã của bạn.

Cái cuối cùng quan trọng hơn, đó là lý do tại sao tôi đã thêm ghi chú đó vào Codex . Nếu bạn muốn tạo các bài kiểm tra đơn vị / tích hợp cho mã của mình, bạn sẽ không thể kiểm tra một hàm gọi exithoặc dietrực tiếp. Nó sẽ chấm dứt kịch bản, giống như nó được cho là vậy. Cách mà các thử nghiệm riêng của WordPress được thiết lập để tránh điều này (đối với các cuộc gọi lại Ajax mà nó đã thử nghiệm), là nối vào các hành động được kích hoạt bởi wp_die()và đưa ra một ngoại lệ. Điều này cho phép ngoại lệ được bắt trong thử nghiệm và đầu ra của cuộc gọi lại (nếu có) được phân tích.

Lần duy nhất bạn sẽ sử dụng diehoặc exitlà nếu bạn muốn bỏ qua bất kỳ xử lý đặc biệt nào wp_die()và giết chết việc thực thi ngay lập tức. Có một số nơi mà WordPress thực hiện điều này (và những nơi khác mà nó có thể sử dụng dietrực tiếp chỉ vì việc xử lý từ đó wp_die()không quan trọng hoặc chưa có ai cố gắng tạo các thử nghiệm cho một đoạn mã, vì vậy nó đã bị bỏ qua). Hãy nhớ rằng điều này cũng làm cho mã của bạn khó kiểm tra hơn, do đó, nó thường chỉ được sử dụng trong mã không có trong thân hàm (dù sao thì WordPress cũng vậy admin-ajax.php). Vì vậy, nếu việc xử lý từ wp_die()đặc biệt không mong muốn hoặc bạn đang giết tập lệnh tại một điểm nhất định để đề phòng (nhưadmin-ajax.phpkhông, hy vọng rằng thường thì một cuộc gọi lại Ajax đã thoát đúng cách), sau đó bạn có thể cân nhắc sử dụng dietrực tiếp.

Về mặt wp_die()vs wp_die( 0 ), cái mà bạn nên sử dụng phụ thuộc vào việc xử lý phản hồi của yêu cầu Ajax đó ở mặt trước. Nếu nó đang mong đợi một cơ quan phản hồi cụ thể, thì bạn cần chuyển thông điệp đó (hoặc số nguyên, trong trường hợp này) cho wp_die(). Nếu tất cả những gì nó đang nghe là phản hồi đang thành công ( 200mã phản hồi hoặc bất cứ điều gì), thì không cần phải chuyển bất cứ điều gì wp_die(). Tuy nhiên, tôi sẽ lưu ý rằng việc kết thúc bằng wp_die( 0 )sẽ làm cho phản hồi không thể phân biệt được với admin-ajax.phpphản hồi mặc định . Vì vậy, kết thúc bằng 0không cho bạn biết liệu cuộc gọi lại của bạn đã được nối đúng cách và thực sự chạy. Một thông điệp khác sẽ tốt hơn.

Như đã chỉ ra trong các câu trả lời khác, bạn sẽ thường tìm thấy wp_send_json()et al. sẽ hữu ích nếu bạn đang gửi phản hồi JSON trở lại, đây thường là một ý tưởng tốt. Điều này cũng tốt hơn so với việc chỉ gọi wp_die()bằng mã, bởi vì bạn có thể truyền lại nhiều thông tin hơn trong một đối tượng JSON, nếu cần. Việc sử dụng wp_send_json_success()wp_send_json_error()cũng sẽ gửi lại thông báo thành công / lỗi theo định dạng chuẩn mà bất kỳ hàm trợ giúp JS Ajax nào được cung cấp bởi WordPress đều có thể hiểu được (như wp.ajax).

TL; DR: Có lẽ bạn nên luôn luôn sử dụng wp_die(), cho dù trong một cuộc gọi lại Ajax hay không. Thậm chí tốt hơn, gửi thông tin trở lại với wp_send_json()và bạn bè.


Bạn đã thêm một số quan điểm tốt. Tôi cập nhật chủ đề với những suy nghĩ của tôi. Bạn có thể bình luận nếu bạn thích. @JD
prosti

@prosti Cảm ơn, tôi đã thêm một đoạn về thời điểm và lý do bạn / WordPress có thể sử dụng diethay vì wp_die().
JD

Tôi đánh giá cao nỗ lực của bạn, tuy nhiên, tôi không hiểu tại sao lõi WordPress đôi khi được sử dụng die()và đôi khi wp_die().
prosti

Cảm ơn @prosti. Về lý do tại sao WordPress đôi khi sử dụng die(), trong một số trường hợp, đó chỉ là mã kế thừa hoặc die()đang được sử dụng để giết tập lệnh như là phương sách cuối cùng khi có điều gì đó thực sự bất ngờ xảy ra và wp_die()không được gọi. Trong các trường hợp khác, không ai tạo ra các thử nghiệm cho một đoạn mã và việc xử lý đặc biệt từ wp_die()không cần thiết đặc biệt, vì vậy nó đã bị bỏ qua.
JD

13

Từ codex AJAX trong 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
}

Lưu ý việc sử dụng wp_die(), thay vì die()hoặc exit(). Hầu hết thời gian bạn nên sử dụng wp_die()trong hàm gọi lại Ajax. Điều này cung cấp tích hợp tốt hơn với WordPress và giúp kiểm tra mã của bạn dễ dàng hơn.


ccodex bạn lưu ý là tuyệt vời, nhưng cốt lõi WordPress không tuân theo nó. Thế còn cái đó?
prosti

3
Tất cả các wp_send_json_*chức năng đều sử dụng wp_send_jsonmà vẫn gọiwp_die
Tunji

Nhưng tại sao, tôi đang thiếu một cái gì đó ở đây. Bạn đã phân tích các chức năng này và đưa ra kết luận?
prosti

1
Bạn có phiền để thêm ghi chú wp_send_jsonvào câu trả lời không?
Đánh dấu Kaplun

1
cái nào đúng wp_die (0) hoặc wp_die ()?
Anwer AR

5

Bạn cũng có thể sử dụng wp_send_json()được mô tả trong Codex nhưsend a JSON response back to an AJAX request, and die().

Vì vậy, nếu bạn phải trả về một mảng, bạn chỉ kết thúc chức năng của mình với wp_send_json($array_with_values);. Không cần echohoặc die.

Bạn cũng có được hai chức năng giúp đỡ helper wp_send_json_success()wp_send_json_error()có thêm một khóa có tên successđó sẽ truehoặc falsetương ứng.

Ví dụ:

$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_encodetrong trường hợp ngoại lệ có thể trả về false, trong trường hợp đó thì sao?
prosti

Nó ném một ngoại lệ nếu đối số thứ ba (độ sâu) nhỏ hơn 0.
RRikesh

Vì vậy, bạn tin rằng wp_send_json()cách tốt nhất? Tại sao?
prosti

@prosti wp_send_json() làm một số thứ cho chúng tôi. Câu hỏi này cũng liên quan đến wp_send_json().
RRikesh

Đây chính xác là @RRikesh tại sao tôi hỏi lõi WP sử dụng chức năng đó. Vậy tại sao lại thế này? Nó tốt hơn theo cách đó?
prosti

3

Để sử dụng wordpress ajax / woo Commerce cú pháp chung ajax như sau:

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

}

Bạn nên sử dụng wp_die () ở cuối hàm. Bởi vì wordpress bên trong sử dụng bộ lọc trong hàm wp_die (). Vì vậy, bất kỳ plugin nào đang hoạt động bằng bộ lọc đó có thể không hoạt động nếu chúng tôi không bao gồm wp_die (). Ngoài ra die () và các hàm khác sẽ ngay lập tức giết chết thực thi PHP mà không xem xét bất kỳ hàm wordpress nào cần được xem xét trong khi chấm dứt thực thi.

Nếu bạn đang sử dụng wp_send_json () bên trong bạn hoạt động như thế này

       function my_action_callback()
    {
    // your code goes here

      wp_send_json();

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

    }

Không cần thiết phải sử dụng wp_die () ở cuối nếu bạn bao gồm wp_send_json () bên trong hàm gọi lại . bởi vì chính wordpress sử dụng hàm wp_die () một cách an toàn bên trong hàm wp_send_json ().


2

Đây chỉ là những gì người khác nói. Lý do để thích wp_dielà lõi có thể kích hoạt các hành động ở đó và các plugin có thể hoàn thành đúng mọi thứ như theo dõi, giám sát hoặc lưu trữ.

Nói chung, bạn nên luôn luôn thích một lệnh gọi API cốt lõi hơn nếu có sẵn vì nó rất có thể sẽ thêm một số giá trị (bộ nhớ đệm, tích hợp plugin hoặc bất cứ thứ gì) mà bạn không nhận được từ cuộc gọi PHP trực tiếp.


2

Tôi sẽ không chấp nhận câu trả lời này, điều này sẽ không công bằng. Tôi chỉ muốn tạo một phác thảo và gợi ý có thể về các mục tôi thấy quan trọng:

Định nghĩa chính của 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: }

Thông thường những gì chúng ta nhận được từ cuộc gọi ajax là một số loại phản hồi. Phản hồi có thể được mã hóa trong json hoặc có thể không được mã hóa trong json.

Trong trường hợp chúng ta cần jsonbộc phát wp_send_jsonhoặc hai vệ tinh là ý tưởng tuyệt vời.

Tuy nhiên, chúng ta có thể trở lại x-www-form-urlencodedhoặc multipart/form-datahoặc text/xmlhoặc bất kỳ loại mã hóa khác. Trong trường hợp đó chúng tôi không sử dụng wp_send_json.

Chúng tôi có thể trả về toàn bộ html và trong trường hợp đó, nên sử dụng wp_die()tham số thứ nhất và thứ hai, nếu không các tham số này sẽ trống.

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

Nhưng lợi ích của việc gọi wp_die()mà không có tham số là gì?


Cuối cùng, nếu bạn kiểm tra lõi WP tuyệt vời bạn có thể tìm thấy

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

Cả hai định dạng được sử dụng die()wp_die(). Bạn có thể giải thích lý do tại sao?

Cuối cùng, đây là những gì admin-ajax.phptrả vềdie( '0' );

Tại sao không wp_die(...)?


1

Sử dụng wp_die(). Tốt hơn là sử dụng các chức năng WordPress càng nhiều càng tốt.


1

Nếu bạn sử dụng echo, nó sẽ buộc bạn phải sử dụng die()hay die(0)hay wp_die().

Nếu bạn không sử dụng echo, JavaScript có thể xử lý việc đó.

Sau đó, bạn nên sử dụng một cách tốt hơn để trả về dữ liệu : wp_send_json().

Để gửi dữ liệu trong cuộc gọi lại của bạn (ở jsonđịnh dạng), bạn có thể sử dụng như sau:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

Tất cả trong số họ sẽ chết vì bạn. Không cần phải thoát ra hoặc chết sau đó.

CẬP NHẬT

Và nếu bạn không cần jsonđịnh dạng đầu ra, bạn nên sử dụng:

wp_die($response)

Nó sẽ trả lời của bạn trước khi nó chết. Theo codex:

Hàm wp_die()này được thiết kế để cung cấp đầu ra ngay trước khi nó chết để tránh các phản hồi trống hoặc hết thời gian.

Xin vui lòng đọc bài viết đầy đủ codex ở đây .


1
Cảm ơn, những gì bạn đề nghị thay vì echo?
prosti

1
Để lưu ý, Javascript không xử lý echo. wp_send_json_*sử dụng echovà thoát ra cho bạn. Có sự nhầm lẫn ở đây giữa máy khách và máy chủ.
Brian Fegter

@prosti wp_send_json ()
Faisal Alvi

Cảm ơn, và trong trường hợp chúng tôi không cần jsonđịnh dạng đầu ra?
prosti

1
@prosti hơn bạn nên sử dụng wp_die ($ reply) vì theo mã: Hàm wp_die () được thiết kế để cung cấp đầu ra ngay trước khi nó chết để tránh phản hồi trống hoặc hết thời gian.
Faisal Alvi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.