✅ Notizie, temi, plugin WEB e WordPress. Qui condividiamo suggerimenti e le migliori soluzioni per siti web.

Query WordPress con clausole IN (chi sapeva)?

22

Poco più di un anno fa, ho scritto un post su come utilizzare WP_Meta_Query ogni volta che si dispone di un set di chiavi che si desidera utilizzare per recuperare informazioni dal database.

Che dire del caso, tuttavia, quando si dispone di un numero di chiavi diverse che risulterebbe nella creazione di un array molto lungo per la classe WP_Meta_Query? Ad esempio, cosa succede se dovessi scorrere una raccolta di dati prima ancora di impostare la query?

A un certo livello, potrebbe sembrare che la cosa naturale da fare sarebbe:

  1. scorrere la raccolta di chiavi,
  2. costruire dinamicamente i risultati,
  3. combinarli in un unico set di risultati,
  4. quindi lavora con tutto ciò che ti viene dato.

Ma non suona un po’ ingombrante (per non parlare di lento)?

Quando si tratta di utilizzare l’API di WordPress, faccio il possibile per attenermi ad essa prima di parlare, ad esempio, direttamente al database, ma ci sono anche momenti in cui ha senso scrivere una query grezza piuttosto che scrivere un tipo di codice intelligente semplicemente per far funzionare l’API di WordPress.

Prima di entrare nella logica del perché ho fatto le cose che ho, voglio spiegare il problema e l’approccio. Questo probabilmente salverà qualcuno dal saltare prematuramente nei commenti.

Questo screenshot non ha nulla a che fare con la query. Solo una foto dell’IDE per divertimento.

Quindi ecco qui:

  • Ho una matrice standard di valori che vengono eventualmente utilizzati per aiutare a prendere i metadati e creare un tipo di post personalizzato da essi (perché sono stati importati da una fonte di terze parti).
  • Sono un grande sostenitore della parametrizzazione delle query (e quindi dell’utilizzo di prepare) per assicurarmi che i dati vengano interrogati correttamente sul database. Sfortunatamente, ciò non accadeva durante il tentativo di eseguire questa query. Spiegherò perché più avanti in questo post.
  • Pertanto, prendere l’array e convertirlo in una stringa è utile, ma non risolve ancora il problema sul motivo per cui la  funzione di preparazione standard non funzionava.

Detto questo, ti spiego alcune cose:

  1. perché ho scelto di utilizzare un array per memorizzare i valori dei metadati,
  2. perché ho usato implode per convertirli in una stringa,
  3. perché non sto usando prepare per gestire la query.

Sui valori dei metadati

Il motivo per mantenere i metadati in un array come proprietà della classe è perché questo array potrebbe cambiare nel tempo.

Cioè, potrebbe essere necessario importare ulteriori dati di terze parti, rimuovere dati di terze parti o apportare alcune modifiche a tutto ciò che è presente.

Quando questi dati vengono conservati in un unico posto, è molto più semplice gestire le versioni future del codice.

Implosione dell’array

Ogni volta che esegui una query sul database e devi lavorare con una matrice di dati, puoi utilizzare WP_Meta_Query e utilizzare ciascuna chiave come parte della matrice degli argomenti.

Ma se hai un set di dati relativamente grande, devi prima scorrerlo tutto, quindi devi creare la query, quindi devi elaborarla.

E una volta che hai fatto tutto questo, non sono convinto che il codice che è stato scritto non sia andato a scapito delle prestazioni. Questo è il motivo per cui, a volte, scelgo di utilizzare wpdb.

Non utilizzando Prepara

Ora, interfacciandomi direttamente con il database, cerco di assicurarmi:

  1. Ho una buona ragione per farlo,
  2. Sto usando query parametrizzate.

Ma ho lavorato con questo specifico insieme di dati per un po’ cercando di utilizzare ogni permutazione dello sviluppo di WordPress di cui sono a conoscenza (incluso parlarne con diversi colleghi) per cercare di farlo funzionare nel miglior modo possibile.

Non stava succedendo, però. Ed è allora che mi sono imbattuto nella seguente pagina del Codex :

Nel 99% dei casi, puoi invece usare $wpdb->prepare(), e questo è il metodo consigliato. Questa funzione è da usare solo in quei rari casi in cui non puoi usare facilmente $wpdb->prepare(). Un esempio è la preparazione di un array da utilizzare in una clausola IN.

Ed è esattamente quello che stavo cercando di fare: stavo cercando di cercare nella meta tabella dei post in cui i valori della meta chiave erano contenuti in un array.

Quindi ecco come ho risolto tutto questo.

Innanzitutto, ho creato un array per contenere le varie meta chiavi che so che alla fine avrò bisogno di mappare (sebbene il valore delle chiavi non abbia importanza ai fini di questo post):

<?php

// This is used to maintain a map of data should we need to add more.
$data_types = [
    'data_item_one',
    'data_item_two',
    '...'
    'data_item_ten,
];

Quindi li ho convertiti in una stringa pronta per MySQL. Certo, questo non è l’input dell’utente e viene utilizzato in una  clausola IN, quindi non può essere utilizzato in  un’istruzione prepare :

<?php

/**
 * Converts the incoming array into a comma-delimited string with
 * quotes wrapped around each key.
 *
 * @access private
 *
 * @param  array $arr The array to convert to a string.
 * @return string     The string representation of the array delimited by quotes and commas.
 */
private function convert_to_sql_ready_string( $arr) {
  return '"'. implode( $arr, '","' ). '"';
}

Infine, ho creato la query e recuperato i risultati:

<?php

public function get_data_values() {

  global $wpdb;
  $query = "
    SELECT post_id, meta_key, meta_value 
    FROM $wpdb->postmeta WHERE
    meta_key in ($this->data_types) AND 
    meta_value <> '';
  ";

  $results = $wpdb->get_results( $query );

  return $results;
}

Ed è così che ho finito per lavorare con gli array, la proprietà della classe e per impostare la mia query.

È questo il modo migliore per lavorare con le query di WordPress con clausole IN? Non ne sono sicuro, ma data la mia esperienza, quello che ho letto e come sta funzionando, sono contento del risultato finale.

Fonte di registrazione: tommcfarlin.com

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More