Cea mai bună modalitate de a încheia o cerere AJAX în WordPress și de ce?
Luând în considerare cererile AJAX obișnuite din WordPress, precum acestea:
add_action( 'wp_ajax_merrychristmas_happynewyear', array( $this, 'merrychristmas_happynewyear' ) );
add_action( 'wp_ajax_nopriv_merrychristmas_happynewyear', array( $this, 'merrychristmas_happynewyear' ) );
Care ar fi cea mai bună variantă pentru a încheia funcția merrychristmas_happynewyear
folosind die()
, die(0)
, wp_die()
, sau altă metodă și de ce?

Folosirea funcției wp_die()
este cea mai bună dintre aceste opțiuni.
După cum au menționat și alții, există multe motive pentru a prefera o funcție specifică WordPress în locul funcțiilor simple die
sau exit
:
- Permite altor plugin-uri să se conecteze la acțiunile apelate de
wp_die()
. - Permite utilizarea unui handler special pentru ieșire, în funcție de context (comportamentul funcției
wp_die()
este adaptat în funcție de faptul dacă cererea este sau nu o cerere Ajax). - Face posibilă testarea codului tău.
Ultimul punct este mai important, motiv pentru care am adăugat această notă în Codex. Dacă dorești să creezi teste unitare/integrale pentru codul tău, nu vei putea testa o funcție care apelează direct exit
sau die
. Aceasta va termina execuția scriptului, așa cum este de așteptat. Modul în care testele WordPress sunt configurate pentru a evita această problemă (pentru callback-urile Ajax pentru care există teste) este prin conectarea la acțiunile declanșate de wp_die()
și aruncarea unei excepții. Acest lucru permite capturarea excepției în cadrul testului și analizarea output-ului callback-ului (dacă există).
Singura situație în care ai folosi die
sau exit
este atunci când dorești să ocolești orice tratament special oferit de wp_die()
și să oprești execuția imediat. Există câteva locuri în care WordPress face acest lucru (și alte locuri în care ar putea folosi direct die
deoarece tratamentul oferit de wp_die()
nu este important sau nimeni nu a încercat să creeze teste pentru acea bucată de cod, așa că a fost omis). Reține că acest lucru face și codul tău mai dificil de testat, așa că este folosit în general doar în cod care nu se află într-un corp de funcție (așa cum face WordPress în admin-ajax.php
). Deci, dacă tratamentul oferit de wp_die()
nu este dorit în mod specific sau dacă oprești scriptul la un anumit punct ca o măsură de precauție (așa cum face admin-ajax.php
, așteptând ca de obicei un callback Ajax să se încheie corect), atunci ai putea lua în considerare utilizarea directă a funcției die
.
În ceea ce privește wp_die()
versus wp_die( 0 )
, alegerea depinde de ceea ce gestionează răspunsul acelei cereri Ajax pe partea de front-end. Dacă se așteaptă un anumit corp de răspuns, atunci trebuie să transmiți acel mesaj (sau întreg, în acest caz) către wp_die()
. Dacă tot ceea ce verifică este dacă răspunsul a avut succes (cod de răspuns 200
sau orice altceva), atunci nu este nevoie să transmiți nimic către wp_die()
. Aș menționa, totuși, că încheierea cu wp_die( 0 )
ar face răspunsul indistinct de răspunsul implicit al admin-ajax.php
. Așadar, încheierea cu 0
nu indică dacă callback-ul tău a fost conectat corect și a rulat efectiv. Un mesaj diferit ar fi mai potrivit.
După cum s-a menționat în alte răspunsuri, vei găsi adesea funcțiile wp_send_json()
și similare utile dacă transmiți un răspuns JSON înapoi, ceea ce este în general o idee bună. Acest lucru este de asemenea superior apelării simple a wp_die()
cu un cod, deoarece poți trimite mult mai multe informații într-un obiect JSON, dacă este necesar. Utilizarea funcțiilor wp_send_json_success()
și wp_send_json_error()
va trimite și mesajul de succes/eroare într-un format standard pe care orice funcții JS Ajax furnizate de WordPress le vor putea înțelege (cum ar fi wp.ajax
).
TL;DR: Ar trebui să folosești întotdeauna wp_die()
, indiferent dacă ești într-un callback Ajax sau nu. Chiar mai bine, trimite informații înapoi cu wp_send_json()
și funcțiile similare.

Ai adăugat niște puncte de vedere bune. Am actualizat discuția cu gândurile mele. Poți comenta dacă dorești. @J.D

@prosti Mulțumesc, am adăugat un paragraf despre când și de ce tu/WordPress ați putea folosi die
în loc de wp_die()
.

Apreciez efortul tău, totuși, nu înțeleg de ce WordPress core folosește uneori die()
și alteori wp_die()
.

Mulțumesc @prosti. Cât despre motivul pentru care WordPress folosește uneori die()
, în unele cazuri este doar cod moștenit, sau die()
este folosit pentru a opri scriptul ca ultimă soluție atunci când ceva cu adevărat neașteptat s-a întâmplat și wp_die()
nu a fost apelat. În alte cazuri, nimeni nu a creat teste pentru o bucată de cod, iar gestionarea specială din wp_die()
nu este necesară în mod specific, așa că a fost neglijată.

Din codex-ul AJAX în Plugin-uri
add_action( 'wp_ajax_my_action', 'my_action_callback' );
function my_action_callback() {
global $wpdb; // asta este modul în care obții acces la baza de date
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
echo $whatever;
wp_die(); // acest lucru este necesar pentru a termina imediat și a returna un răspuns corect
}
Observă utilizarea
wp_die()
, în loc dedie()
sauexit()
. În majoritatea cazurilor, ar trebui să foloseștiwp_die()
în funcția ta de callback pentru Ajax. Acest lucru asigură o integrare mai bună cu WordPress și facilitează testarea codului tău.

codex-ul pe care l-ai menționat este grozav, dar nucleul WordPress nu îl urmează. Ce părere ai despre asta?

Toate funcțiile wp_send_json_*
folosesc wp_send_json
care încă apelează wp_die

Dar de ce, eu nu înțeleg ceva aici. Ai analizat aceste funcții și ai ajuns la aceste concluzii?

Puteți folosi și wp_send_json()
descris în Codex ca trimite un răspuns JSON înapoi la o cerere AJAX și die().
Deci, dacă trebuie să returnați un array, trebuie doar să încheiați funcția cu wp_send_json($array_with_values);
. Nu este nevoie să folosiți echo
sau die
.
De asemenea, aveți la dispoziție două funcții ajutătoare wp_send_json_success()
și wp_send_json_error()
care adaugă o cheie numită success
care va fi true
sau false
respectiv.
De exemplu:
$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'; # Nu este executat deoarece a apelat die() deja.

wp_json_encode
în cazul unei excepții poate returna false, ce se întâmplă în acest caz?

Aruncă o excepție dacă al treilea argument (adâncimea) este mai mic decât 0.

@prosti wp_send_json()
face niște lucruri pentru noi. Această întrebare abordează și ea wp_send_json()
.

Tocmai de aceea @RRikesh întreb de ce WP core folosește această funcție. Deci de ce asta? Este mai bine așa?

Pentru a utiliza funcționalitatea Ajax în WordPress/WooCommerce, sintaxa generală este următoarea:
add_action( 'wp_ajax_my_action', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
function my_action_callback()
{
// codul tău aici
wp_die();
}
Este recomandat să folosești wp_die() la sfârșitul funcției. WordPress utilizează intern un filtru în timpul execuției funcției wp_die(). Astfel, orice plugin care funcționează folosind acel filtru poate să nu funcționeze corect dacă nu includem wp_die(). De asemenea, die() și alte funcții similare opresc imediat execuția PHP fără a ține cont de alte funcții WordPress care ar trebui luate în considerare la terminarea execuției.
Dacă folosești wp_send_json() în interiorul funcției, ca în exemplul următor:
function my_action_callback()
{
// codul tău aici
wp_send_json();
//wp_die(); nu este necesar să folosești wp_die();
}
Nu este necesar să folosești wp_die() la sfârșit dacă incluzi wp_send_json() în funcția de callback, deoarece WordPress folosește în mod sigur funcția wp_die() în interiorul wp_send_json().

Acest lucru este doar în plus față de ceea ce au spus alții. Motivul pentru a prefera wp_die
este că nucleul poate declanșa acțiuni acolo și pluginurile pot finaliza corect lucruri precum urmărirea, monitorizarea sau stocarea în cache.
În general, ar trebui să preferi întotdeauna un apel API al nucleului, dacă este disponibil, deoarece cel mai probabil adaugă o valoare (stocare în cache, integrare cu pluginuri sau orice altceva) pe care nu o obții de la apelul PHP direct.

Nu voi accepta acest răspuns, acest lucru nu ar fi corect. Voiam doar să creez o schiță și posibile indicii asupra elementelor pe care le consider importante:
Definiția principală a wp-die()
Fișier: wp-includes/functions.php
2607: /**
2608: * Oprește execuția WordPress și afișează un mesaj HTML cu eroarea.
2609: *
2610: * Această funcție completează funcția PHP `die()`. Diferența este că
2611: * va fi afișat HTML utilizatorului. Este recomandat să folosiți această funcție
2612: * doar atunci când execuția nu ar trebui să continue. Nu este recomandat
2613: * să apelați această funcție prea des și încercați să gestionați cât mai multe erori
2614: * în mod tăcut sau mai elegant.
2615: *
2616: * Ca scurtătură, codul de răspuns HTTP dorit poate fi transmis ca întreg
2617: * parametrului `$title` (titlul implicit s-ar aplica) sau parametrului `$args`.
2618: *
2619: * @since 2.0.4
2620: * @since 4.1.0 Parametrii `$title` și `$args` au fost modificați pentru a accepta opțional
2621: * un întreg care să fie folosit ca cod de răspuns.
2622: *
2623: * @param string|WP_Error $message Opțional. Mesaj de eroare. Dacă acesta este un obiect WP_Error,
2624: * și nu o cerere Ajax sau XML-RPC, se vor folosi mesajele de eroare.
2625: * Implicit gol.
2626: * @param string|int $title Opțional. Titlul erorii. Dacă `$message` este un obiect `WP_Error`,
2627: * datele de eroare cu cheia 'title' pot fi folosite pentru a specifica titlul.
2628: * Dacă `$title` este un întreg, atunci este tratat ca cod de
2629: * răspuns. Implicit gol.
2630: * @param string|array|int $args {
2631: * Opțional. Argumente pentru controlul comportamentului. Dacă `$args` este un întreg, atunci este tratat
2632: * ca cod de răspuns. Implicit array gol.
2633: *
2634: * @type int $response Codul de răspuns HTTP. Implicit 200 pentru cererile Ajax, 500 altfel.
2635: * @type bool $back_link Dacă să includă un link pentru a reveni. Implicit false.
2636: * @type string $text_direction Direcția textului. Acest lucru este util doar intern, când WordPress
2637: * se încarcă și localizarea site-ului nu este încă configurată. Acceptă 'rtl'.
2638: * Implicit valoarea 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: * Filtrează callback-ul pentru oprirea execuției WordPress pentru cererile Ajax.
2653: *
2654: * @since 3.4.0
2655: *
2656: * @param callable $function Numele funcției callback.
2657: */
2658: $function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
2659: } elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
2660: /**
2661: * Filtrează callback-ul pentru oprirea execuției WordPress pentru cererile XML-RPC.
2662: *
2663: * @since 3.4.0
2664: *
2665: * @param callable $function Numele funcției callback.
2666: */
2667: $function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );
2668: } else {
2669: /**
2670: * Filtrează callback-ul pentru oprirea execuției WordPress pentru toate cererile non-Ajax, non-XML-RPC.
2671: *
2672: * @since 3.0.0
2673: *
2674: * @param callable $function Numele funcției callback.
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
Fișier: wp-includes/functions.php
3144: /**
3145: * Trimite un răspuns JSON înapoi la o cerere Ajax.
3146: *
3147: * @since 3.5.0
3148: * @since 4.7.0 Parametrul `$status_code` a fost adăugat.
3149: *
3150: * @param mixed $response Variabilă (de obicei un array sau obiect) de codificat ca JSON,
3151: * apoi afișat și oprit.
3152: * @param int $status_code Codul de stare HTTP pentru 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
Fișier: wp-includes/load.php
1044: /**
1045: * Determină dacă cererea curentă este o cerere WordPress Ajax.
1046: *
1047: * @since 4.7.0
1048: *
1049: * @return bool True dacă este o cerere WordPress Ajax, false altfel.
1050: */
1051: function wp_doing_ajax() {
1052: /**
1053: * Filtrează dacă cererea curentă este o cerere WordPress Ajax.
1054: *
1055: * @since 4.7.0
1056: *
1057: * @param bool $wp_doing_ajax Dacă cererea curentă este o cerere WordPress Ajax.
1058: */
1059: return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
1060: }
În mod obișnuit, ceea ce primim de la un apel Ajax este un fel de răspuns. Răspunsul poate fi codificat în json sau poate să nu fie codificat în json.
În cazul în care avem nevoie de output json
, wp_send_json
sau cele două funcții satelit sunt o idee bună.
Cu toate acestea, putem returna x-www-form-urlencoded
sau multipart/form-data
sau text/xml
sau orice alt tip de codare. În acest caz, nu folosim wp_send_json
.
Putem returna HTML complet și în acest caz are sens să folosim primul și al doilea parametru al wp_die()
, altfel acești parametri ar trebui să fie goi.
wp_die( '', '', array(
'response' => null,
) );
Dar care este beneficiul apelării wp_die()
fără parametri?
În final, dacă verificăm nucleul WP, putem găsi
Fișier: wp-includes/class-wp-ajax-response.php
139: /**
140: * Afișează răspunsuri formatate XML.
141: *
142: * Setează header-ul Content-Type la 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();
Ambele formate sunt folosite die()
și wp_die()
. Poți explica de ce?
În final, iată ce returnează admin-ajax.php
: die( '0' );
De ce nu wp_die(...)
?

Dacă folosești echo
, acesta te va obliga să utilizezi die()
, die(0)
sau wp_die()
.
Dacă nu folosești echo
, JavaScript poate gestiona această situație.
Apoi, ar trebui să folosești o metodă mai bună pentru a returna date: wp_send_json()
.
Pentru a trimite date în callback-ul tău (în format json
), poți utiliza următoarele:
wp_send_json()
wp_send_json_success()
wp_send_json_error()
Toate acestea vor încheia execuția pentru tine. Nu este nevoie să folosești exit
sau die
ulterior.
ACTUALIZARE
Și dacă nu ai nevoie de json
ca format de ieșire, ar trebui să folosești:
wp_die($response)
Acesta va returna răspunsul tău înainte de a încheia execuția. Conform codex-ului:
Funcția
wp_die()
este proiectată să ofere o ieșire chiar înainte de a încheia execuția pentru a evita răspunsuri goale sau care expiră.
Te rugăm să citești întregul articol din codex aici.

De menționat, Javascript nu procesează echo
. wp_send_json_*
folosește echo
și iese automat pentru tine. Există o confuzie aici între client și server.

@prosti atunci ar trebui să folosești wp_die($response) deoarece conform codex: Funcția wp_die() este concepută să ofere rezultat chiar înainte de a înceta pentru a evita răspunsuri goale sau care expiră.

Mulțumesc, @FaisalAlvi te rog [editează] răspunsul tău pentru a-l face mai atractiv pentru voturi. Nu lăsa detalii importante în comentarii.

@prosti Mulțumesc. Tocmai am actualizat răspunsul.
