WordPress ajaxリクエストを終了する最良の方法とその理由は?


16

次のような通常のWordPress ajaxリクエストを検討してください。

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

それは、機能を終了するのが最善だろうmerrychristmas_happynewyeardie()die(0)wp_die()、または他の何か、なぜ?

回答:


13

wp_die()これらのオプションの中で使用するのが最善です。

他の人が指摘したように、プレーンdieまたはよりもWordPress固有の機能を好む多くの理由がありますexit

  • 他のプラグインが呼び出されたアクションにフックできるようにします wp_die()ます。
  • コンテキストに基づいて、終了するための特別なハンドラーを使用できます( wp_die()、リクエストがAjaxリクエストであるかどうかに基づいて調整さ)。
  • コードのテストが可能になります。

最後の1つはより重要です。そのため、このメモをCodexに追加しました。コードのユニット/統合テスト作成する場合、exitまたはdie直接呼び出す関数をテストすることはできません。想定されるように、スクリプトを終了します。これを回避するためにWordPress独自のテストを設定する方法(テストを行うAjaxコールバックの場合)は、以下によってトリガーされるアクションにフックすることです。wp_die()、例外をスローすることです。これにより、テスト内で例外をキャッチし、コールバックの出力(ある場合)を分析できます。

使用dieするのexitは、または特別な処理をバイパスしてwp_die()すぐに実行を終了する場合のみです。WordPressがこれを行う場所がいくつかあります(またdie、処理wp_die()が重要でないため、またはコードの一部のテストをまだ作成しようとしていないために直接使用する可能性があるため、見落とされていました)。また、これによりコードのテストが難しくなるため、一般的には、とにかく関数本体にないコードでのみ使用されます(WordPressでのようにadmin-ajax.php)。そのためからの処理が行われる場合、wp_die()が特に望ましくない場合、または予防措置として特定の時点でスクリプトを強制終了する場合(admin-ajax.php通常、Ajaxコールバックが既に適切に終了していることを期待して)、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()、WordPressが提供するJS Ajaxヘルパー関数が理解できる標準形式で成功/エラーメッセージが返されます(など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

プラグインのコーデックス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()代わりにの使用に注意してください。ほとんどの場合、Ajaxコールバック関数で使用する必要があります。これにより、WordPressとの統合が改善され、コードのテストが簡単になります。die()exit()wp_die()


あなたが指摘したccodexは素晴らしいですが、WordPressコアはそれに従いません。どのようにそのことについて?
prosti

3
まだ呼び出すすべてのwp_send_json_*機能が使用さwp_send_jsonれますwp_die
Tunji

しかし、なぜ、私はここに何かが欠けています。これらの機能を分析し、結論を出しましたか?
prosti

1
wp_send_json答えにメモを追加してもよろしいですか?
マークカプルン

1
どちらが正しい?wp_die(0)またはwp_die()?
アンワーAR

5

wp_send_json()コーデックスで説明されているように使用することもできますsend a JSON response back to an AJAX request, and die().

したがって、配列を返す必要がある場合は、関数をで終了するだけwp_send_json($array_with_values);です。echoまたはする必要はありませんdie

また、2つのヘルプヘルパー関数wp_send_json_success()を取得します。これらの関数wp_send_json_error()は、それぞれまたはという名前のキーを追加します。successtruefalse

例えば:

$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例外がfalseを返す場合、その場合はどうでしょうか?
prosti

三番目の引数(深さ)が0未満である場合には、例外をスロー
RRikesh

あなたはそれwp_send_json()が最良の方法だと信じていますか?どうして?
prosti

@prosti wp_send_json() はいくつかの処理を行います。この質問はにも対応していwp_send_json()ます。
RRikesh

これがまさにWPコアがその関数を使用するように求めている理由です。なぜこれなの?その方が良いですか?
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();

}

wordpressは、wp_die()関数の実行中にフィルターを内部的に使用するため、wp_die()を含めないと、そのフィルターを使用して機能しているプラ​​グインが機能しない場合があります。また、die()およびその他の関数は、実行を終了する際に考慮する必要のあるwordpress関数を考慮せずに、すぐにPHP実行を強制終了します。

あなたの内部で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_send_json()関数内でwp_die()関数を安全に使用するためです。


2

これは、他の人が言ったことに加えてだけです。好む理由wp_dieは、コアがそこでアクションをトリガーでき、プラグインがトレース、監視、キャッシュなどを適切に完了することができるからです。

一般に、直接のPHP呼び出しからは得られない価値(キャッシュ、プラグインの統合など)を追加する可能性が高いため、コアAPI呼び出しよりも常に優先する必要があります。


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でエンコードされていない場合があります。

ケースでは、必要jsonoutupt wp_send_jsonまたは2 satelitesは素晴らしいアイデアです。

ただし、返されるx-www-form-urlencodedmultipart/form-datatext/xmlまたはその他のエンコードタイプを使用する場合があります。その場合、を使用しませんwp_send_json

html全体を返すことがwp_die()できます。その場合は、最初と2番目のパラメーターを使用する意味があります。そうでない場合、これらのパラメーターは空でなければなりません。

 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

を使用する場合echodie()またはdie(0)またはの使用を強制しますwp_die()

を使用しない場合echo、JavaScriptで処理できます。

次に、データを返すためのより良い方法を使用する必要がありますwp_send_json()

コールバックでデータを(json形式で)送信するには、以下を使用できます。

wp_send_json()

wp_send_json_success()

wp_send_json_error()

それらはすべてあなたのために死ぬでしょう。終了する必要も、後で死ぬ必要もありません。

更新

そして、あなたが必要ない場合 json出力形式としては、次を使用する必要があります。

wp_die($response)

死ぬ前に応答を返します。コーデックスによると:

関数 wp_die()は、空の応答またはタイムアウト応答を回避するために、終了する直前に出力を提供するように設計されています。

ここでコーデックスの全記事をお読みください。


1
ありがとう、代わりに何を提案しますechoか?
prosti

1
Javascriptはを処理しないことに注意してくださいechowp_send_json_*を使用echoして終了します。ここでは、クライアントとサーバーの間で混乱があります。
ブライアンフェクター

@prosti wp_send_json()
ファイサルアルヴィ

おかげで、json出力形式として必要ない場合は?
prosti

1
@prostiより、wx_die($ response)を使用する必要があります。これは、codexによると、関数wp_die()は、空またはタイムアウトの応答を避けるために、死ぬ直前に出力を提供するように設計されているためです。
ファイサルアルヴィ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.