De ce $wpdb->last_error nu afișează interogarea în caz de eroare
Introduc date într-un tabel personalizat folosind $wpdb->insert
. Totuși, în caz de eroare, nu primesc nicio informație din $wpdb->last_error
. Care ar putea fi cauza acestui lucru?
Am deja această configurație setată în wp-config
:
define('WP_DEBUG', false);
define('SAVEQUERIES', true);
Codul este următorul:
$result = $wpdb->insert($this->table, $data_);
if (false === $result) {
error_log($wpdb->last_error);
}
$this->table
și $data_
sunt populate corect, deoarece rulează cu succes.
Dar nu par să primesc nicio informație despre interogarea care a eșuat. Există vreo modalitate prin care să obțin interogarea efectivă rulată în $wpdb->insert
?
Soluție
Am rezolvat problema. Interogarea de inserare a eșuat deoarece una dintre coloane avea date prea mari, depășind dimensiunea coloanei din baza de date. Coloana era varchar(500)
, dar datele reale aveau mai mult de 500 de caractere, ceea ce a făcut ca interogarea să eșueze. Am schimbat coloana în TEXT
, iar inserarea a reușit fără erori.
Dacă dorești interogarea, aceasta va fi $wpdb->last_query
(reține că nu ai nevoie de SAVEQUERIES
, acesta este necesar doar dacă vrei un istoric al fiecărei interogări ($wpdb->queries
).
last_error
este... ei bine, eroarea!
Actualizare: Posibilă explicație pentru last_error
fiind gol - acesta este codul sursă din wpdb::query()
:
// Dacă scriem în baza de date, asigurăm că interogarea va scrie în siguranță.
if ( $this->check_current_query && ! $this->check_ascii( $query ) ) {
$stripped_query = $this->strip_invalid_text_from_query( $query );
// strip_invalid_text_from_query() poate executa interogări, așa că trebuie
// să facem flush din nou, doar pentru a ne asigura că totul este clar.
$this->flush();
if ( $stripped_query !== $query ) {
$this->insert_id = 0;
return false;
}
}
// Cod redactat
// Păstrăm evidența ultimei interogări pentru depanare..
$this->last_query = $query;
$this->_do_query( $query );
// Cod redactat
// Dacă există o eroare, o notăm..
if ( $this->use_mysqli ) {
$this->last_error = mysqli_error( $this->dbh );
} else {
$this->last_error = mysql_error( $this->dbh );
}
Cu alte cuvinte, WordPress pare să verifice preventiv interogarea și va întrerupe dacă consideră că va eșua - în acest caz, vei primi return false
, dar nicio eroare nu va fi setată (deoarece interogarea nu a fost trimisă niciodată către serverul MySQL).

dar de ce tot nu primesc nimic în last_error? interogarea insert returnează false ceea ce înseamnă că ceva a eșuat, dar totuși nu conține nimic în last_error? Ciudat?

https://core.trac.wordpress.org/ticket/32315
Una dintre coloanele de intrare poate fi mai mare decât dimensiunea coloanei. WordPress detectează acest lucru și nici măcar nu va trimite interogarea către baza de date.
Diferența afișată arată un patch pentru wp-db pe care îl puteți aplica pentru a obține mai multe informații în mesajul last_error, astfel încât acesta să nu fie gol.

Acesta este cu adevărat un răspuns grozav. Am adaptat răspunsul tău într-un fișier wp-content/db.php, astfel încât să poată fi integrat ușor și rapid pentru a menține soluția peste actualizările WordPress. Vezi aici pentru detalii suplimentare și fragment de cod.

Oh, super, mulțumesc @BrianC! Am văzut recent un e-mail care menționa că această problemă are acum un milestone pentru versiunea 5.6.
