Cara terbaik untuk mengakhiri permintaan ajax WordPress dan mengapa?

16

Mempertimbangkan permintaan ajax WordPress reguler seperti ini:

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

Apakah akan terbaik untuk fungsi end merrychristmas_happynewyeardengan die(), die(0), wp_die(), atau sesuatu yang lain dan mengapa?

prosti
sumber

Jawaban:

13

Menggunakan wp_die()adalah yang terbaik dari opsi-opsi itu.

Seperti yang telah dicatat orang lain, ada banyak alasan untuk lebih memilih fungsi khusus WordPress daripada yang biasa dieatau exit:

  • Itu memungkinkan plugin lain untuk menghubungkan ke tindakan yang dipanggil oleh wp_die().
  • Ini memungkinkan penangan khusus untuk keluar untuk digunakan berdasarkan konteks (perilaku wp_die()disesuaikan berdasarkan apakah permintaan tersebut permintaan Ajax atau tidak).
  • Memungkinkan untuk menguji kode Anda.

Yang terakhir lebih penting, itulah sebabnya saya menambahkan catatan itu ke Codex . Jika Anda ingin membuat tes unit / integrasi untuk kode Anda, Anda tidak akan dapat menguji fungsi yang memanggil exitatau dielangsung. Ini akan menghentikan skrip, seperti yang seharusnya. Cara tes WordPress sendiri diatur untuk menghindari ini (untuk panggilan balik Ajax yang telah diuji untuk), adalah untuk menghubungkan ke tindakan yang dipicu oleh wp_die()dan melemparkan pengecualian. Ini memungkinkan pengecualian untuk ditangkap dalam pengujian, dan output dari panggilan balik (jika ada) dianalisis.

Satu-satunya waktu yang akan Anda gunakan dieatau exitadalah jika Anda ingin mem-bypass penanganan khusus dari wp_die()dan segera membunuh eksekusi. Ada beberapa tempat di mana WordPress melakukan ini (dan tempat-tempat lain di mana ia dapat digunakan diesecara langsung hanya karena penanganan dari wp_die()tidak penting, atau belum ada yang mencoba membuat tes untuk sepotong kode, jadi itu diabaikan). Ingatlah bahwa ini juga membuat kode Anda lebih sulit untuk tes, sehingga akan umumnya hanya digunakan dalam kode yang tidak dalam fungsi tubuh tetap (seperti WordPress tidak dalam admin-ajax.php). Jadi jika penanganan dari wp_die()secara khusus tidak diinginkan, atau Anda membunuh skrip pada titik tertentu sebagai tindakan pencegahan (sepertiadmin-ajax.phptidak, mengharapkan bahwa biasanya panggilan balik Ajax sudah keluar dengan benar), maka Anda dapat mempertimbangkan untuk menggunakan diesecara langsung.

Dalam hal wp_die()vs wp_die( 0 ), yang harus Anda gunakan tergantung pada apa yang menangani respons permintaan Ajax di ujung depan. Jika mengharapkan badan respons tertentu, maka Anda harus meneruskan pesan itu (atau bilangan bulat, dalam hal ini) ke wp_die(). Jika semua yang didengarkan adalah respons yang berhasil ( 200kode respons atau apa pun), maka tidak perlu meneruskan apa pun wp_die(). Saya akan mencatat, bahwa dengan mengakhiri wp_die( 0 )akan membuat respon tidak bisa dibedakan dari admin-ajax.phprespon default . Jadi diakhiri dengan 0tidak memberi tahu Anda apakah panggilan balik Anda telah tersambung dengan benar dan benar-benar berjalan. Pesan yang berbeda akan lebih baik.

Seperti yang ditunjukkan dalam jawaban lain, Anda akan sering menemukan wp_send_json()et al. untuk membantu jika Anda mengirim respons JSON kembali, yang umumnya merupakan ide bagus. Ini juga lebih unggul daripada hanya menelepon wp_die()dengan kode, karena Anda dapat meneruskan lebih banyak informasi kembali ke objek JSON, jika diperlukan. Menggunakan wp_send_json_success()dan wp_send_json_error()juga akan mengirim pesan keberhasilan / kesalahan kembali dalam format standar yang dapat dimengerti oleh fungsi pembantu Ajax JS yang disediakan oleh WordPress wp.ajax.

TL; DR: Anda mungkin harus selalu menggunakan wp_die(), apakah dalam panggilan balik Ajax atau tidak. Lebih baik lagi, kirim informasi kembali bersama wp_send_json()teman.

JD
sumber
Anda menambahkan beberapa sudut pandang yang baik. Saya memperbarui utas dengan pikiran saya. Anda dapat berkomentar jika Anda suka. @JD
prosti
@prosti Terima kasih, saya telah menambahkan paragraf tentang kapan dan mengapa Anda / WordPress mungkin menggunakan diealih-alih wp_die().
JD
Saya menghargai upaya Anda, namun, saya tidak mengerti mengapa inti WordPress terkadang digunakan die()dan kadang-kadang wp_die().
prosti
Terima kasih @prosti. Adapun mengapa WordPress kadang-kadang menggunakan die(), dalam beberapa kasus itu hanya kode warisan, atau die()digunakan untuk membunuh skrip sebagai upaya terakhir ketika sesuatu yang sangat tidak terduga terjadi dan wp_die()tidak dipanggil. Dalam kasus lain, tidak ada yang membuat tes untuk sepotong kode, dan penanganan khusus dari wp_die()tidak diperlukan secara khusus, sehingga diabaikan.
JD
13

Dari kodeks AJAX di Plugin

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
}

Perhatikan penggunaan wp_die(), bukan die()atau exit(). Sebagian besar waktu Anda harus menggunakan wp_die()fungsi panggilan balik Ajax Anda. Ini memberikan integrasi yang lebih baik dengan WordPress dan membuatnya lebih mudah untuk menguji kode Anda.

Tunji
sumber
ccodex yang Anda catat itu hebat, tetapi inti WordPress tidak mengikutinya. Bagaimana tentang itu?
prosti
3
Semua wp_send_json_*fungsi yang digunakan wp_send_jsonmasih memanggilwp_die
Tunji
Tapi mengapa, saya kehilangan sesuatu di sini. Sudahkah Anda menganalisis fungsi-fungsi ini dan menghasilkan kesimpulan?
prosti
1
Anda keberatan untuk menambahkan catatan tentang wp_send_jsonke jawabannya?
Mark Kaplun
1
yang mana yang benar? wp_die (0) atau wp_die ()?
Anwer AR
5

Anda juga dapat menggunakan yang wp_send_json()dijelaskan dalam Codex sebagaisend a JSON response back to an AJAX request, and die().

Jadi, jika Anda harus mengembalikan array, Anda hanya perlu mengakhiri fungsi Anda wp_send_json($array_with_values);. Tidak perlu echoatau die.

Anda juga mendapatkan dua fungsi bantuan pembantu wp_send_json_success()dan wp_send_json_error()yang menambahkan kunci bernama successyang akan trueatau falsemasing - masing.

Sebagai contoh:

$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
sumber
wp_json_encodedalam kasus pengecualian dapat mengembalikan false, apa dalam kasus itu?
prosti
Ini melempar pengecualian jika argumen ketiga (kedalaman) kurang dari 0.
RRik
Jadi Anda yakin wp_send_json()ini cara terbaik? Mengapa?
prosti
@prosti wp_send_json() melakukan beberapa hal untuk kita. Pertanyaan ini juga berkaitan dengan wp_send_json().
RRikesh
Inilah persisnya @RRikesh mengapa saya meminta WP core menggunakan fungsi itu. Jadi mengapa ini? Apakah lebih baik begitu?
prosti
3

Untuk menggunakan wordpress ajax / woo commerce ajax sintaks umum adalah sebagai berikut:

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

}

Anda harus menggunakan wp_die () di akhir fungsi. Karena wordpress secara internal menggunakan filter selama fungsi wp_die (). Jadi setiap plugin yang berfungsi menggunakan filter itu mungkin tidak berfungsi jika kita tidak memasukkan wp_die (). Juga mati () dan fungsi-fungsi lain segera membunuh eksekusi PHP tanpa mempertimbangkan fungsi wordpress yang harus dipertimbangkan saat mengakhiri eksekusi.

Jika Anda menggunakan wp_send_json () di dalam Anda berfungsi seperti ini

       function my_action_callback()
    {
    // your code goes here

      wp_send_json();

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

    }

Tidak perlu menggunakan wp_die () di akhir jika Anda menyertakan wp_send_json () di dalam fungsi callback . karena wordpress sendiri menggunakan fungsi wp_die () dengan aman di dalam fungsi wp_send_json ().

Saran
sumber
2

Ini hanya sebagai tambahan dari apa yang dikatakan orang lain. Alasan untuk memilih wp_dieadalah bahwa inti dapat memicu tindakan di sana dan plugin dapat dengan benar menyelesaikan hal-hal seperti pelacakan, pemantauan, atau caching.

Secara umum Anda harus selalu lebih suka panggilan API inti jika ada yang tersedia karena kemungkinan besar menambah nilai (caching, integrasi plugin atau apa pun) yang tidak Anda dapatkan dari panggilan PHP langsung.

Mark Kaplun
sumber
2

Saya tidak akan menerima jawaban ini, ini tidak adil. Saya hanya ingin membuat garis besar dan petunjuk yang mungkin tentang item yang saya temukan penting:

Definisi utama dari 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: }

Biasanya apa yang kita dapatkan dari panggilan ajax adalah semacam respons. Respons dapat dikodekan dalam json atau mungkin tidak dikodekan dalam json.

Jika kita perlu jsonkeluar wp_send_jsonatau dua satelit adalah ide bagus.

Namun, kami dapat mengembalikan x-www-form-urlencodedatau multipart/form-dataatau text/xmlatau jenis penyandian lainnya. Dalam hal ini kami tidak menggunakan wp_send_json.

Kami dapat mengembalikan seluruh html dan dalam hal ini masuk akal untuk menggunakan wp_die()parameter pertama dan kedua, kalau tidak parameter ini harus kosong.

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

Tetapi apa manfaat menelepon wp_die()tanpa parameter?


Akhirnya, jika Anda memeriksa inti WP yang hebat Anda mungkin menemukan

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

Kedua format tersebut digunakan die()dan wp_die(). Bisakah Anda jelaskan mengapa?

Akhirnya inilah yang admin-ajax.phpkembalidie( '0' );

Mengapa tidak wp_die(...)?

prosti
sumber
1

Gunakan wp_die(). Lebih baik menggunakan fungsi WordPress sebanyak yang Anda bisa.

Greeso
sumber
1

Jika Anda menggunakan echo, itu akan memaksa Anda untuk menggunakan die()atau die(0)atau wp_die().

Jika Anda tidak menggunakan echo, JavaScript dapat mengatasinya.

Maka anda harus menggunakan cara yang lebih baik untuk mengembalikan data: wp_send_json().

Untuk mengirim data dalam panggilan balik Anda (dalam jsonformat), Anda dapat menggunakan yang berikut:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

Semuanya akan mati untukmu. Tidak perlu keluar atau mati sesudahnya.

MEMPERBARUI

Dan jika Anda tidak perlu jsonsebagai format output, Anda harus menggunakan:

wp_die($response)

Itu akan mengembalikan respons Anda sebelum mati. Sesuai kodeks:

Fungsi wp_die()ini dirancang untuk memberikan output sesaat sebelum mati untuk menghindari respons kosong atau batas waktu.

Baca artikel kodeks lengkap di sini .

Faisal Alvi
sumber
1
Terima kasih, bukan yang Anda sarankan echo?
prosti
1
Untuk diketahui, Javascript tidak menangani echo. wp_send_json_*menggunakan echodan keluar untuk Anda. Ada kebingungan di sini antara klien dan server.
Brian Fegter
@prosti wp_send_json ()
Faisal Alvi
Terima kasih, dan jika kita tidak perlu jsonsebagai format output?
prosti
1
@prosti daripada Anda harus menggunakan wp_die ($ response) karena sesuai kodeks: Fungsi wp_die () dirancang untuk memberikan output sebelum mati untuk menghindari respons kosong atau time-outing.
Faisal Alvi