I namespace permettono di creare insieme di classi , intefacce , funzioni e costanti per risolvere un determinato problema.
Concettualmente sono molto simili alle cartelle di un filesystem di windows e sono stati introdotti dalla versione 5.3

La definizione viene fatta tramite il richiamo del nome nel seguente modo

<?php
 
namespace Esempio;
 
class MyClass
{
 // Corpo della classe esempio
}

Servono per riutilizzare classi già esistenti. Si dividono in

  • Nomi non qualificati non hanno l’elemento separatore \ ad esempio MyClass
  • Nomi qualificati con il separatore progetto\MyClass
  • Nomi completamente Qualificati ad esempio progetto1\sottoprogetto\MyClass

che appunto ricorda molto il concetto di file in cartelle nel filesystem di Windows.

Non è ammessa una dichiarazione prima di loro ossia una codice del tipo

<html>
<?php
namespace progetto;
?>

Restituirà un messaggio di errore di statement.

Sarà invece possibile dichiarare

<?php
namespace progetto\sottoprogetto\Livello;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }

?>

In ogni file sarà però possibile dichiarare multipli namespace nel seguente modo

<?php
namespace progetto;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }

namespace secondoprogetto;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
?>

Con l’introduzione dei namespace sono stati introdutti anche

  • _NAMESPACE_ costante che contiene una stringa con il namespace corrente. nel caso di namespace globale assumerà valore di stringa vuota
  • namespace è una keyword che serve per dichiarare un namespace e accedere ai suoi elementi come con l’operatore self.

Vediamo un esempio per chiarire tutto

<?php

namespace Progetto;

echo '"', __NAMESPACE__, '"'; // mostrerà l'output di "Progetto"
?>

nel caso invece di codice globale avremo

<?php

echo '"', __NAMESPACE__, '"'; //e in output avremo la stringa vuota.
?>

Dalla versione 5.6 inoltre il php permette anche nel caso di namespace l’aliasing

Definizione aliasing indica la situazione in cui una stessa posizione di memoria è associata a nomi simbolici diversi all’interno di un programma. Come nel caso dei puntatori.

Ad esempio

<?php
namespace foo;
use My\Full\Classname as Another;

// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;

// importing a global class
use ArrayObject;

// importing a function (PHP 5.6+)
use function My\Full\functionName;

// aliasing a function (PHP 5.6+)
use function My\Full\functionName as func;

// importing a constant (PHP 5.6+)
use const My\Full\CONSTANT;

$obj = new namespace\Another; // instantiates object of class foo\Another
$obj = new Another; // instantiates object of class My\Full\Classname
NSname\subns\func(); // calls function My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject
// without the "use ArrayObject" we would instantiate an object of class foo\ArrayObject
func(); // calls function My\Full\functionName
echo CONSTANT; // echoes the value of My\Full\CONSTANT
?>


in questo caso si utilizza l'operatore use ..... as ...;

Se non viene definita la parola chiave namespace le funzioni saranno definite nello spazio globale e quindi ne dobbiamo fare ricorso come nel seguente esempio

Senza alcuna definizione di namespace, tutte le definizioni di classi e funzioni sono collocate nello spazio globale, come in PHP prima che fossero supportati gli spazi dei nomi. Prefixing un nome con \ specificherà che il nome è richiesto dallo spazio globale anche nel contesto dello spazio dei nomi.

Utilizzo Namespace e  spazio globale

 

I Namespace in PHP definizione e Esempi

<?php
namespace A\B\C;

/* Questa funzione si trova in A\B\C\fopen */
function fopen() { 
 /* ... */
 $f = \fopen(...); // chiamata globale alla funzione fopen
 return $f;
} 
?>

L’inclusione di file con questo meccanismo è realmente molto immediato vi basterò fare

<?php 
//test.php 
namespace test { 
 include 'test1.inc'; 
 echo '-',__NAMESPACE__,'-<br />'; 
} 
?>

<?php 
//test1.inc 
 echo '-',__NAMESPACE__,'-<br />'; 
?>

Risultato del testo.php

-- 
-testo-

Vediamo un altro esempio per meglio comprendere consideriamo la funzione

<?php
namespace A\B\C;

const E_ERROR = 4;
function strlen($str)
{
 return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // stampa il valore "4"


echo strlen('hi'), "\n"; // stampa il valore "1"
if (is_array('hi')) { // stampa il valore non è un array
 echo "è un array\n";
} else {
 echo "non è un array\n";
}
?>


Facciamo un esempio conclusivo per comprendere la risoluzione dei nomi namespace
<?php
namespace A;
use B\D, C\E as F;

// function calls

foo(); // prima cerca di chiamare "foo" definito nello spazio dei nomi "A"
            // quindi chiama la funzione globale "foo"

\foo(); // chiama la funzione "foo" definita nell'ambito globale

my\foo(); // chima la funzione "foo" definita nel namespace "A\my"

// class references

new B(); // crea l'ggetto classe "B" definito nel namespace globale "A"
 //altrimenti lo cerca in "A\B"

new D(); // crea l'oggetto classe "D" definito nel namespace "B" altrimenti controlla in B\D

new F(); // Crea l'oggetto in classe "E" definito nel namespace "C" altrimenti prova a caricarlo in "C\E"

new \D(); // Crea l'oggetto "D" definito in classe globale
 // if not found, it tries to autoload class "D"


B\foo(); // chiama la funzione "foo" dal namespace "A\B"

B::foo(); // chiama il metodo "foo" di classe "B" definito in classe "A" altrimenti cerca di caricarlo in classe "A\B"


\A\B::foo(); // chiama il metodo "foo" di classe "B" dal namespace "A" altrimenti prova a caricarlo dalla classe "A\B"
?>


A questo punto possiamo vedere un esempio totale per comprenderne il funzionamento
<?php
namespace cartella\nome;

class MiaClasse {}
function miafunzione() {}
const MYCONST = 1;

$a = new MiaClasse;
$c = new \cartella\nome\MiaClasse;

$a = strlen('hi');

$d = namespace\MYCONST; 
$d = __NAMESPACE__ . '\MYCONST';
echo constant($d); 
?>