Beste Weg, um WordPress Ajax-Anfrage zu beenden und warum?

15

In Anbetracht der folgenden regulären WordPress-Ajax-Anforderungen:

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

Wird es am besten zu Ende Funktion sein merrychristmas_happynewyearmit die(), die(0), wp_die(), oder etwas anderes und warum?

prosti
quelle

Antworten:

12

Verwenden wp_die()ist die beste dieser Optionen.

Wie andere angemerkt haben, gibt es viele Gründe, eine WordPress-spezifische Funktion der einfachen vorzuziehen, dieoder exit:

  • Es erlaubt anderen Plugins, sich in die von aufgerufenen Aktionen einzuklinken wp_die().
  • Es ermöglicht die Verwendung eines speziellen Handlers zum Beenden basierend auf dem Kontext (dem Verhalten von wp_die() wird basierend darauf angepasst, ob die Anforderung eine Ajax-Anforderung ist oder nicht).
  • Es macht es möglich, Ihren Code zu testen.

Der letzte ist wichtiger, weshalb ich diesen Vermerk in den Kodex aufgenommen habe . Wenn Sie Unit- / Integrationstests für Ihren Code erstellen möchten , können Sie keine aufrufende exitoder diedirekt aufrufende Funktion testen . Das Skript wird beendet, wie es soll. Die Art und Weise, wie WordPress-eigene Tests eingerichtet werden, um dies zu vermeiden (für die Ajax-Rückrufe, für die es Tests gibt), besteht darin, sich in die von ausgelösten Aktionen einzuklinken wp_die()und eine Ausnahme auszulösen. Dadurch kann die Ausnahme innerhalb des Tests abgefangen und die Ausgabe des Rückrufs (falls vorhanden) analysiert werden.

Das einzige Mal, das Sie verwenden dieoder verwenden würden, exitist, wenn Sie eine spezielle Behandlung umgehen wp_die()und die Ausführung sofort beenden möchten . Es gibt einige Stellen, an denen WordPress dies ausführt (und andere Stellen, an denen WordPress möglicherweise diedirekt verwendet wird, nur weil die Verarbeitung von ausgeführtwp_die() noch nicht wichtig ist oder niemand versucht hat, Tests für ein Stück Code zu erstellen, sodass dies übersehen wurde). Denken Sie daran, dass dies auch das Testen Ihres Codes erschwert. Daher wird er im Allgemeinen nur in Code verwendet, der sich ohnehin nicht in einem Funktionskörper befindet (wie dies in WordPress der Fall ist admin-ajax.php). Also, wenn die Behandlung von wp_die()ausdrücklich nicht gewünscht ist, oder Sie das Skript an einem bestimmten Punkt vorsichtshalber beenden (wie zadmin-ajax.phpIn der Erwartung, dass Ajax-Rückrufe normalerweise bereits ordnungsgemäß beendet wurden, sollten Sie die diedirekte Verwendung in Betracht ziehen .

In Bezug auf wp_die()vs wp_die( 0 ), was Sie verwenden sollten, hängt davon ab, wie die Antwort auf diese Ajax-Anfrage auf dem Front-End behandelt wird. Wenn ein bestimmter Antworttext erwartet wird, müssen Sie diese Nachricht (oder in diesem Fall eine Ganzzahl) an übergeben wp_die(). Wenn nur auf eine erfolgreiche 200Antwort gewartet wird ( Antwortcode oder was auch immer), muss nichts weiter übergeben werden wp_die(). Ich würde jedoch bemerken, dass ein Ende mit wp_die( 0 )die Antwort von der Standardantwort ununterscheidbar machen würde admin-ajax.php. 0Wenn Sie also mit enden , sehen Sie nicht, ob Ihr Rückruf ordnungsgemäß verbunden und tatsächlich ausgeführt wurde. Eine andere Nachricht wäre besser.

Wie in anderen Antworten ausgeführt, werden Sie häufig wp_send_json()et al. Dies ist hilfreich, wenn Sie eine JSON-Antwort zurücksenden. Dies ist im Allgemeinen eine gute Idee. Dies ist auch besser als das bloße Aufrufen wp_die()mit einem Code, da Sie bei Bedarf viel mehr Informationen in ein JSON-Objekt zurückgeben können. Wenn Sie wp_send_json_success()und verwenden, wp_send_json_error()wird die Erfolgs- / Fehlermeldung auch in einem Standardformat zurückgesendet, das alle von WordPress bereitgestellten JS Ajax-Hilfsfunktionen verstehen (wie wp.ajax).

TL; DR: Sie sollten wahrscheinlich immer verwenden wp_die(), ob in einem Ajax-Rückruf oder nicht. Noch besser, senden Sie Informationen mit wp_send_json()und Freunden zurück.

JD
quelle
Sie haben einige gute Gesichtspunkte hinzugefügt. Ich habe den Thread mit meinen Gedanken aktualisiert. Sie können kommentieren, wenn Sie möchten. @ JD
Prosti
@prosti Danke, ich habe einen Absatz darüber hinzugefügt, wann und warum Sie / WordPress möglicherweise dieanstelle von verwenden wp_die().
JD
Ich weiß Ihre Bemühungen zu schätzen, verstehe jedoch nicht, warum der WordPress-Kern manchmal die()und manchmal verwendet wird wp_die().
Prosti
Danke @prosti. Was den Grund angeht, warum WordPress manchmal verwendet die(), ist es in einigen Fällen nur Legacy-Code oder die()wird verwendet, um das Skript als letzten Ausweg zu beenden, wenn etwas wirklich Unerwartetes passiert ist und wp_die()nicht aufgerufen wurde. In anderen Fällen hat niemand Tests für einen Code erstellt, und die spezielle Behandlung von wp_die()wird nicht speziell benötigt, sodass sie übersehen wurde.
JD
13

Aus dem Codex AJAX in 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
}

Beachten Sie die Verwendung von wp_die(), anstelle von die()oder exit(). Die meiste Zeit sollten Sie wp_die()in Ihrer Ajax-Rückruffunktion verwenden. Dies bietet eine bessere Integration mit WordPress und erleichtert das Testen Ihres Codes.

Tunji
quelle
Der von Ihnen notierte Codex ist großartig, aber der WordPress-Kern folgt ihm nicht. Wie ist es damit?
Prosti
3
Alle wp_send_json_*Funktionen alle verwenden, wp_send_jsondie immer noch anruftwp_die
Tunji
Aber warum, ich vermisse hier etwas. Haben Sie diese Funktionen analysiert und die Schlussfolgerungen gezogen?
Prosti
1
Stört es Sie, wp_send_jsonder Antwort einen Hinweis hinzuzufügen ?
Mark Kaplun
1
welches ist richtig? wp_die (0) oder wp_die ()?
Anwer AR
5

Sie können auch wp_send_json()im Codex als beschrieben verwendensend a JSON response back to an AJAX request, and die().

Wenn Sie also ein Array zurückgeben müssen, müssen Sie Ihre Funktion nur mit beenden wp_send_json($array_with_values);. Keine Notwendigkeit echooder die.

Sie erhalten auch zwei Funktionen Hilfe Helfer wp_send_json_success()und wp_send_json_error()welche fügt einen Schlüssel mit dem Namen , successder sein trueoder falsesind.

Beispielsweise:

$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
quelle
wp_json_encodeWas ist in diesem Fall, wenn eine Ausnahme false zurückgibt?
Prosti
Es wird eine Ausnahme
ausgelöst,
Sie glauben also, das wp_send_json()ist der beste Weg? Warum?
Prosti
@prosti wp_send_json() macht ein paar Sachen für uns. Diese Frage beschäftigt sich auch mit wp_send_json().
RRikesh
Genau aus diesem Grund frage ich @RRikesh, ob der WP-Core diese Funktion verwendet. Warum das? Ist es so besser?
Prosti
3

Für die Verwendung von WordPress Ajax / Woo Commerce Ajax lautet die allgemeine Syntax wie folgt:

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

}

Sie sollten wp_die () am Ende der Funktion verwenden. WordPress verwendet intern einen Filter während der Funktion wp_die (). Daher funktioniert ein Plugin, das diesen Filter verwendet, möglicherweise nicht, wenn wir nicht wp_die () einschließen. Auch die () und andere Funktionen beenden die PHP-Ausführung sofort, ohne eine WordPress-Funktion zu berücksichtigen, die beim Beenden der Ausführung berücksichtigt werden sollte.

Wenn Sie wp_send_json () verwenden, funktionieren Sie so

       function my_action_callback()
    {
    // your code goes here

      wp_send_json();

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

    }

Es ist nicht erforderlich, wp_die () am Ende zu verwenden, wenn Sie wp_send_json () in die Rückruffunktion einschließen . weil wordpress selbst die Funktion wp_die () sicher innerhalb der Funktion wp_send_json () verwendet.

Saran
quelle
2

Dies ist nur eine Ergänzung zu dem, was andere gesagt haben. Der Grund dafür wp_dieist, dass core dort Aktionen auslösen kann und Plugins Dinge wie Tracing, Monitoring oder Caching ordnungsgemäß abschließen können.

Im Allgemeinen sollten Sie einen Kern-API-Aufruf immer einem verfügbaren vorziehen, da er höchstwahrscheinlich einen Wert hinzufügt (Caching, Plug-in-Integration oder was auch immer), den Sie nicht durch den direkten PHP-Aufruf erhalten.

Mark Kaplun
quelle
2

Ich werde diese Antwort nicht akzeptieren, das wäre nicht fair. Ich wollte nur eine Übersicht und mögliche Hinweise zu den Elementen erstellen, die ich für wichtig halte:

Die Hauptdefinition von 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: }

Typischerweise ist das, was wir von einem Ajax-Anruf erhalten, eine Art Antwort. Die Antwort kann in JSON codiert sein oder kann nicht in JSON codiert sein.

Für den Fall, dass wir einen jsonAusbruch brauchen, sind wp_send_jsonzwei Satelliten eine großartige Idee.

Jedoch können wir zurückkommen x-www-form-urlencodedoder multipart/form-dataoder text/xmloder anderer Codierungstyp. In diesem Fall verwenden wir nicht wp_send_json.

Wir können den gesamten HTML-Code zurückgeben. In diesem Fall ist es sinnvoll, den wp_die()ersten und den zweiten Parameter zu verwenden. Andernfalls sollten diese Parameter leer sein.

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

Aber was bringt es, wp_die()ohne Parameter aufzurufen ?


Schließlich, wenn Sie den großen WP-Kern überprüfen, können Sie finden

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

Beide Formate werden verwendet die()und wp_die(). Kannst du erklären warum?

Schließlich ist hier was admin-ajax.phpzurückkehrtdie( '0' );

Warum nicht wp_die(...)?

prosti
quelle
1

Verwenden Sie wp_die(). Es ist besser, WordPress-Funktionen so oft wie möglich zu verwenden.

Greeso
quelle
1

Wenn Sie verwenden echo, werden Sie gezwungen, die()oder die(0)oder zu verwenden wp_die().

Wenn Sie dies nicht verwenden echo, kann JavaScript dies verarbeiten.

Dann sollten Sie sich eine bessere Art und Weise verwenden , um Daten zurück: wp_send_json().

Um Daten in Ihrem Rückruf (im jsonFormat) zu senden , können Sie Folgendes verwenden:

wp_send_json()

wp_send_json_success()

wp_send_json_error()

Alle von ihnen werden für dich sterben. Keine Notwendigkeit zu verlassen oder danach zu sterben.

AKTUALISIEREN

Und wenn Sie kein jsonAusgabeformat benötigen , sollten Sie Folgendes verwenden:

wp_die($response)

Es wird Ihre Antwort zurückgeben, bevor es stirbt. Nach dem Kodex:

Die Funktion wp_die()ist so konzipiert, dass die Ausgabe unmittelbar vor dem Tod erfolgt, um Leerlauf- oder Zeitüberschreitungsreaktionen zu vermeiden.

Bitte lesen Sie den vollständigen Codex-Artikel hier .

Faisal Alvi
quelle
1
Danke, was schlägst du stattdessen vor echo?
Prosti
1
Zu beachten ist, dass Javascript nicht funktioniert echo. wp_send_json_*verwendet echound beendet für Sie. Hier besteht eine Verwechslung zwischen Client und Server.
Brian Fegter
@prosti wp_send_json ()
Faisal Alvi
Danke, und falls wir nicht jsonals Ausgabeformat brauchen ?
Prosti
1
@prosti, als Sie sollten wp_die ($ response) verwenden, da laut Codex: Die Funktion wp_die () so konzipiert ist, dass sie eine Ausgabe kurz vor ihrem Tod ausgibt, um leere oder Timeout-Antworten zu vermeiden.
Faisal Alvi