Quando si parla di OOP (Object Oriented Programming) gli sviluppatori di WordPress spesso hanno problemi a comprendere le sostanziali differenze esistenti tra il tradizionale approccio procedurale e quello OOP. Questo articolo vuole essere una semplice introduzione all'OOP in WordPress.
L'approccio procedurale
Nell'approccio procedurale noi usiamo funzioni per svolgere determinati compiti. Le funzioni possono essere definite sia nel file functions.php
o richiamate in questo file tramite il costrutto require_once()
dopo essere state definite in file separati:
require_once(TEMPLATEPATH . '/framework/posts.php');
require_once(TEMPLATEPATH . '/framework/shortcodes.php');
oppure direttamente in functions.php
:
add_filter('widget_text', 'do_shortcode'); // abilito gli shortcode nei widget della sidebar
function display_sidebar_post($attrs) {
extract( shortcode_atts( array(
'id' => ''
), $attrs ) );
$permalink = get_permalink($id);
$excerpt = get_the_excerpt($id);
$thumb = get_the_post_thumbnail($id, 'thumb');
$title = get_the_title($id);
$html = '<h3>' . $title . '</h3>';
$html .= '<div class="sidebar-featured-image">' . $thumb . '</div>';
$html .= '<p>' . $excerpt . '</p>';
$html .= '<p><a href="' . $permalink . '" class="more-link">Leggi tutto</a></p>';
return $html;
}
add_shortcode('sidebar-post', 'display_sidebar_post');
Il problema di questo approccio è che il codice diventa sempre più difficile da gestire man mano che si aggiungono funzioni e si definiscono procedure. Tutto il codice vive in un namespace globale senza alcun tipo di incapsulamento. Se ad esempio volessimo definire una funzione di utility che deve operare solo in un determinato contesto, questa sarebbe comunque accessibile nel contesto globale.
L'approccio OOP risolve questi problemi.
Classi e oggetti
Una classe non è altro che il modello per un oggetto. Quando si utilizza l'operatore new
non si fa altro che creare una rappresentazione concreta di questo modello, ossia una sua istanza.
Ad esempio:
class MyClass {
public $property; // proprietà
public function __construct($prop) {
// definisce il valore della proprietà quando si usa new
$this->property = $prop;
}
public function method() {
echo $this->property;
}
}
$myClass = new MyClass('Test'); // ora MyClass::property = 'Test'
$myClass->method(); // visualizza 'Test'
PHP ci permette di definire vari livelli di visibilità per i membri di una classe. Nel nostro caso la parola chiave public
indica che sia il metodo che la proprietà definite nella classe sono accessibili anche al di fuori della stessa. Ad esempio:
echo $myClass->property; // 'Test'
Se invece avessimo avuto private
(accessibile solo all'interno della classe e non dalle sottoclassi) o protected
(accessibile solo all'interno della classe e anche dalle sottoclassi) avremmo visualizzato un errore PHP nel codice precedente perché il livello di visibilità non consentiva di accedere a property
in modo pubblico, ossia dall'esterno.
Sicuramente avrete intuito, conoscendo JavaScript, il significato della variabile speciale $this
: si tratta del riferimento interno alla classe corrente. Avrete anche notato che la proprietà property
viene inizialmente scritta come una variabile e in seguito referenziata senza il simbolo del dollaro.
Per le proprietà e i metodi di tipo private
o protected
si usa il prefisso _
prima del nome, quindi property
sarebbe diventata _property
e sarebbe stata definita come private $_property;
.
Usare le classi in WordPress
Tornando all'esempio iniziale, possiamo definire una classe chiamata ThemeShortcodes
e creare quindi un file PHP con lo stesso nome. Si noti come nel caso dei nomi delle classi si metta in maiuscolo l'iniziale di ciascuna parola.
Quindi in functions.php
la richiameremo in questo modo:
require_once(TEMPLATEPATH . '/framework/ThemeShortcodes.php');
A questo punto possiamo scrivere:
class ThemeShortcodes {
public function __construct() {
add_filter('widget_text', 'do_shortcode');
add_shortcode('sidebar-post', array($this, 'displaySidebarPost'));
}
public function displaySidebarPost($attrs) {
extract( shortcode_atts( array(
'id' => ''
), $attrs ) );
$permalink = get_permalink($id);
$excerpt = get_the_excerpt($id);
$thumb = get_the_post_thumbnail($id, 'thumb');
$title = get_the_title($id);
$html = '<h3>' . $title . '</h3>';
$html .= '<div class="sidebar-featured-image">' . $thumb . '</div>';
$html .= '<p>' . $excerpt . '</p>';
$html .= '<p><a href="' . $permalink . '" class="more-link">Leggi tutto</a></p>';
return $html;
}
}
$themeShortcodes = new ThemeShortcodes();
All'interno del metodo costruttore della classe abbiamo richiamato le funzioni di WordPress necessarie al nostro scopo. Da notare come le funzioni add_shortcode()
, add_filter()
e add_action()
accettino la seguente sintassi alternativa:
add_funzione('nome', array($this, 'nomeMetodoDellaClasse'));
$this
si riferisce alla classe corrente e nomeMetodoDellaClasse
al metodo da usare. add_filter()
supporta anche una sintassi alternativa:
add_filter('filtro', array('nomeDellaClasse', 'nomeMetodoDellaClasse'));
Nel nostro caso specifico per lanciare il codice dobbiamo solo istanziare la classe:
$themeShortcodes = new ThemeShortcodes();
In questo modo il nostro codice risulta molto più semplice da gestire perché tutta la logica viene incapsulata all'interno delle classi.