Nel corso della vita della tua tabella personalizzata, probabilmente troverai la necessità di apportare modifiche a ciò che memorizza o in che modo lo memorizza. Questo potrebbe essere in risposta alla necessità di memorizzare più (o meno) dati. Potrebbe essere che il progetto iniziale del tuo database non fosse inteso per trattare (in modo efficiente) con ciò che la tua base di utenti richiede ora. In ogni caso, dobbiamo sapere come adattare il nostro tavolo per soddisfare i nostri nuovi bisogni. Questo è ciò che vedremo in questo tutorial e ci concentreremo principalmente sulla funzione dbDelta ()
che ci siamo incontrati per la prima volta nella prima parte.
Fortunatamente la maggior parte dei legwork nella gestione delle modifiche al database viene eseguita dalla funzione WordPress dbDelta ()
. Abbiamo usato questa funzione nella prima parte per creare la nostra tabella, ma in realtà fa molto di più: prima di eseguire la query che abbiamo dato, controlla se la tabella esiste già. In caso contrario, crea la tabella, ma se esiste, confronta la differenza (da cui il nome) e la marca alcuni i cambiamenti. Questo è il motivo per cui nella prima parte non abbiamo verificato manualmente se la tabella esistesse già.
Se la tabella esiste già, ma è diversa dalla tabella fornita dall'SQL (ad esempio, la tabella esistente ha una colonna mancante o una colonna diversa), quindi dbDelta ()
applica automaticamente questi aggiornamenti. In questo modo possiamo rilasciare una nuova versione del nostro plug-in che altera la nostra tabella semplicemente applicando 'dbDelta ()' con l'SQL modificato. Quasi.
Sfortunatamente, dbDelta ()
non si applica tutti i cambiamenti. Supponiamo che nella nostra ultima versione del plug-in non abbiamo bisogno di una colonna e vogliamo rimuoverla. Quindi lo rimuoviamo dalla query SQL nella prima parte e nella chiamata di routine di aggiornamento wptuts_create_tables ()
. Dopo l'aggiornamento scopriremo che la colonna è ancora lì. Peggio ancora: gli utenti che passano dalla versione precedente alla nuova versione avranno quindi una tabella strutturalmente diversa da quelli che iniziano con la nuova versione.
Nota: dbDelta ()
è non distruttivo: questo aggiungerà colonne mancanti o cambierà le colonne modificate, ma non rimuoverà colonne o indici.
Quindi cosa fa dbDelta ()
davvero?
Ricordiamoci della query SQL a cui passiamo dbDelta ()
quando si crea la tabella:
$ 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) non firmato 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 user_id (user_id)) $ charset_collate ; "; dbDelta ($ sql_create_table);
Prima estrae tutto il CREA TABELLA
domande (tu può passare più query a dbDelta ()
contemporaneamente, separandoli con un ';
', ma per migliorare la leggibilità preferisco non farlo). Da questo prende il nome della tabella, $ tavolo
, e corre
$ wpdb-> get_results ("DESCRIBE $ table;");
Questo restituisce un array di colonne esistenti: ogni colonna è in realtà un oggetto contenente informazioni relative a tale colonna (nome, tipo, valore predefinito, ecc.). Per esempio il nostro log_id
la colonna ha il seguente aspetto:
stdClass Object ([Field] => log_id [Type] => bigint (20) unsigned [Null] => NO [Key] => PRI [Default] => [Extra] => auto_increment)
Se la tabella non esiste, viene restituito un array vuoto e viene creata la tabella. Altrimenti dbDelta ()
quindi passa attraverso ogni riga della query passata, estrae le colonne e le archivia in una matrice $ cfields
. Lo fa allo stesso modo con ciascuna delle chiavi (incluso primaria).
Quindi passa attraverso ciascuno dei esistente colonne. Se sono presenti nell'array sopra, $ cfields
, sono rimossi. Quindi confronta il loro tipo, se non corrispondono, genera automaticamente un corrispondente ALTER TABLE
query da eseguire in seguito. Dopo averlo fatto, rimasero solo le colonne $ cfields
sono quelli che non esistono già. Da questo genera ulteriormente ALTER TABLE
query per creare queste colonne.
Quindi esegue una procedura quasi identica per le chiavi.
La capacità di dbDelta ()
fare tutte queste analisi ha un costo: la sua pignoleria di ciò che accetterà (o interpreterà correttamente). Per esempio:
user_id bigint (20) unsigned NOT NULL default '0', activity varchar (20) NOT NULL default 'updated',
agirà come se il attività
la colonna non è presente. Il formato corretto è:
user_id bigint (20) unsigned NOT NULL default '0', activity varchar (20) NOT NULL default 'updated',
KEY (user_id)]
invece dovrebbe essere
KEY user_id (user_id)
(anche se il nome non deve essere lo stesso della colonna).
CHIAVE PRIMARIA
e la dichiarazione della colonna: (Log_id)
. Per esempio, CHIAVE PRIMARIA (log_id),
causerà un errore Il formato corretto è:
CHIAVE PRIMARIA (log_id),
Questa non è una lista completa, come regola generale dovresti evitare spazi extra intorno e tra parole chiave, come ad esempio CREARE
e TAVOLO
e non dovrebbero esserci spazi aggiuntivi attorno alle colonne. Gli interni di dbDelta ()
fare affidamento sull'uso preg_match ()
per estrarre informazioni dall'istruzione SQL passata - e in quanto tale le cose possono andare male abbastanza facilmente se tale istruzione non è adeguatamente formattata.
Alcuni di questi errori si verificano in silenzio (ad esempio se non si fornisce un CHIAVE
un nome, dbDelta ()
continuerà a duplicarlo). Per questo motivo è importante ispezionare manualmente la tabella (utilizzando phpMyAdmin o simile) per verificare che il codice funzioni correttamente.
Con dbDelta ()
, questo è molto semplice - supponiamo di voler fare object_id
un indice, aggiungi una colonna aggiuntiva user_ip
per memorizzare l'indirizzo IP dell'utente e modificare il tipo di colonna attività in varchar (30)
, semplicemente sostituiamo la query SQL originale con:
$ 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', user_ip varchar (15), attività varchar (30) 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), KEY object_id (object_id),) $ charset_collate; ";
Quindi ci assicuriamo di chiamare wptuts_create_tables ()
nella routine di aggiornamento e le modifiche avranno effetto.
Da dbDelta ()
non rimuoverà le colonne, la semplice rimozione della riga appropriata dalla query non sarà sufficiente (è comunque necessario). Invece dobbiamo fare le cose manualmente.
Per prima cosa, estrai una serie di colonne esistenti:
$ existing_columns = $ wpdb-> get_col ("DESC $ wpdb-> wptuts_activity_log", 0);
Quindi, se sono presenti le colonne che desideriamo rimuovere, possiamo rimuoverle con un ALTER TABLE
query:
$ remove_columns = array ('object_id'); // Matrice di colonne per rimuovere $ remove_columns = array_intersect ($ remove_columns, $ existing_columns); if (! empty ($ remove_columns)) $ wpdb-> query ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP COLUMN" .implode (', DROP COLUMN', $ remove_columns). ';');
Proprio come abbiamo fatto con le colonne, per prima cosa prendiamo una serie di indici:
$ existing_keys = $ wpdb-> get_col ("SHOW INDEX FROM $ wpdb-> wptuts_activity_log WHERE Key_name! = 'PRIMARY';", 2);
Quindi, se le chiavi che vogliamo rimuovere esistono, possiamo rimuoverle come sopra, ma ora usando DROP INDEX
$ remove_keys = array ('user_id'); // Array di chiavi per rimuovere $ remove_keys = array_intersect ($ remove_keys, $ existing_keys); if (! empty ($ remove_keys)) $ wpdb-> query ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP INDEX" .implode (', DROP INDEX', $ remove_keys). ';');
Ora che sappiamo come aggiornare il nostro database - vediamo come dovremmo gestirlo nel nostro plug-in. Conserveremo tutta la nostra gestione dell'upgrade all'interno della funzione: wptuts_activity_log_upgradecheck ()
. Si noti che il gancio di attivazione del plug-in funzionerà non essere attivato quando si aggiorna un plug-in: per garantire che la nostra routine di aggiornamento faccia il suo lavoro, ci collegheremo admin_init
.
Per verificare quali routine di aggiornamento dobbiamo eseguire, memorizzeremo la versione plug-in nel database. Confronteremo questa versione (la versione installata) con la versione corrente (attivata) del plug-in:
add_action ('admin_init', 'wptuts_activity_log_upgradecheck'); function wptuts_activity_log_upgradecheck () // Versione del plugin attualmente attivato $ current_version = '1.3'; // Versione del database: potrebbe essere necessario eseguire l'aggiornamento. $ installed_version = get_option ('wptuts_activity_log_version'); if (! $ installed_version) // Nessuna versione installata - assumeremo che sia stata appena installata add_option ('wptuts_activity_log_version', $ current_version); elseif ($ installed_version! = $ current_version) / * * Se si tratta di una versione precedente, eseguire alcuni aggiornamenti. * / // La versione installata è precedente alla 1.1 - l'aggiornamento alla versione 1.1 se (version_compare ('1.1', $ installed_version)) // Codice per l'aggiornamento alla versione 1.1 // La versione installata è precedente alla 1.3 - upgrade alla 1.3 if (version_compare ( '1.3', $ installed_version)) // Codice per l'aggiornamento alla versione 1.3 // Il database è ora aggiornato: aggiorna la versione installata all'ultima versione update_option ('wptuts_activity_log_version', $ current_version);
Nota: È importante che questa routine di aggiornamento sia presente nel iniziale rilascio in quanto aggiungerà la versione iniziale (1.0) al database. In caso contrario, potrebbero verificarsi problemi per gli aggiornamenti da 1.0 a 1.1.
Ciascuna delle singole routine di aggiornamento dovrebbe assicurare che il database sia 'aggiornato' utilizzando il codice discusso nelle sezioni precedenti. È importante sottolineare che, se apportiamo modifiche a SQL CREATE TABLE, è necessario ricordare di eseguire tale query dbDelta ()
(nel nostro esempio, chiamando wptuts_create_tables ()
come parte della routine di aggiornamento) affinché le modifiche abbiano effetto.
Fai attenzione a come gestisci gli aggiornamenti durante l'utilizzo dbDelta
. Ricorda che alcuni utenti potrebbero eseguire l'aggiornamento tra due o più aggiornamenti. Quindi, se tali modifiche non possono essere apportate in parallelo, è necessario eseguire l'aggiornamento in fasi, chiamando più volte "dbDelta ()", apportando le modifiche appropriate per tale fase.
Mentre ci siamo, guardiamo a ripulire noi stessi dopo aver disinstallato il plug-in. Queste sono in genere routine molto semplici: basta rimuovere la tabella del database, eventuali opzioni salvate e qualsiasi cron job che il plug-in potrebbe aver attivato. Colleghiamo la nostra routine al gancio di disinstallazione usando register uninstall hook ()
registrare disinstallazione hook (__ FILE __, 'wptuts_uninstall_plugin'); function wptuts_uninstall_plugin () global $ wpdb; // Rimuovi la nostra tabella (se esiste) $ wpdb-> query ("DROP TABLE IF EXISTS $ wpdb-> wptuts_activity_log"); // Rimuovi la versione del database delete_option ('wptuts_activity_log_version'); / * Rimuovi qualsiasi altra opzione installata dal plug-in e cancella tutti i lavori cron plug-in * /