In questa serie considereremo le tabelle del database personalizzate. Tratteremo come creare, mantenere e rimuovere la tabella, nonché come aggiungere, rimuovere e interrogare i dati in modo sicuro ed efficiente. In questo primo articolo esaminiamo quando i tavoli personalizzati possono essere appropriati, i pro e i contro del loro utilizzo e come creare la tabella.
Fortunatamente, WordPress fornisce un'API abbastanza consistente che rende la creazione e l'interazione con le tabelle personalizzate un po 'più semplice. In particolare: il $ wpdb
classe e il dbDelta ()
funzione che vedremo più durante la serie. Nonostante ciò, tuttavia, creare una tabella personalizzata significa creare qualcosa di estraneo a WordPress e perdere la maggior parte del framework che circonda le tabelle native. Per questo motivo, tu come autore del plugin sei responsabile dell'interazione sicura ed efficiente con esso. Quindi, prima di saltare è necessario considerare attentamente se sia più appropriato utilizzare un tavolo principale esistente.
Come accennato, le tabelle personalizzate si trovano al di fuori del normale framework WordPress e per la maggior parte questa è la causa alla base dei suoi svantaggi:
Non c'è una risposta "giusta" a questo, e è necessario un giudizio ragionevole sui pro e contro. Tuttavia, la sezione precedente delinea alcuni seri inconvenienti di non utilizzare lo schema di WordPress esistente - in quanto tale, se non sei sicuro, solitamente è meglio evitare di creare una tabella. Inoltre, un approccio basato su tabelle personalizzate richiede molto lavoro e offre ampie opportunità di accesso agli errori. Ma con questo in mente, quando potrebbe essere appropriato un tavolo personalizzato?
Uno degli argomenti più importanti per le tabelle personalizzate è quando i dati devono essere strutturati in modo tale da risultare inappropriati per le tabelle native. Il * _posts
la tabella è intrinsecamente orientata verso i post e le pagine, che potrebbero essere del tutto inadatti ai tuoi dati. In realtà i tuoi dati potrebbero essere meglio distribuiti su più tabelle, con relazioni tra loro. Potrebbe anche non essere così complicato: il plugin Posts 2 Posts utilizza una tabella personalizzata per memorizzare relazioni molti-a-molti tra i tipi di post. Questo poteva essere fatto usando l'API di tassonomia (e in origine era) o la meta API - ma nessuno di questi è particolarmente efficiente - e sebbene possa andare bene per i siti più piccoli, non si adatta bene. Scribu ha spostato Post 2 Post in un'implementazione di tabella personalizzata per consentire l'archiviazione di informazioni su una relazione.
Mentre la maggior parte dei casi può essere 'spremuta' nel * _posts
stampo usando post meta, questo potrebbe non fornire il percorso più efficiente: la metamorfonica post utilizza una colonna di valore non indicizzato per memorizzare i dati. È incredibilmente veloce nel recuperare i metadati di un post (anche qui WordPress impiega il caching), ma le query complesse che usano il meta-table possono essere inefficienti o quasi impossibili.
Relativo a quanto sopra è query complesse, che le tabelle native potrebbero non essere progettati per completare in modo efficiente. In Event Organizer, ad esempio, un evento è un post con date di eventi memorizzate in una tabella separata. Sebbene sia possibile archiviare tali date come post meta-fare in modo che quando gli eventi abbiano più di una data, renderebbe estremamente difficile e inefficiente qualsiasi query basata sulla data, in particolare perché la colonna del valore meta non è indicizzata.
Se usi wp_posts
e i tuoi dati sono sufficientemente grandi (più di 100.000 post) potrebbe ostacola le prestazioni, a seconda di quali query stai eseguendo. Questa argomentazione a parte è piuttosto debole in quanto vi sono molte incognite che ne comprometteranno la validità. In generale, però, i database sono veloci in ciò che fanno - e il framework WordPress circostante serve a ottimizzare le query il più possibile. In combinazione con gli altri due fattori, tuttavia, è possibile che una tabella personalizzata presenti l'opzione più sensata.
Una volta che hai deciso che una tabella personalizzata è necessaria, dobbiamo creare la tabella. Prima di farlo, memorizzeremo il nome del nostro tavolo personalizzato $ wpdb
. Questo globale contiene tutte le informazioni relative al database per il blog corrente (cambierà da sito a sito, quando si utilizza multi-sito). Aggiungeremo il nome della nostra tabella a questo globale. Questo non è affatto necessario, ma rende il resto del nostro codice leggermente più ordinato:
add_action ('init', 'wptuts_register_activity_log_table', 1); add_action ('switch_blog', 'wptuts_register_activity_log_table'); function wptuts_register_activity_log_table () global $ wpdb; $ wpdb-> wptuts_activity_log = "$ wpdb-> prefisso wptuts_activity_log";
Il codice precedente utilizza $ Wpdb-> prefix
per aggiungere un prefisso al nome della tabella. Il prefisso è per impostazione predefinita wp_
ma può essere modificato dall'utente in wp-config.php
. Questo è necessario quando potresti avere più di una installazione di WordPress usando lo stesso database, ma potrebbe anche essere cambiato per altri motivi. Come tale non puoi supporre che sia il prefisso wp_
. Come con le funzioni, le classi e le impostazioni, ecc, devi assicurarti che il nome della tua tabella sia unico.
In questa serie torneremo all'esempio seguente. Immaginiamo di creare una tabella per registrare le attività degli utenti (aggiornamento o rimozione di post, modifica delle impostazioni, caricamento di un'immagine, ecc.).
Esistono varie convenzioni per il modo in cui le colonne vengono nominate (e anche le tabelle), ma indipendentemente da come le chiami, è importante essere coerente. Ti consigliamo di utilizzare solo caratteri minuscoli in quanto in alcune situazioni i nomi delle colonne possono essere case sensitive e imporre tale regola rende meno probabili gli errori e migliora la leggibilità. Come vedremo più avanti nella serie, è utile anche quando devi inserire nella whitelist le colonne. Dovresti separare le parole nei nomi delle colonne (ad es. post_data
, POST_CONTENT
) per la leggibilità, ma dovresti farlo con i trattini bassi e mai spazi.
Dovresti anche evitare parole riservate. Se la colonna fa riferimento a una tabella esterna, si consiglia di utilizzare il nome di quella colonna straniera (ad esempio ID utente
, il nostro esempio).
Nel nostro esempio nomineremo le nostre colonne:
log_id
- l'ID del registro.ID utente
- l'ID utente per il quale il registro corrisponde.attività
- l'attività che si è verificata.object_id
- l'ID dell'oggetto (ad esempio post ID, ID utente, ID commento, ecc.) che era l'argomento dell'attività dell'utente.tipo di oggetto
- il tipo di oggetto (ad esempio "post", "utente", "commento" ecc.).activity_date
- il datetime dell'attività.Prima di andare oltre dovrai decidere i tipi di dati delle colonne che la tua tabella avrà. I tipi di colonna possono essere suddivisi in tre categorie: stringhe, numeri e dati. Per ognuno di questi ci sono molte varianti. Puoi trovare un riferimento completo qui.
È importante scegliere il tipo di dati appropriato per la tabella in quanto ciò influirà sull'efficacia delle query. Alcuni tipi di dati ti consentono di impostare un limite (ad es. varchar (40)
- che ti consente di memorizzare fino a 40 caratteri). Il limite è facoltativo, ma è consigliato in quanto può migliorare le prestazioni, quindi dovrai decidere per ogni colonna qual è la quantità massima di caratteri che la colonna richiederà. Nota per tipi di dati numerici la lunghezza si riferisce al numero di cifre, non al massimo (ad es. INT (10)
consente numeri interi non negativi fino a 10 cifre - quindi fino a 4.294.967.295).
Quando si memorizzano le date si dovrebbe quasi sempre usare il APPUNTAMENTO
tipo di dati (memorizzati come 2012-11-05 14:55:10) - e certamente non una rappresentazione umana amichevole della data (ad esempio il 5 novembre 2012 alle 14:55). APPUNTAMENTO
i valori possono essere facilmente formattati in forma leggibile dall'uomo usando funzioni come mysql2date ()
. È necessario memorizzare le date nel fuso orario UTC e, se necessario, impostarlo in un fuso orario diverso in uscita.
Nel nostro esempio avremo:
log_id
- bigint (20)ID utente
- bigint (20)attività
- varchar (20)object_id
- bigint (20)tipo di oggetto
- varchar (20)Data
- appuntamentoSuccessivamente dovrai decidere quali colonne indicizzare: queste saranno dichiarate come CHIAVE
s, uno dei quali sarà il CHIAVE PRIMARIA
. La chiave primaria è una colonna in cui ogni riga ha un unico voce - di solito è solo un intero autoincrementante, essenzialmente il 'numero di riga'.
I valori delle altre colonne indicizzate non devono necessariamente essere univoci, ma il valore dovrebbe determinare un set relativamente piccolo di record. L'idea di indicizzazione è di migliorare le query di lettura. Senza un indice una ricerca dovrebbe leggere l'intera tabella per trovare le righe corrispondenti. Se una colonna è indicizzata e parte della query, allora può trovare rapidamente le righe che corrispondono a quella colonna e quindi quel sottogruppo più piccolo di righe corrispondenti può essere confrontato con la query (L'analogia è un indice per un libro).
Pertanto, se non si esegue una query in base a tale colonna, l'indicizzazione di tale colonna non sarà di aiuto (se non si cerca mai una parola nell'indice del libro, potrebbe non esserci). Né se molti record condividono lo stesso valore, ad esempio una colonna di "genere", in quanto ciò non offrirà molti miglioramenti su una scansione completa della tabella (immagina un indice di un libro che elenca una parola che appare su ogni altra pagina).
Anche l'indicizzazione non è libera: colonne dichiarate come CHIAVE
Riducono le prestazioni in scrittura (per continuare l'analogia è necessario aggiornare l'indice del libro quando viene aggiunta o rimossa una parola indicizzata) e quindi dovrai decidere quale sia il giusto equilibrio per la tua configurazione. Ulteriori informazioni possono essere trovate qui.
Poiché è probabile che desideriamo eseguire una query per utente (per vedere la loro attività recente) indicizzeremo questa colonna e useremo il comando log_id
come la chiave primaria.
Inseriremo il codice per la creazione della tabella personalizzata all'interno della seguente funzione:
function wptuts_create_tables () // Il codice per creare una tabella va qui // Crea tabelle sull'attivazione del plugin register_activation_hook (__FILE__, 'wptuts_create_tables');
Questa funzione dovrà essere richiamata sul hook di attivazione del plugin, così come ogni volta che desideriamo apportare modifiche alla tabella, ad esempio aggiungendo colonne o cambiando il loro tipo di dati (vedremo perché più avanti nella serie).
Il fatto che usando il gancio di attivazione, wptuts_create_tables ()
potrebbe essere chiamato quando un tavolo esiste già, non è una svista - e di nuovo, copriremo il perché più avanti nella serie.
Dentro quella funzione, includiamo wp-admin / include / upgrade.php per impostare alcune costanti e caricare la funzione dbDelta ()
. Nota che quando un plugin è attivato manca il dentro
gancio, quindi wptuts_register_activity_log_table ()
deve essere chiamato manualmente.
require_once (ABSPATH. 'wp-admin / includes / upgrade.php'); globale $ wpdb; globale $ charset_collate; // Chiama questo manualmente perché potrebbe esserci perso il hook init wptuts_register_activity_log_table ();
Il globale $ charset_collate
contiene il set di caratteri e le regole di confronto utilizzate dalle tabelle native di WordPress. In modo approssimativo, questi definiscono le codifiche dei personaggi e il modo in cui vengono confrontati - dato che WordPress è usato in molti linguaggi diversi è importante usare le regole di confronto corrette per il tuo tavolo.
Oltre alle regole di confronto, l'istruzione SQL dovrebbe dichiarare il nome della tabella, insieme a ciascuna colonna, il suo tipo e il valore predefinito e qualsiasi CHIAVE
colonne, tra cui a CHIAVE PRIMARIA
colonna. In genere sarà della forma:
CREATE TABLE [nome tabella] ([colonna chiave primaria] bigint (20) non firmato NOT NULL auto_increment, [nome colonna] [tipo dati] [predefinito], PRIMARY KEY ([nome colonna]), KEY nome_chiave ([nome colonna]) ) [collation];
Per creare questo tavolo aggiungiamo il seguente al nostro wptuts_create_tables ()
funzione:
$ sql_create_table = "CREATE TABLE $ wpdb-> wptuts_activity_log (log_id bigint (20) non firmato NOT NULL auto_increment, user_id bigint (20) non firmato NOT NULL predefinito '0', attività varchar (20) NOT NULL predefinito 'aggiornato', object_id bigint (20) unsigned NOT NULL predefinito '0', object_type varchar (20) NOT NULL predefinito 'post', activity_date datetime NOT NULL predefinito '0000-00-00 00:00:00', PRIMARY KEY (log_id), KEY id_utente (user_id)) $ charset_collate; "; dbDelta ($ sql_create_table);
Il dbDelta ()
la funzione esegue il nostro CREA TABELLA
comando. Può essere piuttosto severo riguardo alla dichiarazione SQL assegnatagli. Per esempio, lì dovere due spazi tra CHIAVE PRIMARIA
e la colonna chiave primaria. e le chiavi devono avere un nome.
Se durante l'attivazione trovi che ottieni il 'Hai un carattere X di output inatteso ... 'messaggio di errore - è probabile che ci sia un errore nella tua istruzione SQL. A volte è dovuto a dbDelta ()
La rigidità Se aggiungi wp_die ();
dopo dbDelta ()
, questo uccide l'elaborazione e (con 'WP_DEBUG' impostato su true) rivelerà eventuali messaggi di errore.
In questo articolo abbiamo esaminato le ragioni per le quali dovresti e non dovresti usare le tabelle personalizzate, i dettagli che dovrai considerare e infine come creare una tabella. La parte successiva di questa serie riguarderà la sanificazione, esaminando l'iniezione SQL e il modo in cui proteggersi da esso. Il codice in questo articolo è disponibile in questo repository GitHub e verrà aggiornato man mano che la serie continua.
$ wpdb
classe