I namespace in PHP sono un modo con cui raggruppare logicamente le classi appartenenti ad uno stesso modulo o applicazione. Si dichiara un namespace all’inizio di un file PHP come:
namespace PHPEcommerce;
PHP esegue una correlazione tra il nome dichiarato ed una directory fisicamente esistente nell’applicazione. Chi inizia a lavorare con i namespace in PHP di solito pensa che sia sufficiente inserire i file delle classi nella directory del namespace e quindi usare la parola chiave use
per richiamare le classi al momento opportuno:
namespace PHPEcommerce;
use PHPEcommerce\Database as Database;
use PHPEcommerce\Vat as Vat;
PHP usa il backslash per i percorsi all’interno dei namespace. La parola chiave as
serve all’occorrenza a creare un alias per una data classe. Il codice si legge come: “Seleziona la classe X dentro il namespace PHPEcommerce e crea il riferimento chiamato Y a questa classe”.
PHP quindi cercherà la classe nella directory selezionata ma, attenzione, non lo farà automaticamente!
Infatti i namespace non eliminano l’autoloading delle classi necessario per includere una classe. Quindi nella nostra applicazione dobbiamo sempre includere un file come il seguente:
define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
spl_autoload_register(function($className) {
$className = str_replace('\\', DIRECTORY_SEPARATOR, $className);
$path = (strpos($className, 'PHPEcommerce') !== false) ? ABSPATH . 'core/classes/' . $className . '.php' : ABSPATH . 'core/classes/PHPEcommerce/' . $className . '.php';
require_once($path);
});
Dobbiamo rimuovere il backslash aggiunto dal namespace PHP e gestire l’eventuale presenza della stringa con il nome dello stesso namespace nei percorsi. Come si può notare, la creazione di un namespace in PHP determina un cambiamento radicale nel modo di includere le classi nel processo di autoloading. Quindi nel file index.php
avremo:
namespace PHPEcommerce;
require_once(__DIR__ . '/core/config.php');
require_once(__DIR__ . '/core/autoload.php');
$shop = new Shop();
$app = new Dispatcher($shop);
$app->handle();
E se volessimo usare una libreria di utility di terze parti che logicamente non appartiene al nostro namespace e che fisicamente risiede in una directory diversa? In questo caso dobbiamo informare PHP che vogliamo usare una classe che appartiene al namespace globale (o root), ossia \
:
require_once ABSPATH . 'core/lib/htmlpurifier/library/HTMLPurifier.auto.php';
$config = \HTMLPurifier_Config::createDefault();
$purifier = new \HTMLPurifier($config);
$clean_html = $purifier->purify($value);
In questo modo l'interprete PHP capirà che la classe non si trova nel namespace PHPEcommerce
ma nel namespace globale rappresentato dal token \
preposto al nome della classe.
Conclusione
In questo capitolo abbiamo affrontato alcuni dettagli interessanti dei namespace PHP in relazione al pattern MVC usato dal nostro e-commerce. Nei prossimi capitoli vedremo le varie fasi del processo di acquisto.