WordPress ajax isteğini sonlandırmanın en iyi yolu ve neden?


16

Aşağıdaki gibi normal WordPress ajax istekleri göz önüne alındığında:

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

O uç işlevine iyi olacak merrychristmas_happynewyearile die(), die(0), wp_die(), ya da başka bir şey ve neden?

Yanıtlar:


13

Kullanmak wp_die()bu seçeneklerin en iyisidir.

Diğerleri de belirtildiği gibi, düz üzerinde bir WordPress özgü fonksiyonunu tercih etmelerinin birçok nedeni vardır dieya exit:

  • Diğer eklentilerin çağırdığı eylemlere bağlanmasına izin verir wp_die().
  • Bağlama dayalı olarak çıkmak için özel bir işleyiciye izin verir (davranışı wp_die(), isteğin bir Ajax isteği olup olmamasına göre uyarlanır).
  • Kodunuzu test etmeyi mümkün kılar.

Sonuncusu daha önemlidir, bu yüzden bu notu Kodeks'e ekledim . Kodunuz için birim / entegrasyon testleri oluşturmak istiyorsanız , çağıran exitveya diedoğrudan çağıran bir işlevi test edemezsiniz . Komut dosyasını olması gerektiği gibi sonlandıracaktır. Bunu önlemek için WordPress'in kendi testlerinin ayarlanma yolu (test ettiği Ajax geri çağrıları için) tarafından tetiklenen eylemlere bağlanmak wp_die()ve bir istisna atmaktır. Bu, istisnanın test içinde yakalanmasını ve geri çağrı (varsa) çıktısının analiz edilmesini sağlar.

Kullanacağınız tek zaman dieveya exitherhangi bir özel işlemeyi atlamak wp_die()ve yürütmeyi hemen öldürmek istiyorsanız . WordPress'in bunu yaptığı bazı yerler vardır (ve diedoğrudan kullanımın wp_die()önemli olmaması nedeniyle doğrudan kullanabileceği başka yerler vardır veya hiç kimse henüz bir kod parçası için test oluşturmaya çalışmadı, bu yüzden gözardı edildi). Bunun kodunuzu test etmeyi daha da zorlaştırdığını unutmayın, bu nedenle genellikle yalnızca bir işlev gövdesinde olmayan kodlarda kullanılır (WordPress'in yaptığı gibi admin-ajax.php). Bu nedenle, işleme wp_die()özel olarak istenmiyorsa veya senaryoyu önlem olarak belirli bir noktada öldürüyorsanız (admin-ajax.phpgenellikle bir Ajax geri aramasının zaten düzgün bir şekilde çıkacağını umuyorsa), diedoğrudan kullanmayı düşünebilirsiniz .

Açısından wp_die()vs wp_die( 0 )kullanmak zorunda olan ön uçta olduğu Ajax isteği yanıtı işleyen bağlıdır. Belirli bir yanıt gövdesi bekleniyorsa, o iletiyi (veya bu durumda tamsayı) iletmeniz gerekir wp_die(). Dinlediği tek şey yanıtın başarılı olması ( 200yanıt kodu ya da her neyse) ise, hiçbir şey iletmeye gerek yoktur wp_die(). Bununla birlikte, bununla bitmenin wp_die( 0 )cevabı varsayılan admin-ajax.phpyanıttan ayırt edilemez hale getireceğini unutmayın . Yani ile 0bitirmek size geri arama düzgün bağlandı ve gerçekten koştu olup olmadığını söylemez. Farklı bir mesaj daha iyi olurdu.

Diğer cevaplarda belirtildiği gibi, çoğu zaman wp_send_json()et al. genellikle iyi bir fikir olan bir JSON yanıtı gönderiyorsanız yardımcı olabilir. Bu ayrıca wp_die()bir kodla çağrı yapmaktan da üstündür , çünkü gerekirse bir JSON nesnesine çok daha fazla bilgi aktarabilirsiniz. Kullanılması wp_send_json_success()ve wp_send_json_error()ayrıca WordPress tarafından sağlanan herhangi JS Ajax yardımcı fonksiyonları (gibi anlamak mümkün olacak standart bir formatta başarı / hata mesajı geri gönderir wp.ajax).

TL; DR:wp_die() Ajax geri aramasında olsun ya da olmasın muhtemelen her zaman kullanmalısınız . Daha da iyisi, bilgileri wp_send_json()arkadaşlarınızla geri gönderin .


Bazı iyi bakış açıları eklediniz. Konuyu düşüncelerimle güncelledim. İsterseniz yorum yapabilirsiniz. @JD
prosti

@prosti teşekkürler, seni / WordPress kullanıyor olabilir ne zaman ve neden bir paragraf ekledik dieyerine wp_die().
JD

Çabalarınızı takdir ediyorum, ancak WordPress çekirdeğinin neden bazen die()ve bazen kullanıldığını anlamıyorum wp_die().
prosti

Teşekkürler @prosti. WordPress'in neden bazen kullandığına gelince die(), bazı durumlarda sadece eski bir koddur veya die()gerçekten beklenmedik bir şey olduğunda ve wp_die()çağrılmadığında komut dosyasını son çare olarak öldürmek için kullanılır . Diğer durumlarda, hiç kimse bir kod parçası için testler oluşturmadı ve özel işlem wp_die()özel olarak gerekli değildir, bu yüzden gözden kaçırılmıştır.
JD

13

Eklentilerdeki AJAX kodeksinden

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
}

Veya wp_die()yerine kullanıldığına dikkat edin . Çoğu zaman Ajax geri arama işlevinizde kullanmanız gerekir . Bu, WordPress ile daha iyi entegrasyon sağlar ve kodunuzu test etmeyi kolaylaştırır.die()exit()wp_die()


not ettiğiniz ccodex harika, ancak WordPress çekirdeği bunu takip etmiyor. Peki ya bu?
prosti

3
Tüm wp_send_json_*fonksiyonlar tüm kullanımını wp_send_jsonhala çağırırwp_die
Tunji

Ama neden, burada bir şey eksik. Bu işlevleri analiz ettiniz ve sonuçlar buldunuz mu?
prosti

1
wp_send_jsoncevaba not eklemek ister misiniz ?
Mark Kaplun

1
hangisi doğru? wp_die (0) veya wp_die ()?
Anwer AR

5

Ayrıca wp_send_json(), Kodeks'de açıklanansend a JSON response back to an AJAX request, and die().

Bu nedenle, bir dizi döndürmeniz gerekiyorsa, işlevinizi yalnızca sonlandırırsınız wp_send_json($array_with_values);. Gerek yok echoya da die.

Ayrıca iki yardım yardımcısı işlevi alırsınız wp_send_json_success()ve wp_send_json_error()hangisinin sırasıyla veya successolacağı adlı bir anahtar ekler .truefalse

Örneğin:

$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_encodebir istisna durumunda yanlış dönebilir, bu durumda ne olur?
prosti

Üçüncü argüman (derinlik) 0'dan
küçükse

Yani wp_send_json()bunun en iyi yol olduğuna inanıyorsunuz ? Neden?
prosti

@prosti bizim için bir wp_send_json() şeyler yapıyor. Bu soru ile de ilgilidir wp_send_json().
RRikesh

Bu tam olarak @RRikesh neden WP çekirdek bu işlevi kullanıyor soruyorum. Peki neden bu? Bu şekilde daha mı iyi?
prosti

3

Wordpress ajax / woo trade ajax genel sözdizimini kullanmak için aşağıdaki gibidir:

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

}

WordPress wp_die () işlevi sırasında dahili olarak bir filtre kullandığından, wp_die () işlevini kullanmalısınız. Wp_die () içermezsek, bu filtreyi kullanarak çalışan herhangi bir eklenti çalışmayabilir. Ayrıca die () ve diğer işlevler, yürütmeyi sonlandırırken dikkate alınması gereken herhangi bir wordpress işlevini düşünmeden hemen PHP yürütmesini öldürür.

Eğer içinde wp_send_json () kullanıyorsanız bu şekilde çalışırsınız

       function my_action_callback()
    {
    // your code goes here

      wp_send_json();

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

    }

Geri arama işlevi içine wp_send_json () eklerseniz, sonunda wp_die () kullanmak gerekli değildir . çünkü wordpress kendisi wp_send_json () fonksiyonu içinde wp_die () fonksiyonunu güvenle kullanır.


2

Bu sadece başkalarının söylediklerine ek olarak. Tercih etmenin nedeni wp_die, çekirdeğin orada eylemleri tetikleyebilmesi ve eklentilerin izleme, izleme veya önbellekleme gibi şeyleri düzgün bir şekilde tamamlayabilmesidir.

Genel olarak, doğrudan PHP çağrısından elde edemeyeceğiniz bir değer (önbellek, eklenti entegrasyonu veya herhangi bir şey) eklediğinden, her zaman bir çekirdek API çağrısını tercih etmelisiniz.


2

Bu cevabı kabul etmeyeceğim, bu adil olmaz. Sadece önemli bulduğum öğeler hakkında bir taslak ve olası ipuçları oluşturmak istedim:

Wp-die () ana tanımı

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

Tipik olarak ajax çağrısından aldığımız şey bir çeşit yanıttır. Yanıt json olarak kodlanmış olabilir veya json olarak kodlanmamış olabilir.

Eğer jsonçıkışa ihtiyacımız olursa wp_send_jsoniki uydu harika fikirdir.

Ancak, geri dönebilir x-www-form-urlencodedveya multipart/form-dataveya text/xmlbaşka bir kodlama türü getirebiliriz . Bu durumda kullanmayız wp_send_json.

Tüm html'yi döndürebiliriz ve bu durumda wp_die()birinci ve ikinci parametreyi kullanmak mantıklıdır , aksi takdirde bu parametreler boş olmalıdır.

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

Ancak wp_die()parametre olmadan çağrı yapmanın faydası nedir?


Son olarak, büyük WP çekirdeğini kontrol ederseniz bulabilirsiniz

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

Her iki format kullanılır die()ve wp_die(). Bana nedenini açıklayabilir misin?

Sonunda işte admin-ajax.phpgeri dönendie( '0' );

Neden olmasın wp_die(...)?


1

Kullanın wp_die(). WordPress işlevlerini olabildiğince kullanmak daha iyidir.


1

Kullanırsanız echo, sizi die()veya die(0)veya kullanmaya zorlar wp_die().

Kullanmazsanız echo, JavaScript bunu yapabilir.

Sonra verileri döndürmek için daha iyi bir yol kullanmalısınız: wp_send_json().

Geri aramanızdaki ( jsonbiçimdeki) verileri göndermek için aşağıdakileri kullanabilirsiniz:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

Hepsi senin için ölecek. Daha sonra çıkmaya veya ölmeye gerek yok.

GÜNCELLEME

Ve jsonçıktı biçimi olarak ihtiyacınız yoksa şunları kullanmalısınız:

wp_die($response)

Yanıtınız ölmeden önce geri dönecektir. Kodeksine göre:

İşlev wp_die(), boş veya zaman aşımı yanıtlarından kaçınmak için ölmeden hemen önce çıktı vermek üzere tasarlanmıştır.

Lütfen tam kodeks makalesini buradan okuyun .


1
Teşekkürler, bunun yerine ne öneriyorsun echo?
prosti

1
Not etmek gerekirse, Javascript işlemez echo. sizin için wp_send_json_*kullanır echove çıkar. Burada istemci ve sunucu arasında karışıklık var.
Brian Fegter

@prosti wp_send_json ()
Faisal Alvi

Teşekkürler ve jsonçıktı biçimi olarak ihtiyacımız yoksa ?
prosti

1
@prosti wp_die ($ response) kullanmanız gerekir, çünkü codex'a göre: wp_die () işlevi, boş veya zaman aşımı yanıtlarından kaçınmak için ölmeden hemen önce çıktı vermek üzere tasarlanmıştır.
Faisal Alvi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.