Le persone si lamentano spesso che WordPress sia lento. Se questo è vero o no dipende da molti fattori, ma se possiamo vedere le risorse del server all'interno del dashboard di WordPress, allora può darci qualche informazione su come funziona bene l'installazione di WordPress.
In questo tutorial, creeremo un plug-in per mostrare lo stato del server incluso lo spazio su disco, i consumi di memoria, l'utilizzo della CPU e l'utilizzo del processo.
Impareremo anche a conoscere la cache di WordPress per evitare di interrogare queste metriche più e più volte e riguarderemo anche i lavori cron di WordPress per generare automaticamente questi dati.
Il dashboard dell'amministratore, di default, ci presenta un paio di blocchi chiamati widget. Questi includono:
I widget possono essere riordinati in base alle preferenze e possono essere visualizzati o nascosti. In generale, la dashboard è personalizzabile.
Poiché i widget sono molto flessibili e disponibili direttamente nella prima schermata dello schermo amministratore, possiamo utilizzarli per mostrare le risorse del server: stato del disco, utilizzo della RAM, utilizzo della CPU e informazioni sul sistema operativo. Chiameremo queste "metriche" di risorse in breve.
In questo modo impareremo l'API e i ruoli e le funzionalità di Dashboard Widget per rendere questi widget disponibili per alcuni utenti poiché i dati potrebbero essere sensibili.
Per fare ciò, impareremo anche alcuni comandi di base di Linux per estrarre le informazioni sul server e il seed sul dashboard dei widget. Useremo Transients API per memorizzare questi dati. Cronjobs sfrutterà automaticamente questi dati invece di ottenerli su richiesta ad ogni richiesta.
Il lavoro del nostro plugin è ispirato a Linux Dash.
Il nostro plugin supporta nove tipi di metriche. Di conseguenza, avremo nove widget dashboard.
Creiamo un semplice plugin e chiamalo Server Dashboard. Inizieremo con alcune cose basilari. Un tradizionale Ciao mondo ti aiuterà ad avere un assaggio di aggiungere un widget alla dashboard.
È facile, in realtà.
Creazione di una chiamata alla cartella Server Dashboard dentro wp-content / plugins
, e un file serverdashboard.php
. Il layout della cartella è simile a questo. Concentrati solo sul file principale e ignora il cestino, i test, i widget e così via.
Utilizzare questo codice per serverdashboard.php
correre(); ?>Ho usato namespace
AX \ StatBoard
per evitare la collisione dei nomi con diverse classi di plug-in, nomi di funzioni di temi e altri plug-in. correre
per registrare hook o filtro con WordPress.wp_dashboard_setup
. Questi hook ci concedono l'accesso all'opzione di personalizzazione relativa di Dashboard. Ci consente di aggiungere o rimuovere il widget di dashboard da WordPress. wp_add_dashboard_widget
per registrare un widget. Richiede argomenti in questo ordine:La maggior parte delle volte incontreremo i callback come una singola funzione, una funzione anonima, una matrice di oggetti e metodi, o un array di classi e metodi statici.Aggiorna la tua dashboard. Il nostro plugin mostra il suo widget. Notare il
id
dell'elemento div di widget.Facciamo avanzare questo. Mostreremo un grafico a torta con alcuni dati fittizi. Per semplificare le cose, utilizzerò l'API di Google Chart. Lo utilizzeremo estesamente in seguito per le metriche del server perché è meglio visualizzare questo tipo di dati.
Se non ti piace Google Chart, puoi sbarazzartene e mettere la tua libreria di carte preferita. Ricorda che questo è un tutorial, quindi non limitarti: usa qualsiasi cosa tu stia usando!
Dobbiamo caricare lo script di Google Chart. Cambia il tuo correre()
metodo per registrare un altro gancio.
funzione pubblica run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset'));
admin_enqueue_scripts
è l'azione necessaria per aggiungere il tuo script nel dashboard dell'amministratore. Aggiungeremo un'altra chiamata al metodo add_asset
nella nostra classe per gestire il caricamento degli script. L'attrezzo di add_asset
.
/ ** * Aggiungi javascript * / function add_asset () wp_enqueue_script ('google-chart', 'https://www.google.com/jsapi');Abbiamo la libreria di carte. Ora dobbiamo renderlo all'interno della nostra dashboard. Puoi giocare con Google Chart. Ora riutilizzeremo il loro esempio.
function add_dashboard_widgets () syslog (LOG_DEBUG, "Esegui"); wp_add_dashboard_widget ('hello_world_dashboard_widget', // A Slug per identificare questo widget 'Hello World', // Widget title function () echo <<<'EOD' Hey, I'm the body of widget. Thanks for bring me to the life.Semplicemente aggiungiamo un altro elemento div con id hello_piechart e renderizza il grafico in quell'elemento. Vediamo cosa abbiamo ora:Si noti l'ID dell'elemento widget.EOD; // funzione per rendere il contenuto del widget, sto usando una chiusura qui);
Ora che sappiamo come aggiungere il nostro blocco di widget alla dashboard, e ora che sappiamo come ottenere Google Chart per il rendering delle informazioni, possiamo combinarle per mostrare più informazioni.
Nella prossima sezione, impareremo come acquisire le metriche del server e renderizzare il contenuto per ogni tipo di metrica del server che abbiamo discusso in precedenza.
Quando estraiamo le metriche del server, useremo il comando di Linux per ottenere queste informazioni. In PHP, possiamo usare backtick "o shell_exec per invocare un comando shell e recuperare l'output.
Possiamo analizzare l'output per ottenere i dati del server. Ad esempio, per ottenere lo stato di utilizzo del disco, è possibile utilizzare il comando df -h
. Conosciamo il formato dell'output, quindi possiamo analizzarlo per ottenere ciò che vogliamo.
$ df = 'df -h'; $ df = explode ("\ n", $ df); if (is_array ($ df) && count ($ df)> = 2) array_shift ($ df); // Elimina la prima riga $ df = array_map (function ($ line) if (vuoto ($ line)) return NULL; $ segment = preg_split ('/ \ s + /', $ line); restituisce array ( 'filesystem' => $ segmento [0], 'dimensione' => $ segmento [1], 'usato' => $ segmento [2], 'disponibile' => $ segmento [3], 'use_percent' => $ segment [4],);, $ df); var_dump ($ df);
[command_we_run] | awk 'print $ 1, $ 3, ...'
. ☁ Server Dashboard [master] ls -lh totale 32 -rw-r - r-- 1 personale kureikain 2.6K Apr 11 00:46 Server Dashboard.php drwxr-xr-x 3 kureikain staff 102B Mar 29 01:27 bin - rw-r - r-- 1 kureikain staff 98B Apr 5 18:53 loader.js -rw-r - r-- 1 kureikain staff 321B 29 marzo 01:27 phpunit.xml drwxr-xr-x 4 kureikain staff 136B 29 marzo 01:27 test drwxr-xr-x 12 personale kureikain 408B Apr 13 17:37 widget -rw-r - r-- 1 personale kureikain 1.1K Apr 6 01:04 widget.php ☁ Server Dashboard [master] ls -lh | awk 'stampa $ 3, $ 4, $ 5, $ 9' personale kureikain 2.6K Server kureikain staff 102B bin kureikain staff 98B loader.js kureikain staff 321B phpunit.xml kureikain staff 136B prove kureikain staff 408B widget kureikain staff 1.1K widget.phpCome puoi vedere ogni riga di
ls -la
contiene nove campi:drwxr-xr-x 4 kureikain staff 136B 29 marzo 01:27 testSeparando per spazi, questi 9 campi sono:
awk 'print $ 3, $ 4, $ 5, $ 9'
e vedrò:test kureikain 136B
Pertanto, utilizzando awk possiamo pulire un po 'di più l'output prima di passare alla nostra funzione di elaborazione PHP.
Alcuni comandi generano dati extra di cui non abbiamo bisogno; quindi, richiede un po 'di sforzo in più con PHP per ripulirlo.
Per esempio:
[vagrant @ vagrant-centos64 ~] $ free -m totale usato buffer condivisi gratuiti memorizzati Mem: 589 537 51 0 8 271 - / + buffer / cache: 258 330 Swap: 255 0 255
libero -m
ci mostra l'utilizzo della RAM con file di memoria e di scambio; tuttavia include due altre linee con totale / usato / libero e - / + buffer / cache che potrebbe non essere necessario. -E
interruttore. Quell'interruttore consente di utilizzare l'espressione regolare normale per la ricerca. Perché vogliamo trovare la linea con le parole Mem e Swap, combinare con grep -E "Mem | Swap"
. [vagrant @ vagrant-centos64 ~] $ free -m | grep -E "Mem | Swap" Mem: 589 536 52 0 8 271 Swap: 255 0 255Quindi è molto più pulito. Combinare entrambi
grep
e awk
possiamo pulire i dati e ottenere solo ciò di cui abbiamo bisogno.[vagrant @ vagrant-centos64 ~] $ free -m | grep -E "Mem | Swap" | awk 'print $ 1, $ 2, $ 3, $ 4' Mem: 589 537 52 Swap: 255 0 255
Dobbiamo imparare alcuni comandi per ottenere le metriche del server, quindi apriamo la shell del nostro server e proviamo a digitare il comando sotto per avere un assaggio veloce.
$ netstat -in Tabella dell'interfaccia del kernel Iface MTU soddisfatto RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth0 1500 0 5538339494 0 0 0 6216082004 0 0 0 BMRU eth0: 1 1500 0 - nessuna statistica disponibile - BMRU eth1 1500 0 96707328840 0 0 0 102776317608 0 0 0 BMRU eth2 1500 0 33 0 0 0 7 0 0 0 BMRU lo 16436 0 29461422 0 0 0 29461422 0 0 0 LRU
df -h Dimensione del filesystem utilizzata Uso disponibile% montato su / dev / sda7 2.0G 660M 1.3G 35% / / dev / sda8 1.0T 632G 340G 66% / home / dev / sda6 2.0G 68M 1.9G 4% / tmp / dev / sda5 20G 1.5G 18G 8% / var / dev / sda2 20G 2.1G 17G 12% / usr / dev / sda1 194M 25M 160M 14% / avvio / dev / hdb1 459G 277G 159G 64% / backup tmpfs 16G 0 16G 0% / dev / shm
free -m totali utilizzati buffer condivisi gratuiti memorizzati Mem: 32189 32129 59 0 419 9052 - / + buffer / cache: 22656 9532 Swap: 32767 4 3276Useremo più comandi in seguito, ma quelli sopra ti daranno un comando fondamentale per vedere cosa possiamo ottenere dal server direttamente dalla riga di comando.
Riforterà un po 'la nostra classe originale nella sezione precedente. Tieni presente che, salvo indicazione contraria, creeremo tutti i file e le cartelle entro la nostra directory di plugin.
Innanzitutto, non vogliamo includere manualmente i file. Scriveremo un caricatore automatico di classe per questo scopo. Quando una classe mancante viene inizializzata, controlleremo il nome della classe e cercheremo di includere il file sorgente che contiene la definizione della classe.
Useremo gli spazi dei nomi come percorso e nome della classe come nome del file. Ad esempio, una classe foo
nello spazio dei nomi AX \ StatBoard
dovrebbe essere nella radice della cartella dei plugin. Una classe ronzio
nello spazio dei nomi AX \ StatBoard \ Bar
dovrebbe essere in Bar \ buzz.php
Con questo in mente, procediamo e iniziamo a creare il nostro metodo di caricamento automatico:
_plugin_dir. strtolower (str_replace ('\\', '/', $ classname). '.php'); if (! file_exists ($ filepath)) return false; include $ filepath;Quindi, cosa succede qui? Il nostro plugin usa lo spazio dei nomi
/ **
* Imposta la variabile e intialize provider di widget
* /
function __construct ()
$ this -> _ plugin_dir = plugin_dir_path (__FILE__);
spl_autoload_register (array ($ this, 'load_class'));
// ...
AX \ StatBoard
. Quindi ci assicuriamo che la classe richiesta sotto questo spazio dei nomi debba essere gestita dal nostro plugin, altrimenti il nostro caricatore automatico non è in grado di caricarli. Quindi spogliamo il AX \ StatBoard nel nome della classe e sostituirlo con il percorso della cartella dei plugin. Il backslash \ nel namespace viene sostituito con / separatore di percorso e append php
estensione. Ciò significa che lo spazio dei nomi verrà utilizzato poiché il percorso della cartella contiene il file di classe e il nome della classe è il nome del file. L'inclusione avviene solo se il file esiste. Ora, abbiamo il caricatore automatico, dobbiamo ancora far sapere a PHP che abbiamo un caricatore automatico e vogliamo usarlo. PHP include spl_autoload_register per questo scopo. Lo inseriamo nel nostro costruttore di classi.wp_add_dashboard_widget
, dobbiamo dargli il titolo e il contenuto. In corrispondenza di ciascun widget, avremo una classe per renderizzare titolo e contenuto per esso. Chiamiamo queste classi sono widget Provider
. Tutto il provider di widget deve definire get_title ()
e get_content ()
per rendere il contenuto.Provider
interfaccia e la nostra classe di provider di widget implementa questa interfaccia. Dobbiamo anche creare un'altra chiamata al metodo get_metric ()
per estrarre i dati del server.widget di / provider.php
con questo contenuto:Questa è un'interfaccia. Abbiamo richiesto che ogni provider di widget abbia implementato questa interfaccia, e quindi assicuriamo che la classe del fornitore di widget tat abbia sempre questi tre metodi.
Creeremo un'altra classewidget
per gestire questi fornitori. Creiamo classi di provider, quindi li distribuiamo awidget
classe e vistawidget
classe come un unico punto per noi di chiedere un fornitore quando abbiamo bisogno. Possiamo semplicemente mettere tutto nel nostro file di plugin principale e creare semplicemente un'istanza di classe connuovo
operatore quando abbiamo bisogno ma è difficile da mantenere in seguito.
Quando suddividiamo le cose in più livelli, è più facile testare ed estendere. Una volta che tutti i provider saranno gestiti da una singola classe, possiamo usare quella singola classe per fare la stessa cosa sul set di provider. Possiamo aggiungere facilmente più provider in qualsiasi momento, semplicemente creando un oggetto che implementa la classe di provider e li alimentawidget
classe
Componi un filewidget.php
nella directory principale della cartella dei plugin.Di nuovo, stiamo usando il Pattern Singleton per la nostra classe Widget. Un rapido riassunto del nostro metodo qui.
namespace AX \ StatBoard;
utilizzare AX \ StatBoard \ Widget \ Provider;
class Widget
const WIDGET_SLUG_PREFIX = 'AX';
protected $ _providers = array ();
$ static istanza protetta;
istanza della funzione statica ()
return self :: $ _ instance = self :: $ _ instance?: new self ();
function __construct ()
/ **
* Aggiungi un provider di widget
* Nome del widget stringa @param
* Oggetto provider @param per gestire il rendering del contenuto del widget
* /
funzione pubblica add_provider ($ name, Provider $ handler)
$ this -> _ providers [$ name] = $ handler;
restituire $ questo;
/ **
* Ottieni tutti i provider o un particolare provider
* /
funzione pubblica get_provider ($ name = NULL)
if (! $ name)
restituire $ this -> _ providers;
restituire $ this -> _ providers [$ name];
/ **
* Registra un widget per renderlo.
* /
registro delle funzioni pubbliche ($ name)
$ slugid = self :: WIDGET_SLUG_PREFIX. $ Name;
$ widget_provider = $ this-> get_provider ($ name);
if (vuoto ($ widget_provider))
restituisce falso;
wp_add_dashboard_widget (
$ slugid,
$ Widget_provider-> get_title (),
array ($ widget_provider, 'get_content'));
ritorna vero;
- Il
add_provider
il metodo aggiungerà un oggetto provider di widget all'elenco dei provider di widget. Usiamo anche il suggerimento del tipo per assicurarci che l'oggetto che passa a add_provider debba essere a Provider implementando il nostroProvider
interfaccia.- Il
get_provider
metodo può restituire un elenco di tutti i provider o di un particolare provider.- Il
Registrare
il metodo registrerà effettivamente il nostro oggetto provider con WordPress per il rendering di un widget dashboardwp_add_dashboard_widget
. L'ID del widget viene generato in base al prefisso, una costante pre definita e il nome della classe del widget. Il titolo sarà e il contenuto sarà tirato viaget_title
e get_content
del fornitore. Ci siamo assicurati che implementassero la nostra interfaccia Provider. Con questo metodo di registrazione, si astraggono l'implementazione dell'aggiunta del widget alla dashboard. Tutto quello che dobbiamo fare ora è chiamareRegistrare
con il nome del fornitore che aggiungiamo prima conadd_provider
. Con questo in mente, quando l'API di WordPress cambia, non è necessario andare in ogni posto diwp_add_dashboard_widget
, aggiorniamo solo in un posto.
Tornando il nostro file di plugin principale originaleserverdashboard.php
, inizializzeremo tutti i provider e li aggiungeremo all'elenco dei provider di oggetti Widget._plugin_dir = plugin_dir_path (__FILE__); spl_autoload_register (array ($ this, 'load_class')); $ this -> _ dashboard_widget = array ('server', 'cpu_load', 'ram', 'disk', 'diskio', 'software', 'ethernet', 'internetspeed', 'networkio', 'processo',); foreach ($ this -> _ dashboard_widget as $ item) if (! file_exists ($ this -> _ plugin_dir. '/ widget /'. $ item. '.php')) continua; $ classname = 'AX \ StatBoard \\ Widget \\'. ucwords ($ item); Widget :: instance () -> add_provider ($ item, new $ classname ());Metteremo tutte le classi dei provider di widget sotto namespaceAX \ StatBoard \ Widget
e quindi si siederanno nella cartellawidget di
. Supportiamo nove tipi di metrica e chiamiamo la classe corrispondente alla matrice_dashboard_widgets
sopra.
Per ciascun widget, creiamo una nuova istanza del suo provider e aggiungiamowidget
classe. Ecco cosa otterremo in seguito con questa struttura:
Ricorda che ci siamo agganciatiwp_dashboard_setup
, e al suo interno chiamiamo la funzionewp_add_dashboard_widget
per aggiungere un nuovo widget alla dashboard. Successivamente, abbiamo il nostroRegistrare
metodo per questo scopo. Effettueremo un ciclo su tutti i provider aggiunti e li registreremo. Aggiorna il contenuto diadd_dashboard_widgets
diserverdashboard.php
diventare:
/ ** * Registra il gestore del widget del dashboard per visualizzarlo sul dashboard * / function add_dashboard_widgets () $ widget = Widget :: instance (); foreach ($ widget-> get_provider () come $ name => $ provider) $ widget-> register ($ name);
Successivamente, collegheremo in admin_footer per generare JavaScript inline nella parte inferiore della pagina di amministrazione per l'inizializzazione del pacchetto di classi di Google Chart. Nostrocorrere()
il metodo viene aggiornato anche per il nuovo hook./ ** * Avvia l'installazione hook * / public function run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset')); add_action ('admin_footer', array ($ this, 'footer')); / ** * Inline JavaScript per chart * / function footer () echo ' ';
In questo momento, abbiamo completato la base e il file del plugin principale dovrebbe essere simile a questo._plugin_dir. strtolower (str_replace ('\\', '/', $ classname). '.php'); if (! file_exists ($ filepath)) return false; include $ filepath; / ** * Imposta la variabile e intialize il provider di widget * / function __construct () $ this -> _ plugin_dir = plugin_dir_path (__FILE__); spl_autoload_register (array ($ this, 'load_class')); $ this -> _ dashboard_widget = array ('server', 'cpuload', 'ram', 'disk', 'software', 'process', 'ethernet', 'networkio', 'iostat',); foreach ($ this -> _ dashboard_widget as $ item) if (! file_exists ($ this -> _ plugin_dir. '/ widget /'. $ item. '.php')) continua; $ classname = 'AX \ StatBoard \\ Widget \\'. ucwords ($ item); Widget :: instance () -> add_provider ($ item, new $ classname ()); / ** * Crea un'istanza univoca attraverso l'app * / public static function instance () return self :: $ _ instance = self :: $ _ instance?: New self (); / ** * Avvia all'installazione hook * / public function run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset')); add_action ('admin_footer', array ($ this, 'footer')); / ** * Registra il gestore del widget del dashboard per visualizzarlo sul dashboard * / function add_dashboard_widgets () $ widget = Widget :: instance (); foreach ($ widget-> get_provider () come $ name => $ provider) $ widget-> register ($ name); / ** * Asset load: stylesheet, JS. * / function add_asset () syslog (LOG_DEBUG, "Loaded"); wp_enqueue_script ('google-chart', 'https://www.google.com/jsapi'); // wp_enqueue_script ('plugin_dir_url', plugin_dir_url (__ FILE__). '/loader.js'); / ** * Inline JavaScript per chart * / function footer () echo ' '; Dashboard :: instance () -> run ();Fondamentalmente creiamo un'istanza della classe plugin principale e chiamiamo il metodo run. Che a sua volta ha appena creato un elenco di hook. Ogni hook è un altro metodo all'interno della classe. Creiamo e registriamo anche il nostro oggetto provider conwidget
oggetto.Qual'è il prossimo?
A questo punto, non abbiamo ancora visualizzato nulla; tuttavia, abbiamo predisposto una struttura per il nostro annuncio plug-in che ha iniziato a collegarsi a Google Charts.
Puoi scaricare lo script completo dai link di download nella parte superiore di questo articolo. Entreremo nel dettaglio dell'attrezzo di ciascun fornitore di widget nel prossimo articolo, quindi assicurati di seguire la parte successiva.
Spero che questo articolo ti sia piaciuto. Lascia dei commenti con uno qualsiasi dei tuoi pensieri e sarò sicuro di risponderli.