$wpdb->get_results(...) restituisce un array vuoto nonostante la query corretta
Come implica il titolo, non riesco a ottenere risultati da $wpdb->get_results. Eseguire la query "grezza" ha successo, ma questo sembra fallire per qualche strana ragione sconosciuta.
global $wpdb;
$sql = "SELECT *
FROM something aki,
somethingelse akb,
somethingelseelse ac
WHERE aki.keyID = akb.keyID
AND akb.someID = ac.someID
AND aki.type LIKE '%thing%'";
$corps = $wpdb->get_results($sql, OBJECT);
var_dump($corps);
Utilizza $wpdb->show_errors( true )
prima della query e vedi quale errore viene restituito.
Il mio problema (perché ho vissuto la stessa situazione) era che avrei dovuto usare $wpdb->posts
invece di wp_posts
all'interno della query. Il prefisso delle tabelle può cambiare da installazione a installazione di WP o persino nella stessa installazione a seconda del momento (ad esempio, un amministratore può cambiare il prefisso quando vuole). Quindi, si dovrebbe scrivere la query in questo modo:
$query = "select <stuff here> from $wpdb->posts where <stuff here>";

Stavo risolvendo un problema con il mio script che restituiva un array vuoto in WordPress nonostante avessi una stringa MySQL apparentemente corretta. Si è scoperto che, a differenza della persona che aveva posto la domanda originale, io avevo utilizzato $wpdb->prepare(), ma la soluzione che ho trovato potrebbe comunque essere utile a qualcuno che si imbatte in questo Q&A (come è successo a me).
Questa stringa, AND aki.type LIKE '%thing%'"
, contiene i caratteri jolly percentuale (%
) che indicano che stiamo cercando una cella aki.type
che contiene thing
come parte del suo valore.
$wpdb->prepare
li converte in hash, e il server MySQL riceve qualcosa del genere: AND aki.type LIKE '{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}thing{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}'
. Naturalmente, non si otterrebbero risultati!
La pagina wpdb::prepare recita: 'I segni di percentuale letterali (%) nella stringa di query devono essere scritti come %%. I caratteri jolly percentuale (ad esempio, da usare nella sintassi LIKE) devono essere passati tramite un argomento di sostituzione contenente la stringa LIKE completa, questi non possono essere inseriti direttamente nella stringa di query. Vedere anche wpdb::esc_like().'
Quindi, la parte LIKE
deve essere preparata in questo modo (esempio tratto dalla pagina wpdb::esc_like()):
$wild = '%';
$find = 'only 43% of planets';
$like = $wild . $wpdb->esc_like( $find ) . $wild;
$sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );
Dove $wpdb->esc_like()
dovrebbe essere utilizzato prima di $wpdb->prepare()
.
E se si desidera sostituire manualmente i segnaposto dei caratteri jolly percentuale, si dovrebbe usare $wpdb->remove_placeholder_escape() dopo $wpdb->prepare()
.

Sto pubblicando questo qui perché la query nella domanda è molto simile a quella che avevo io, e non era immediatamente ovvio che nel mio caso il problema fosse in $wpdb->prepare()
. Credo che qualcun altro potrebbe arrivare su questa pagina con lo stesso problema.

Il tuo problema è in qualche modo simile, ma non uguale alla domanda originale. Suggerisco di aprire una nuova domanda e poi rispondere (rispondere alla propria domanda è incoraggiato). Potrai quindi contrassegnare la tua risposta come quella accettata, e le persone che hanno problemi con $wpdb->prepare()
(invece che con $wpdb->get_results()
) potranno trovare più facilmente la tua domanda e risposta.

Ricevuto Pat J. Pensi che dovrei lasciare questa risposta qui o eliminarla?

Direi di lasciarlo. Se un amministratore lo ritiene inappropriato può rimuoverlo.

fatto https://wordpress.stackexchange.com/q/406772/190417

Potrebbe essere un po' tardi, ma ti manca la chiamata "prepare" necessaria in WordPress:
$Table_Name = $wpdb->prefix.'Nome Della Tua Tabella';
$sql_query = $wpdb->prepare("SELECT * FROM $Table_Name WHERE aki.keyID=%d AND akb.someID=%d AND aki.type like %s", akb.keyID, ac.someID, ''%cosa%');
$result = $wpdb->query( $sql_query );
I risultati multipli possono essere trovati nell'array.

Ha menzionato di aver sbagliato il nome della tabella sopra. La chiamata $wpdb->prepare() non è necessaria per una query completamente statica e non originata dall'utente, quindi qui probabilmente non è utile. In ogni caso, la tua riga prepare() sopra contiene codice che non è PHP.

Per le ricerche numeriche no... ma per le ricerche di stringhe in mySQL, richiedono un diverso set di passaggio di parametri che la chiamata prepare fa per te. Altrimenti devi inserire '%s%' attorno alla stringa. Se non lo fai, la ricerca mysql fallisce.

Corretto, ma hai letto male. "Statico" significa invariabile, cioè una query basata interamente su testo fisso, con variabili inserite. La query mostrata era testo fisso (aka "statico") quindi usare prepare non aggiunge nulla. Tuttavia, è buona pratica usare prepare() quando si interpolano valori in una query (aka dinamica o non statica). Saluti.

Ho avuto lo stesso problema, un'istruzione SQL corretta, nessun errore, ma nessun risultato utilizzando wpdb.
La soluzione per me è stata avere la corretta collazione/codifica dei caratteri (ad esempio COLLATE 'utf8_general_ci') per la mia tabella.
Avevo una query che funzionava, la tabella è stata sostituita con un dump da un altro server (un server più vecchio) e la mia query ha smesso di funzionare. Restituiva NULL o 0 anche se eseguire la query nel database restituiva i risultati corretti.
Ho creato le tabelle in entrambi i modi (un paio di volte perché non ci credevo), ho eseguito lo stesso script di inserimento dati e non ho cambiato il mio codice PHP/wpdb.
Quando la tabella è stata creata in questo modo, la mia query NON ha funzionato.
CREATE TABLE IF NOT EXISTS `vf_user` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`email` varchar(50) NOT NULL,
`full_name` varchar(25) NOT NULL,
`password` varchar(25) NOT NULL,
`role` enum('user','tester','admin') NOT NULL DEFAULT 'user',
`phone` varchar(25) NOT NULL,
`last_modified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user_activation_key` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=325 DEFAULT CHARSET=utf8 COMMENT='users table';
Quando è stata creata in questo modo, la mia query ha restituito risultati
CREATE TABLE `vf_user` (
`id` MEDIUMINT(9) NOT NULL AUTO_INCREMENT,
`email` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
`full_name` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`password` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`role` ENUM('user','tester','admin') NOT NULL DEFAULT 'user' COLLATE 'utf8_general_ci',
`phone` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`last_modified` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user_activation_key` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `email` (`email`) USING BTREE
)
COMMENT='utenti con accesso al festival virtuale'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=325
;

La funzione wpdb->get_results
di WordPress restituisce il risultato se ha successo, altrimenti restituirà null. Ci possono essere molte ragioni se una query fallisce. Consulta l'articolo approfondito sul debug get_results() che restituisce risultati vuoti qui.
Sebbene tu possa usare funzioni come wpdb->show_error()
per verificare quale sia stato l'ultimo errore dopo l'esecuzione della query SQL, a volte questo errore restituisce vuoto. In tal caso, prova a utilizzare wpdb->last_query
per controllare la query finale che è stata generata.
