วิธีที่ดีที่สุดในการจบคำขอ WordPress ajax และทำไม


16

พิจารณาคำขออาแจ็กซ์ WordPress แบบปกติเช่นนี้:

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

มันจะดีที่สุดในการฟังก์ชั่นที่สิ้นสุดmerrychristmas_happynewyearกับdie(), die(0), wp_die()หรือสิ่งอื่นและทำไม?

คำตอบ:


13

การใช้wp_die()เป็นตัวเลือกที่ดีที่สุด

ดังที่คนอื่น ๆ ระบุไว้มีหลายเหตุผลที่จะชอบฟังก์ชั่นที่เฉพาะเจาะจงของ WordPress มากกว่าธรรมดาdieหรือexit:

  • จะช่วยให้ปลั๊กอินอื่น ๆ wp_die()เพื่อเบ็ดลงไปในการดำเนินการที่เรียกได้ว่า
  • อนุญาตให้ใช้ตัวจัดการพิเศษสำหรับการออกจากการใช้งานตามบริบท (พฤติกรรมของได้wp_die()รับการปรับแต่งขึ้นอยู่กับว่าคำขอนั้นเป็นคำขอ Ajax หรือไม่)
  • ทำให้สามารถทดสอบรหัสของคุณได้

คนสุดท้ายที่มีความสำคัญมากขึ้นซึ่งเป็นเหตุผลว่าทำไมผมเพิ่มทราบว่าไป Codex หากคุณต้องการสร้างการทดสอบหน่วย / การรวมสำหรับรหัสของคุณคุณจะไม่สามารถทดสอบฟังก์ชั่นที่โทรexitหรือdieโดยตรง มันจะยุติสคริปต์เหมือนที่ควรจะเป็น วิธีที่การทดสอบของ WordPress ถูกตั้งค่าเพื่อหลีกเลี่ยงปัญหานี้ (สำหรับการเรียกกลับของ Ajax ที่มีการทดสอบ) คือการเชื่อมโยงกับการกระทำที่เกิดขึ้นจากwp_die()และโยนข้อยกเว้น สิ่งนี้จะช่วยให้สามารถตรวจสอบข้อยกเว้นภายในการทดสอบและวิเคราะห์ผลลัพธ์ของการติดต่อกลับ (ถ้ามี)

ครั้งเดียวที่คุณจะใช้dieหรือexitถ้าคุณต้องการข้ามการจัดการพิเศษจากwp_die()และฆ่าการดำเนินการทันที มีบางสถานที่ที่ WordPress ทำเช่นนี้ (และที่อื่น ๆ ที่มันอาจใช้dieโดยตรงเพราะการจัดการจากwp_die()นั้นไม่สำคัญหรือไม่มีใครพยายามสร้างการทดสอบสำหรับโค้ดหนึ่งชิ้นเลยก็ถูกมองข้ามไป) โปรดจำไว้ว่าสิ่งนี้จะทำให้รหัสของคุณทดสอบได้ยากขึ้นดังนั้นโดยทั่วไปจะใช้เฉพาะในรหัสที่ไม่ได้อยู่ในส่วนของฟังก์ชัน (เช่นเดียวกับ WordPress admin-ajax.php) ดังนั้นหากwp_die()ไม่ต้องการจัดการโดยเฉพาะหรือคุณกำลังฆ่าสคริปต์ในบางจุดเพื่อเป็นการป้องกันไว้ก่อน (เช่นadmin-ajax.phpคาดหวังว่าโดยปกติแล้วการโทรกลับของอาแจ็กซ์จะออกไปแล้วอย่างเหมาะสมแล้วคุณอาจพิจารณาใช้งานdieโดยตรง

ในแง่ของwp_die()vs 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()จะส่งข้อความความสำเร็จ / ข้อผิดพลาดกลับมาในรูปแบบมาตรฐานที่ฟังก์ชันตัวช่วย JS Ajax ที่จัดทำโดย WordPress จะสามารถเข้าใจได้ (เช่น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()ไม่จำเป็นโดยเฉพาะดังนั้นจึงถูกมองข้าม
JD

13

จาก codex 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 ที่คุณจดบันทึกไว้นั้นยอดเยี่ยม แต่เวิร์ดเพรสคอร์ไม่ได้ติดตาม แล้วมันล่ะ?
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()อธิบายไว้ใน Codex เป็น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ซึ่งจะเป็นtrueหรือ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ในกรณีที่มีข้อยกเว้นอาจส่งคืนเท็จเกิดอะไรขึ้นในกรณีนั้น
prosti

มันจะโยนข้อยกเว้นถ้าอาร์กิวเมนต์ที่สาม (ความลึก) น้อยกว่า 0
RRikesh

ดังนั้นคุณเชื่อว่าwp_send_json()เป็นวิธีที่ดีที่สุด? ทำไม?
prosti

@prosti wp_send_json() ทำบางสิ่งให้เรา คำถามนี้wp_send_json()ยังเกี่ยวข้องกับ
RRikesh

นี่คือ @RRikesh ว่าทำไมฉันถึงขอให้ WP core ใช้ฟังก์ชั่นนั้น เหตุใดจึงเป็นเช่นนี้ มันจะดีกว่าอย่างนั้นเหรอ?
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 () ที่ส่วนท้ายของ function เนื่องจาก wordpress ใช้ตัวกรองภายในระหว่าง wp_die () function ดังนั้นปลั๊กอินใด ๆ ที่ทำงานโดยใช้ตัวกรองนั้นอาจไม่ทำงานหากเราไม่รวม 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_die () ในตอนท้ายถ้าคุณรวม wp_send_json () ภายในฟังก์ชันการเรียกกลับ เพราะเวิร์ดเพรสเองใช้ฟังก์ชั่น wp_die () อย่างปลอดภัยภายในฟังก์ชั่น wp_send_json ()


2

นี่เป็นเพียงแค่นอกเหนือจากสิ่งที่คนอื่นพูด เหตุผลที่ต้องการwp_dieคือแกนกลางสามารถเรียกใช้การกระทำที่นั่นและปลั๊กอินสามารถทำสิ่งต่าง ๆ ได้อย่างสมบูรณ์เช่นการติดตามการตรวจสอบหรือการแคช

โดยทั่วไปคุณควรต้องการการเรียก 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

ในกรณีที่เราต้องการการjsonระเบิดwp_send_jsonหรือสองดาวเทียมเป็นความคิดที่ดี

อย่างไรก็ตามเราอาจส่งคืนx-www-form-urlencodedหรือmultipart/form-dataหรือtext/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()

หากคุณไม่ได้ใช้echoJavaScript สามารถจัดการกับมันได้

wp_send_json()แล้วคุณควรใช้วิธีที่ดีกว่าที่จะกลับมาข้อมูล:

ในการส่งข้อมูลในการโทรกลับ (ในjsonรูปแบบ) คุณสามารถใช้สิ่งต่อไปนี้:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

พวกเขาทั้งหมดจะตายเพื่อคุณ ไม่จำเป็นต้องออกหรือตายหลังจากนั้น

UPDATE

และหากคุณไม่ต้องการใช้jsonรูปแบบเอาต์พุตคุณควรใช้:

wp_die($response)

มันจะตอบกลับคุณก่อนที่มันจะตาย ตาม codex:

ฟังก์ชั่นwp_die()ถูกออกแบบมาเพื่อให้การส่งออกก่อนที่มันจะตายเพื่อหลีกเลี่ยงการตอบสนองที่ว่างเปล่าหรือหมดเวลา

โปรดอ่านบทความ Codex เต็มรูปแบบที่นี่


1
ขอบคุณคุณแนะนำechoอะไรแทน
prosti

1
echoที่จะต้องทราบจาวาสคริปต์ไม่ได้จัดการ wp_send_json_*ใช้echoและออกจากคุณ มีความสับสนระหว่างไคลเอนต์และเซิร์ฟเวอร์
Brian Fegter

@prosti wp_send_json ()
Faisal Alvi

ขอบคุณและในกรณีที่เราไม่ต้องการjsonรูปแบบผลลัพธ์
prosti

1
@prosti มากกว่าที่คุณควรใช้ wp_die ($ response) เพราะตาม codex: ฟังก์ชั่น wp_die () ได้รับการออกแบบมาเพื่อให้เอาต์พุตก่อนที่มันจะตายเพื่อหลีกเลี่ยงการตอบสนองที่ว่างเปล่าหรือหมดเวลา
Faisal Alvi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.