Usando namespaces: Fundamentos
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Antes de discutir o uso de namespaces, é importante entender como o PHP
sabe qual elemento de namespace seu código está solicitando. Uma analogia simples pode ser feita
entre os namespaces do PHP e um sistema de arquivos. Existem três maneiras de acessar um arquivo em um
sistema de arquivos:
-
Nome de arquivo relativo como
foo.txt. Será resolvido para
diretorioatual/foo.txt onde diretorioatual é o
diretório ocupado atualmente. Então, se o diretório atual for
/home/foo, o nome será resolvido para /home/foo/foo.txt.
-
Nome de caminho relativo como
subdiretorio/foo.txt. Será resolvido
para diretorioatual/subdiretorio/foo.txt.
-
Nome de caminho absoluto como
/main/foo.txt. Será resolvido
para /main/foo.txt.
O mesmo princípio pode ser aplicado a elementos com namespace no PHP. Por
exemplo, um nome de classe pode ser referenciado de três maneiras:
-
Nome não qualificado ou nome de classe sem prefixo como
$a = new foo(); ou
foo::metodoestatico();. Se o namespace atual for
namespaceatual, ele será resolvido para
namespaceatual\foo. Se
o código for global, sem namespace, ele será resolvido para foo.
Uma ressalva: nomes não qualificados para funções e constantes
serão resolvidos para funções e constantes globais se a função ou constante com namespace
não for definida. Veja Usando namespaces:
recorrendo a funções/constantes globais para obter detalhes.
-
Nome qualificado ou um nome de classe prefixado como
$a = new subnamespace\foo(); ou
subnamespace\foo::metodoestatico();. Se o namespace atual for
namespaceatual, ele será resolvido para
namespaceatual\subnamespace\foo. Se
o código for global, sem namespace, ele será resolvido para subnamespace\foo.
-
Nome totalmente qualificado ou um nome prefixado com um operador de prefixo global como
$a = new \namespaceatual\foo(); ou
\namespaceatual\foo::metodoestatico();. Ele sempre será resolvido
para o nome literal especificado no código, namespaceatual\foo.
Aqui está um exemplo dos três tipos de sintaxe em código real:
Note que para acessar qualquer classe,
função ou constante global, um nome totalmente qualificado pode ser usado, como
\strlen() ou \Exception ou
\INI_ALL.
Exemplo #1 Acessando classes, funções e constantes globais em um namespace
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
print \strlen('olá') . "\n"; // chama a função global strlen
print \INI_ALL . "\n"; // acessa a constante global INI_ALL
$c = new \Exception('erro'); // instancia um objeto da classe global Exception
print $c::class . "\n";
richard at richard-sumilang dot com ¶18 years ago
Syntax for extending classes in namespaces is still the same.
Lets call this Object.php:
<?php
namespace com\rsumilang\common;
class Object{
}
?>
And now lets create a class called String that extends object in String.php:
<?php
class String extends com\rsumilang\common\Object{
}
?>
Now if you class String was defined in the same namespace as Object then you don't have to specify a full namespace path:
<?php
namespace com\rsumilang\common;
class String extends Object
{
}
?>
Lastly, you can also alias a namespace name to use a shorter name for the class you are extending incase your class is in seperate namespace:
<?php
namespace com\rsumilang\util;
use com\rsumlang\common as Common;
class String extends Common\Object
{
}
?>
- Richard Sumilang
Anonymous ¶11 years ago
<?php
namespace Foo;
try {
}
catch (Exception as $ex) {
}
?>
Instead use fully qualified name for the exception to catch it
<?php
namespace Foo;
try {
}
catch (\Exception as $ex) {
}
?>
Lukas Z ¶14 years ago
Well variables inside namespaces do not override others since variables are never affected by namespace but always global:
"Although any valid PHP code can be contained within a namespace, only four types of code are affected by namespaces: classes, interfaces, functions and constants. "
Source: "Defining Namespaces"
http://www.php.net/manual/en/language.namespaces.definition.php
tom at tomwardrop dot com ¶14 years ago
It seems the file system analogy only goes so far. One thing that's missing that would be very useful is relative navigation up the namespace chain, e.g.
<?php
namespace MyProject {
class Person {}
}
namespace MyProject\People {
class Adult extends ..\Person {}
}
?>
That would be really nice, especially if you had really deep namespaces. It would save you having to type out the full namespace just to reference a resource one level up.
philip dot preisser at arcor dot de ¶15 years ago
Working with variables can overwrite equal variables in other namespaces
<?php namespace
main
{}
namespace
main\sub1
{
$data = 1;
}
namespace
main\sub2
{
echo $data;$data = 2;
}
namespace
main\sub1
{
echo $data;$data = 1;
}
namespace
{
echo $data;}
?>