$wpdb->last_error non mostra la query in caso di errore
Sto inserendo dati in una tabella personalizzata utilizzando $wpdb->insert
. Tuttavia, in caso di errore non ottengo alcuna informazione da $wpdb->last_error
. Quale potrebbe essere la causa?
Ho già questa configurazione impostata in wp-config
define('WP_DEBUG', false);
define('SAVEQUERIES', true);
Il codice è il seguente:
$result = $wpdb->insert($this->table, $data_);
if (false === $result) {
error_log($wpdb->last_error);
}
$this->table
e $data_
sono popolati correttamente poiché l'operazione va a buon fine.
Ma non sembro ottenere alcuna informazione sulla query che ha fallito. C'è un modo per ottenere la query effettivamente eseguita in $wpdb->insert
?
Soluzione
Ho capito il problema. La query di inserimento falliva perché uno dei dati della colonna era troppo grande e superava la dimensione massima della colonna nel database. La colonna era varchar(500)
ma i dati effettivi superavano i 500 caratteri, causando il fallimento della query. Ho cambiato la colonna in TEXT
e l'inserimento è avvenuto con successo senza errori.
Se vuoi ottenere la query, dovrai usare $wpdb->last_query
(nota che non hai bisogno di SAVEQUERIES
, questo è utile solo se vuoi un registro di tutte le query ($wpdb->queries
).
last_error
è... beh, l'errore!
Aggiornamento: Possibile spiegazione per last_error
vuoto - questo è il sorgente di wpdb::query()
:
// Se stiamo scrivendo nel database, assicuriamoci che la query scriva in modo sicuro.
if ( $this->check_current_query && ! $this->check_ascii( $query ) ) {
$stripped_query = $this->strip_invalid_text_from_query( $query );
// strip_invalid_text_from_query() può eseguire query, quindi dobbiamo
// ripulire nuovamente, per assicurarci che tutto sia chiaro.
$this->flush();
if ( $stripped_query !== $query ) {
$this->insert_id = 0;
return false;
}
}
// Codice omesso
// Tieni traccia dell'ultima query per debug...
$this->last_query = $query;
$this->_do_query( $query );
// Codice omesso
// Se c'è un errore, prendine nota...
if ( $this->use_mysqli ) {
$this->last_error = mysqli_error( $this->dbh );
} else {
$this->last_error = mysql_error( $this->dbh );
}
In altre parole, WordPress sembra verificare preventivamente la query e interromperà l'esecuzione se ritiene che fallirà - in questo caso ottieni il tuo return false
ma nessun errore verrà impostato (poiché non è mai stato inviato al server MySQL).

ma perché non ottengo ancora nulla in last_error? La query insert restituisce false il che significa che qualcosa è fallito, ma non contiene ancora nulla in last_error? Strano?

https://core.trac.wordpress.org/ticket/32315
Uno degli input delle colonne potrebbe essere più grande della colonna stessa. WordPress rileva questo e non invierà nemmeno la query al database.
Il Diff mostra una patch per wp-db che puoi applicare per ottenere maggiori informazioni nel messaggio last_error in modo che non sia vuoto.

Questa è davvero una risposta fantastica. Ho adattato la tua risposta in un file wp-content/db.php così può essere facilmente e rapidamente inserito per mantenere la soluzione valida tra gli aggiornamenti di WordPress. Vedi qui per il gist e maggiori dettagli.

Oh fantastico, grazie @BrianC! Ho visto un'email poco fa che segnala come questo problema abbia ora una milestone per la versione 5.6.
