Namespace in PHP

12 agosto 2016

Dichiarazione del namespace

Fino ad ora abbiamo analizzato la creazione di singole classi in PHP tenendo in considerazione solo due caratteristiche:

  • il nome della classe;
  • il file in cui veniva dichiarata la classe.

Questo è stato lo standard fino all’introduzione di PHP 5.3.0 che ha rivoluzionato il linguaggio introducendo il concetto di namespace. Tale paradigma non è nuovo nella programmazione ad oggetti ed è presente in molti dei linguaggi (ad esempio Java). In sostanza si tratta di creare un proprio spazio tramite una dichiarazione arbitraria in cui faremo risiedere le nostre classi.

La definizione viene effettuata tramite la parola chiave namespace che deve essere inserita prima di ogni altra istruzione e quindi deve precedere la dichiarazione della classe:

<?php

namespace Acme;

class MyClass
{
    // Corpo della classe
}

Concettualmente un namespace è assimilabile alla struttura delle cartelle di un filesystem: dobbiamo dichiarare un’origine per il nostro namespace che corrisponde alla directory root, o al nome del disco su sistemi Windows, e possiamo inserire in maniera sequenziale una serie di suddivisioni che in questa similitudine rappresenterebbero le sottocartelle.

Questa caratteristica dei namespace offre due vantaggi rilevanti:

  • possiamo organizzare il codice in modo da facilitare la mantenibilità, ad esempio tramite lo standard PSR-4;
  • non dobbiamo preoccuparci dei problemi relativi alle omonimie tra classi, ad esempio una classe con un nome molto comune come Connection non sarà più un problema.

Richiamare una classe interna ad un namespace

Una volta dichiarata una classe all’interno di un namespace è possibile richiamarla utilizzando il suo nome completo nel punto in cui la utilizziamo oppure il solo nome della classe se questa viene dichiarata, dopo la parola chiave namespace, tramite la keyword use. Entrambi i metodi sono validi ma il secondo ci permette di utilizzare due classi con lo stesso nome tramite gli alias. Per chiarire il concetto ecco un esempio:

<php
namespace Acme\Database\Connection;

use Acme\Database\Connection\Connection;
use Acme\Database\Connection2\Connection as ConnectionTwo;

class MySQL
{
    // Corpo della classe

    public function getConnection()
    {
        return new Connection(); // Restituisce un'istanza della classe Acme\Database\Connection\Connection
    }

    public function getConnection2()
    {
        return new ConnectionTwo(); // Restituisce un'istanza della classe Acme\Database\Connection2\Connection
    }

    public function getConnection3()
    {
        return new Acme\Database\Connection3\Connection();  // Restituisce un'istanza della classe Acme\Database\Connection3\Connection
    }
}

Le classi utilizzate devono essere state precedentemente caricate in memoria tramite i relativi comandi PHP (include, include_once, require, require_once) oppure possiamo semplificare la procedura ricorrendo ad un autoloader come quello generato automaticamente da Composer.

Usare classi senza namespace

Nonostante i namespace siano stati introdotti da diversi anni in PHP, alcune librerie anche se ad oggetti non fanno ricorso ai namespace. Esempi di questo tipo con una diffusione notevole sono Twig (libreria per il templating), SwiftMailer (per inviare messaggi email) o PHPExcel (per leggere e creare fogli di lavoro del popolare software).

Utilizzare direttamente queste librerie in un file in cui viene dichiarato un namespace (ad esempio quello del listato precedente) non è possibile perché l’interprete PHP si aspetta di trovare una classe priva del namespace completo sotto il namespace dichiarato all’inizio del file o, in alternativa, tra le classi importate tramite use. In questo caso infatti si riceverebbe un errore perché la classe non è stata precedentemente importata. Esistono due metodi per aggirare questo impedimento:

  • far precedere in tutto il codice il nome della classe da un carattere di backslash;
  • inserire la classe tra quelle dichiarate per l’utilizzo sempre preceduta da un carattere di backslash.

La seconda versione è più semplice perché permette anche di copiare parti di codice non pensate per la programmazione ad oggetti con namespace, ma non esiste una differenza tra le due:

<php
namespace Acme;

use \Exception;

class Utils
{
    // Corpo della classe

    public function doSomething()
    {
        try {
            // fa qualcosa
        } catch (RangeException $e) {
            // Errore -> non esiste la classe Acme\RangeException
        } catch (\DomainException $e) {
            // OK -> gestione delle eccezioni standard PHP di tipo DomainException
        } catch (Exception $e) {
            // OK -> gestione delle eccezioni standard PHP di tipo Exception
            //       perché dichiarata tra le classi da usare
        }
    }
}

Questa modalità deve essere usata anche per le classi stardard PHP. Non è invece necessaria per richiamare funzioni o costanti globali (dichiarate al di fuori di un namespace) come quelle standard del linguaggio.

Tutte le lezioni

1 ... 6 7 8 ... 50

Se vuoi aggiornamenti su Namespace in PHP inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su Namespace in PHP

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento dei dati per attività di marketing