Files
archived-doc-pt-br/language/namespaces.xml
2025-08-27 14:12:36 -03:00

1566 lines
52 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 1651836ff309efd14a795eff44ee51455f66c7d3 Maintainer: leonardolara Status: ready --><!-- CREDITS: dcbmariano,lhsazevedo,ae,nawarian,adiel,leonardolara -->
<chapter xml:id="language.namespaces" xmlns="http://docbook.org/ns/docbook"
version="1.1">
<title>Namespaces</title>
<sect1 xml:id="language.namespaces.rationale">
<title>Visão geral de Namespaces</title>
<titleabbrev>Visão Geral</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<simpara>
O que são namespaces? Na definição mais ampla, os namespaces (na tradução literal, "espaços de nomes") são uma forma de encapsular
itens. Isso é visto como um conceito abstrato em muitos lugares. Por exemplo, em qualquer
sistema operacional, os diretórios servem para agrupar arquivos relacionados, e agem como um namespace para
os arquivos dentro deles. Como um exemplo concreto, o arquivo <literal>foo.txt</literal> pode
existir em ambos os diretórios <literal>/home/greg</literal> e <literal>/home/other</literal>,
mas duas cópias de <literal>foo.txt</literal> não podem coexistir em um mesmo diretório. Além
disso, para acessar o arquivo <literal>foo.txt</literal> fora do
diretório <literal>/home/greg</literal>, o nome do diretório deve ser prefixado ao nome
do arquivo usando o separador de diretórios para obter <literal>/home/greg/foo.txt</literal>. Esse
mesmo princípio se estende a namespaces no mundo da programação.
</simpara>
<simpara>
No mundo PHP, os namespaces são projetados para resolver dois problemas que os autores
de bibliotecas e aplicações encontram ao criar elementos de código reutilizáveis,
como classes ou funções:
</simpara>
<para>
<orderedlist>
<listitem>
<simpara>
Colisões de nomes entre o código criado e
classes/funções/constantes internas do PHP ou classes/funções/constantes de terceiros.
</simpara>
</listitem>
<listitem>
<simpara>
Capacidade de criar apelidos (ou encurtar) Nomes_Extralongos projetados para aliviar o primeiro problema,
melhorando a legibilidade do código-fonte.
</simpara>
</listitem>
</orderedlist>
</para>
<simpara>
Os Namespaces do PHP fornecem uma maneira de agrupar classes, interfaces,
funções e constantes relacionadas. Aqui está um exemplo da sintaxe de namespace em PHP:
</simpara>
<example>
<title>Exemplo da sintaxe de namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace meu\nome; // veja a seção "Definindo Namespaces"
class MinhaClasse {}
function minhafuncao() {}
const MINHACONST = 1;
$a = new MinhaClasse;
$c = new \meu\nome\MinhaClasse; // veja a seção "Espaço Global"
$a = strlen('oi'); // veja a seção "Usando namespaces: recorrendo a
// funções/constantes globais"
$d = namespace\MINHACONST; // veja a seção "operador de namespace
// e constante __NAMESPACE__"
$d = __NAMESPACE__ . '\MINHACONST';
echo constant($d); // veja a seção "Namespaces e recursos de linguagem dinâmica"
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Nomes de namespace não diferenciam maiúsculas de minúsculas.
</simpara>
</note>
<note>
<para>
O nome do namespace <literal>PHP</literal> e os nomes compostos que começam
com esse nome (como <literal>PHP\Classes</literal>) são reservados para uso interno da linguagem
e não devem ser usados no código criado pelo usuário.
</para>
</note>
</sect1>
<sect1 xml:id="language.namespaces.definition">
<title>Definindo namespaces</title>
<titleabbrev>Namespaces</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Embora qualquer código PHP válido possa estar contido em um namespace, apenas os seguintes
tipos de código são afetados por namespaces: classes (incluindo abstratas, traits e enumerações), interfaces,
funções e constantes.
</para>
<para>
Namespaces são declarados usando a palavra-chave <literal>namespace</literal>.
Um arquivo contendo um namespace deve declarar o namespace
no início do arquivo antes de qualquer outro código - com uma exceção: a
palavra-chave <xref linkend="control-structures.declare" />.
<example>
<title>Declarando um único namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto;
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Nomes totalmente qualificados (ou seja, nomes que começam com uma barra invertida) não são permitidos em declarações
de namespace, por serem construções interpretadas como expressões de namespace relativos.
</simpara>
</note>
A única construção de código permitida antes de uma declaração de namespace é a
declaração <literal>declare</literal>, para definir a codificação de um arquivo-fonte. Além disso,
nenhum código não-PHP pode preceder uma declaração de namespace, incluindo espaço em branco extra:
<example>
<title>Declarando um único namespace</title>
<programlisting role="php">
<![CDATA[
<html>
<?php
namespace MeuProjeto; // erro fatal - namespace precisa ser a primeira declaração no script
?>
]]>
</programlisting>
</example>
</para>
<para>
Além disso, ao contrário de qualquer outra construção do PHP, o mesmo namespace pode ser definido
em vários arquivos, permitindo a divisão do conteúdo de um namespace no sistema de arquivos.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nested">
<title>Declarando sub-namespaces</title>
<titleabbrev>Sub-namespaces</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Assim como diretórios e arquivos, os namespaces do PHP podem especificar
uma hierarquia de namespaces. Assim, um namespace pode ser definido com
subníveis.
<example>
<title>Declarando um único namespace com hierarquia</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto\Nivel\SubNivel;
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
?>
]]>
</programlisting>
</example>
O exemplo acima cria a constante <literal>MeuProjeto\Nivel\SubNivel\CONEXAO_OK</literal>,
a classe <literal>MeuProjeto\Nivel\SubNivel\Conexao</literal> e a função
<literal>MeuProjeto\Nivel\SubNivel\conectar</literal>.
</para>
</sect1>
<sect1 xml:id="language.namespaces.definitionmultiple">
<title>Definindo vários namespaces no mesmo arquivo</title>
<titleabbrev>Definindo vários namespaces no mesmo arquivo</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Vários namespaces também podem ser declarados no mesmo arquivo. Existem duas sintaxes
permitidas.
</para>
<para>
<example>
<title>Declarando vários namespaces, sintaxe de combinação simples</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto;
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
namespace OutroProjeto;
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
?>
]]>
</programlisting>
</example>
</para>
<para>
Essa sintaxe não é recomendada para combinar namespaces em um único arquivo.
Em vez disso, é recomendado usar a sintaxe alternativa de colchetes.
</para>
<para>
<example>
<title>Declarando vários namespaces, sintaxe de colchetes</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto {
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
}
namespace OutroProjeto {
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
}
?>
]]>
</programlisting>
</example>
</para>
<para>
É altamente desaconselhado como prática de programação combinar vários namespaces no
mesmo arquivo. O principal caso de uso é combinar vários scripts PHP no mesmo
arquivo.
</para>
<para>
Para combinar código global sem namespace com código com namespace, apenas a sintaxe de colchetes é
suportada. O código global deve ser
encapsulado em uma declaração de namespace sem nome de namespace, como em:
<example>
<title>Declarando vários namespaces e código sem namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto {
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
}
namespace { // código global
session_start();
$a = MeuProjeto\conectar();
echo MeuProjeto\Conexao::iniciar();
}
?>
]]>
</programlisting>
</example>
</para>
<para>
Nenhum código PHP pode existir fora dos colchetes do namespace, exceto uma declaração
declare de abertura.
<example>
<title>Declarando vários namespaces e código sem namespace</title>
<programlisting role="php">
<![CDATA[
<?php
declare(encoding='UTF-8');
namespace MeuProjeto {
const CONEXAO_OK = 1;
class Conexao { /* ... */ }
function conectar() { /* ... */ }
}
namespace { // código global
session_start();
$a = MeuProjeto\conectar();
echo MeuProjeto\Conexao::iniciar();
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.basics">
<title>Usando namespaces: Fundamentos</title>
<titleabbrev>Fundamentos</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
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:
<orderedlist>
<listitem>
<simpara>
Nome de arquivo relativo como <literal>foo.txt</literal>. Será resolvido para
<literal>diretorioatual/foo.txt</literal> onde <literal>diretorioatual</literal> é o
diretório ocupado atualmente. Então, se o diretório atual for
<literal>/home/foo</literal>, o nome será resolvido para <literal>/home/foo/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Nome de caminho relativo como <literal>subdiretorio/foo.txt</literal>. Será resolvido
para <literal>diretorioatual/subdiretorio/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Nome de caminho absoluto como <literal>/main/foo.txt</literal>. Será resolvido
para <literal>/main/foo.txt</literal>.
</simpara>
</listitem>
</orderedlist>
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:
<orderedlist>
<listitem>
<simpara>
Nome não qualificado ou nome de classe sem prefixo como
<literal>$a = new foo();</literal> ou
<literal>foo::metodoestatico();</literal>. Se o namespace atual for
<literal>namespaceatual</literal>, ele será resolvido para
<literal>namespaceatual\foo</literal>. Se
o código for global, sem namespace, ele será resolvido para <literal>foo</literal>.
</simpara>
<simpara>
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 <link linkend="language.namespaces.fallback">Usando namespaces:
recorrendo a funções/constantes globais</link> para obter detalhes.
</simpara>
</listitem>
<listitem>
<simpara>
Nome qualificado ou um nome de classe prefixado como
<literal>$a = new subnamespace\foo();</literal> ou
<literal>subnamespace\foo::metodoestatico();</literal>. Se o namespace atual for
<literal>namespaceatual</literal>, ele será resolvido para
<literal>namespaceatual\subnamespace\foo</literal>. Se
o código for global, sem namespace, ele será resolvido para <literal>subnamespace\foo</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Nome totalmente qualificado ou um nome prefixado com um operador de prefixo global como
<literal>$a = new \namespaceatual\foo();</literal> ou
<literal>\namespaceatual\foo::metodoestatico();</literal>. Ele sempre será resolvido
para o nome literal especificado no código, <literal>namespaceatual\foo</literal>.
</simpara>
</listitem>
</orderedlist>
</para>
<para>
Aqui está um exemplo dos três tipos de sintaxe em código real:
<informalexample>
<simpara>arquivo1.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo() {}
class foo
{
static function metodoestatico() {}
}
?>
]]>
</programlisting>
<simpara>arquivo2.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo\Bar;
include 'arquivo1.php';
const FOO = 2;
function foo() {}
class foo
{
static function metodoestatico() {}
}
/* Nome não qualificado */
foo(); // será resolvido para a função Foo\Bar\foo
foo::metodoestatico(); // será resolvido para a classe Foo\Bar\foo, método metodoestatico
echo FOO; // será resolvido para a constante Foo\Bar\FOO
/* Nome qualificado */
subnamespace\foo(); // será resolvido para a função Foo\Bar\subnamespace\foo
subnamespace\foo::metodoestatico(); // será resolvido para a classe Foo\Bar\subnamespace\foo,
// método metodoestatico
echo subnamespace\FOO; // será resolvido para a constante constant Foo\Bar\subnamespace\FOO
/* Nome totalmente qualificado */
\Foo\Bar\foo(); // será resolvido para a função Foo\Bar\foo
\Foo\Bar\foo::metodoestatico(); // será resolvido para a classe Foo\Bar\foo, método metodoestatico
echo \Foo\Bar\FOO; // será resolvido para a constante Foo\Bar\FOO
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Note que para acessar qualquer classe,
função ou constante global, um nome totalmente qualificado pode ser usado, como
<function>\strlen</function> ou <classname>\Exception</classname> ou
\<constant>INI_ALL</constant>.
<example>
<title>Acessando classes, funções e constantes globais em um namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('oi'); // chama a função global strlen
$b = \INI_ALL; // acessa a constante global INI_ALL
$c = new \Exception('erro'); // instancia um objeto da classe global Exception
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.dynamic">
<title>Namespaces e recursos de linguagem dinâmica</title>
<titleabbrev>Namespaces e recursos de linguagem dinâmica</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
A implementação de namespaces do PHP é influenciada por sua natureza dinâmica como linguagem
de programação. Assim, para converter código como o exemplo a seguir em código com namespace:
<example>
<title>Acessando elementos dinamicamente</title>
<simpara>exemplo1.php:</simpara>
<programlisting role="php">
<![CDATA[
<?php
class nomedaclasse
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function nomedafuncao()
{
echo __FUNCTION__,"\n";
}
const nomedaconstante = "global";
$a = 'nomedaclasse';
$obj = new $a; // imprime nomedaclasse::__construct
$b = 'nomedafuncao';
$b(); // imprime nomedafuncao
echo constant('nomedaconstante'), "\n"; // imprime global
?>
]]>
</programlisting>
</example>
Deve-se usar o nome totalmente qualificado (nome da classe prefixado com o namespace).
Observe que, como não há diferença entre um nome qualificado e um nome totalmente qualificado
em um nome de classe, nome de função ou nome de constante dinâmico, a barra invertida inicial não
é necessária.
<example>
<title>Acessando dinamicamente elementos com namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace nomedonamespace;
class nomedaclasse
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function nomedafuncao()
{
echo __FUNCTION__,"\n";
}
const nomedaconstante = "comnamespace";
/* note que, ao usar aspas duplas, "\\nomedonamespace\\nomedaclasse" deve ser usado */
$a = '\nomedonamespace\nomedaclasse';
$obj = new $a; // imprime nomedonamespace\nomedaclasse::__construct
$a = 'nomedonamespace\nomedaclasse';
$obj = new $a; // também imprime nomedonamespace\nomedaclasse::__construct
$b = 'nomedonamespace\nomedafuncao';
$b(); // imprime nomedonamespace\nomedafuncao
$b = '\nomedonamespace\nomedafuncao';
$b(); // também imprime nomedonamespace\nomedafuncao
echo constant('\nomedonamespace\nomedaconstante'), "\n"; // imprime comnamespace
echo constant('nomedonamespace\nomedaconstante'), "\n"; // também imprime comnamespace
?>
]]>
</programlisting>
</example>
</para>
<para>
Certifique-se de ler a <link linkend="language.namespaces.faq.quote">nota sobre
escapamento de namespaces em strings</link>.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nsconstants">
<title>Palavra-chave namespace e constante __NAMESPACE__</title>
<titleabbrev>Palavra-chave namespace e __NAMESPACE__</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
O PHP suporta duas maneiras de acessar elementos de forma abstrata dentro do namespace atual,
a constante mágica <constant>__NAMESPACE__</constant> e a palavra-chave
<literal>namespace</literal>.
</para>
<para>
O valor de <constant>__NAMESPACE__</constant> é uma string que contém o nome do namespace
atual. Em código global, sem namespace, ela contém uma string vazia.
<example>
<title>Exemplo de __NAMESPACE__, código com namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto;
echo '"', __NAMESPACE__, '"'; // produz "MeuProjeto"
?>
]]>
</programlisting>
</example>
<example>
<title>Exemplo de __NAMESPACE__, código global</title>
<programlisting role="php">
<![CDATA[
<?php
echo '"', __NAMESPACE__, '"'; // produz ""
?>
]]>
</programlisting>
</example>
A constante <constant>__NAMESPACE__</constant> é útil para construir nomes de forma
dinâmica, por exemplo:
<example>
<title>Usando __NAMESPACE__ para construção dinâmica de nomes</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto;
function get($nomedaclasse)
{
$a = __NAMESPACE__ . '\\' . $nomedaclasse;
return new $a;
}
?>
]]>
</programlisting>
</example>
</para>
<para>
A palavra-chave <literal>namespace</literal> pode ser usada para solicitar explicitamente
um elemento do namespace atual ou um subnamespace. Ela é o equivalente
para namespaces do operador <literal>self</literal> para classes.
<example>
<title>O operador namespace, em um namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MeuProjeto;
use bla\bla as meu; // Veja "Usando namespaces: Apelidando/Importando"
bla\meu(); // chama a função MeuProjeto\bla\meu()
namespace\bla\meu(); // chama a função MeuProjeto\bla\meu()
namespace\funcao(); // chama a função MeuProjeto\funcao()
namespace\sub\funcao(); // chama a função MeuProjeto\sub\funcao()
namespace\nomedaclasse::metodo(); // chama o método estático "metodo" da classe MeuProjeto\nomedaclasse
$a = new namespace\sub\nomedaclasse(); // instancia um objeto da classe MeuProjeto\sub\nomedaclasse
$b = namespace\CONSTANTE; // atribui o valor da constante MeuProjeto\CONSTANTE a $b
?>
]]>
</programlisting>
</example>
<example>
<title>O operador namespace, em código global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace\funcao(); // chama a função funcao()
namespace\sub\funcao(); // chama a função sub\funcao()
namespace\nomedaclasse::metodo(); // chama o método estático "metodo" da classe nomedaclasse
$a = new namespace\sub\nomedaclasse(); // instancia um objeto da classe sub\nomedaclasse
$b = namespace\CONSTANTE; // atribui o valor da constante CONSTANTE a $b
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.importing">
<title>Usando namespaces: Apelidando/Importando</title>
<titleabbrev>Apelidando e Importando</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
A capacidade de se referir a um nome totalmente qualificado externo com um apelido, ou importação,
é um recurso importante dos namespaces. Isso é semelhante à
capacidade dos sistemas de arquivos baseados em Unix de criar links simbólicos para um arquivo ou diretório.
</para>
<para>
O PHP pode apelidar ou importar constantes, funções, classes, interfaces, traits, enums e namespaces.
</para>
<para>
A criação de apelidos é realizada com o operador <literal>use</literal>.
Aqui está um exemplo mostrando todos os 5 tipos de importação:
<example>
<title>Importando ou apelidando com o operador use</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use Caminho\Completo\Classe as Outra;
// Isso é o mesmo que use Caminho\Completo\NomeNamespace as NomeNamespace
use Caminho\Completo\NomeNamespace;
// Importando uma classe global
use ArrayObject;
// Importando uma função
use function Caminho\Completo\nomeFuncao;
// Apelidando uma função
use function Caminho\Completo\nomeFuncao as funcao;
// Importando uma constante
use const Caminho\Completo\CONSTANTE;
$obj = new namespace\Outra; // Instancia um objeto da classe foo\Outra
$obj = new Outra; // Instancia um objeto da classe Caminho\Completo\Classe
NomeNamespace\SubNamespace\funcao(); // Chama a função Caminho\Completo\NomeNamespace\SubNamespace\funcao
$a = new ArrayObject(array(1)); // Instancia um objeto da classe ArrayObject
// Sem a declaração "use ArrayObject" teria sido instanciado um objeto da classe foo\ArrayObject
funcao(); // chama a função Caminho\Completo\nomeFuncao
echo CONSTANTE; // imprime o valor de Caminho\Completo\CONSTANTE
?>
]]>
</programlisting>
</example>
Note que para nomes com namespaces (nomes de namespaces totalmente qualificados contendo
o separador de namespace, como <literal>Foo\Bar</literal>, em oposição a nomes globais sem
separadores, como <literal>FooBar</literal>), a barra invertida inicial não é necessária e não
é recomendada, pois nomes importados precisam
ser totalmente qualificados e não são processados em relação ao namespace atual.
</para>
<para>
O PHP também suporta um atalho de conveniência para colocar várias instruções use
na mesma linha.
<example>
<title>Importando ou criando apelidos com várias declarações use combinadas</title>
<programlisting role="php">
<![CDATA[
<?php
use Caminho\Completo\Classe as Outra, Caminho\Completo\NomeNamespace;
$obj = new Outra; // Instancia um objeto da classe Caminho\Completo\Classe
NomeNamespace\SubNamespace\funcao(); // Chama a função Caminho\Completo\NomeNamespace\SubNamespace\funcao
?>
]]>
</programlisting>
</example>
</para>
<para>
A importação é realizada em tempo de compilação e por isso, não afeta classes, funções
ou nomes de constantes gerados dinamicamente.
<example>
<title>Importação e nomes dinâmicos</title>
<programlisting role="php">
<![CDATA[
<?php
use Caminho\Completo\Classe as Outra, Caminho\Completo\NomeNamespace;
$obj = new Outra; // Instancia um objeto da classe Caminho\Completo\Classe
$a = 'Outra';
$obj = new $a; // Instancia um objeto da classe Outra
?>
]]>
</programlisting>
</example>
</para>
<para>
Além disso, a importação afeta apenas nomes não qualificados e qualificados. Nomes totalmente
qualificados são absolutos e não são afetados pelas importações.
<example>
<title>Importação e nomes completamente qualificados</title>
<programlisting role="php">
<![CDATA[
<?php
use Caminho\Completo\Classe as Outra, Caminho\Completo\NomeNamespace;
$obj = new Outra; // Instancia um objeto da classe Caminho\Completo\Classe
$obj = new \Outra; // Instancia um objeto da classe Outra
$obj = new Outra\Coisa; // Instancia um objeto da classe Caminho\Completo\Classe\Coisa
$obj = new \Outra\Coisa; // Instancia um objeto da classe Outra\Coisa
?>
]]>
</programlisting>
</example>
</para>
<sect2 xml:id="language.namespaces.importing.scope">
<title>Regras de escopo para importação</title>
<para>
A palavra-chave <literal>use</literal> precisa ser declarada no
escopo mais externo do arquivo (o escopo global) ou dentro de declarações
de namespaces. Isso ocorre por a importação ser realizada em tempo de
compilação e não em tempo de execução, portanto, não pode ter escopo de bloco. O exemplo
a seguir mostra um uso inválido da palavra-chave
<literal>use</literal>:
</para>
<para>
<example>
<title>Regra de importação inválida</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Linguas;
function paraGroenlandes()
{
use Linguas\Dinamarques;
// ...
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
As regras de importação são por arquivo, o que significa que os arquivos incluídos
<emphasis>NÃO</emphasis> herdarão as regras de importação do arquivo pai.
</para>
</note>
</sect2>
<sect2 xml:id="language.namespaces.importing.group">
<title>Declarações <literal>use</literal> em grupo</title>
<para>
Classes, funções e constantes importadas do
mesmo &namespace; podem ser agrupadas numa única declaração
&use.namespace;.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
use algum\namespace\ClasseA;
use algum\namespace\ClasseB;
use algum\namespace\ClasseC as C;
use function algum\namespace\fn_a;
use function algum\namespace\fn_b;
use function algum\namespace\fn_c;
use const algum\namespace\ConstA;
use const algum\namespace\ConstB;
use const algum\namespace\ConstC;
// É equivalente à seguinte declaração use agrupada
use algum\namespace\{ClasseA, ClasseB, ClasseC as C};
use function algum\namespace\{fn_a, fn_b, fn_c};
use const algum\namespace\{ConstA, ConstB, ConstC};
]]>
</programlisting>
</informalexample>
</sect2>
</sect1>
<sect1 xml:id="language.namespaces.global">
<title>Espaço Global</title>
<titleabbrev>Espaço Global</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Quando um namespace não é definido, todas as definições de classes e funções são
colocadas no espaço global, como era no PHP antes de os namespaces serem
suportados. Prefixar um nome com <literal>\</literal> especificará que
o nome é necessário no espaço global, mesmo no contexto do
namespace.
<example>
<title>Usando a especificação do espaço global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
/* Esta função é A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // chama a função fopen global
return $f;
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.fallback">
<title>Usando namespaces: recorrendo ao espaço global para funções e constantes</title>
<titleabbrev>Recorrendo ao espaço global</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Dentro de um namespace, quando o PHP encontra um nome não qualificado em um nome de classe, função ou
contexto de constante, eles são resolvidos com diferentes prioridades. Nomes de classe sempre
são resolvidos para o nome do namespace atual. Portanto, para acessar classes internas ou classes de usuário
sem namespace, deve-se referir a elas com o nome totalmente qualificado como em:
<example>
<title>Acessando classes globais em um namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('oi'); // $a é um objeto da classe A\B\C\Exception
$b = new \Exception('oi'); // $b é um objeto da classe Exception
$c = new ArrayObject; // erro fatal, classe A\B\C\ArrayObject não encontrada
?>
]]>
</programlisting>
</example>
</para>
<para>
Para funções e constantes, o PHP recorrerá a funções ou constantes globais
se a função ou constante com namespace não existir.
<example>
<title>Recorrendo a funções/constantes globais em um namespace</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
const E_ERROR = 45;
function strlen($str)
{
return \strlen($str) - 1;
}
echo E_ERROR, "\n"; // imprime "45"
echo INI_ALL, "\n"; // imprime "7" - recorre à constante INI_ALL global
echo strlen('oi'), "\n"; // imprime "1"
if (is_array('oi')) { // imprime "não é array"
echo "é array\n";
} else {
echo "não é array\n";
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.rules">
<title>Regras de resolução de nomes</title>
<titleabbrev>Regras de resolução de nomes</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Para efeitos destas regras de resolução, aqui estão algumas definições importantes:
<variablelist>
<title>Definições de nomes de namespace</title>
<varlistentry>
<term>Nome não qualificado</term>
<listitem>
<para>
Este é um identificador sem separador de namespace, como <literal>Foo</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nome qualificado</term>
<listitem>
<para>
Este é um identificador com separador de namespace, como <literal>Foo\Bar</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nome totalmente qualificado</term>
<listitem>
<para>
Este é um identificador com separador de namespace que começa com um
separador de namespace, como <literal>\Foo\Bar</literal>. O namespace
<literal>\Foo</literal> também é um nome totalmente qualificado.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nome relativo</term>
<listitem>
<para>
Este é um identificador que começa com <literal>namespace</literal>, como
<literal>namespace\Foo\Bar</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Os nomes são resolvidos seguindo estas regras de resolução:
<orderedlist>
<listitem>
<simpara>
Nomes totalmente qualificados sempre são resolvidos para o nome sem separador de namespace à esquerda.
Por exemplo, <literal>\A\B</literal> será resolvido para <literal>A\B</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Nomes relativos sempre são resolvidos para o nome com <literal>namespace</literal> substituído
pelo namespace atual. Se o nome ocorrer no namespace global, o
prefixo <literal>namespace\</literal> será removido. Por exemplo, <literal>namespace\A</literal>
dentro do namespace <literal>X\Y</literal> será resolvido para <literal>X\Y\A</literal>. O mesmo nome
dentro do namespace global será resolvido para <literal>A</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para nomes qualificados, o primeiro segmento do nome será traduzido conforme a tabela
de importação de classe/namespace atual. Por exemplo, se o namespace <literal>A\B\C</literal> for
importado como <literal>C</literal>, o nome <literal>C\D\E</literal> será traduzido para
<literal>A\B\C\D\E</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para nomes qualificados, se nenhuma regra de importação se aplicar, o namespace atual será prefixo ao
nome. Por exemplo, o nome <literal>C\D\E</literal> dentro do namespace <literal>A\B</literal>,
será resolvido para <literal>A\B\C\D\E</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para nomes não qualificados, o nome será traduzido conforme a tabela de importação atual para o
respectivo tipo de símbolo. Isso significa que nomes semelhantes a classes serão traduzidos conforme a
tabela de importação de classe/namespace, nomes de funções conforme a tabela de importação de funções e
constantes conforme a tabela de importação de constantes. Por exemplo, após a declaração
<literal>use A\B\C;</literal> um uso como <literal>new C()</literal> será resolvido para o nome
<literal>A\B\C()</literal>. Da mesma forma, após a declaração <literal>use function A\B\foo;</literal> um uso
como <literal>foo()</literal> será resolvido para o nome <literal>A\B\foo</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para nomes não qualificados, se nenhuma regra de importação se aplicar e o nome se referir a um símbolo de classe,
o namespace atual será prefixo. Por exemplo <literal>new C()</literal> dentro do namespace
<literal>A\B</literal> será resolvido para o nome <literal>A\B\C</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para nomes não qualificados, se nenhuma regra de importação se aplicar e o nome se referir a uma função ou constante
e o código estiver fora do namespace global, o nome será resolvido em tempo de execução.
Supondo que o código esteja no namespace <literal>A\B</literal>, é assim que uma chamada para a função
<literal>foo()</literal> será resolvida:
</simpara>
<orderedlist>
<listitem>
<simpara>
Procura pela função no namespace atual:
<literal>A\B\foo()</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Tenta encontrar e chamar a função <emphasis>global</emphasis>
<literal>foo()</literal>.
</simpara>
</listitem>
</orderedlist>
</listitem>
</orderedlist>
</para>
<example>
<title>Resoluções de nomes ilustradas</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A;
use B\D, C\E as F;
// chamadas de funções
foo(); // primeiro tenta chamar "foo" definida no namespace "A"
// então chama a função global "foo"
\foo(); // chama a função "foo" definida no escopo global
minha\foo(); // chama a função "foo" definida no namespace "A\minha"
F(); // primeiro tenta chamar "F" definida no namespace "A"
// e então chama a função global "F"
// referências de classe
new B(); // cria um objeto da classe "B" definida no namespace "A"
// se não for encontrada, tenta carregar automaticamente a classe "A\B"
new D(); // usando regras de importação, cria um objeto da classe "D" definida no namespace "B"
// se não for encontrada, tenta carregar automaticamente a classe "B\D"
new F(); // usando regras de importação, cria um objeto da classe "E" definida no namespace "C"
// se não for encontrada, tenta carregar automaticamente a classe "C\E"
new \B(); // cria um objeto da classe "B" definida no escopo global
// se não for encontrada, tenta carregar automaticamente a classe "B"
new \D(); // cria um objeto da classe "D" definida no escopo global
// se não for encontrado, tenta carregar automaticamente a classe "D"
new \F(); // cria um objeto da classe "F" definida no escopo global
// se não for encontrada, tenta carregar automaticamente a classe "F"
// métodos estáticos/funções de namespace de outro namespace
B\foo(); // chama a função "foo" do namespace "A\B"
B::foo(); // chama o método "foo" da classe "B" definida no namespace "A"
// se a classe "A\B" não for encontrada, tenta carregar automaticamente a classe "A\B"
D::foo(); // usando regras de importação, chama o método "foo" da classe "D" definida no namespace "B"
// se a classe "B\D" não for encontrada, tenta carregar automaticamente a classe "B\D"
\B\foo(); // chama a função "foo" do namespace "B"
\B::foo(); // chama o método "foo" da classe "B" do escopo global
// se a classe "B" não for encontrada, tenta carregar automaticamente a classe "B"
// métodos estáticos/funções de namespace do namespace atual
A\B::foo(); // chama o método "foo" da classe "B" do namespace "A\A"
// se a classe "A\A\B" não for encontrada, tenta carregar automaticamente a class "A\A\B"
\A\B::foo(); // chama o método "foo" da classe "B" do namespace "A"
// se a classe "A\B" não for encontrada, tenta carregar automaticamente a classe "A\B"
?>
]]>
</programlisting>
</example>
</sect1>
<sect1 xml:id="language.namespaces.faq">
<title>Perguntas Frequentes: Coisas que você precisa saber sobre namespaces</title>
<titleabbrev>Perguntas Frequentes</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Estas perguntas frequentes são divididas em duas seções: perguntas comuns e alguns detalhes de
implementação úteis para entender os pormenores.
</para>
<para>
Primeiro, as perguntas comuns.
<orderedlist>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shouldicare">Se não usar namespaces, devo
me importar com esta documentação?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.globalclass">Como usar classes internas ou globais
em um namespace?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.innamespace">Como usar classes,
funções ou constantes de namespace em seu próprio namespace?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.full">
Como nomes como <literal>\meu\nome</literal> ou <literal>\nome</literal>
são resolvidos?
</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.qualified">Como um nome como
<literal>meu\nome</literal> é resolvido?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shortname1">Como um nome de classe não qualificado
como <literal>nome</literal> é resolvido?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shortname2">Como um nome de função
não qualificado ou nome de constante não qualificado
como <literal>nome</literal> é resolvido?</link>
</simpara>
</listitem>
</orderedlist>
</para>
<para>
Há alguns detalhes de implementação dos namespaces úteis para
entendê-los melhor.
<orderedlist>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.conflict">Nomes de importação não devem entrar em conflito com
classes definidas no mesmo arquivo</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.nested">Namespaces aninhados não são permitidos.
</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.quote">Nomes de namespace dinâmicos (identificadores
entre aspas) devem escapar a barra invertida</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.constants">Constantes indefinidas referenciadas
usando qualquer barra invertida geram erro fatal</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.builtinconst">Não é possível substituir
as constantes especiais &null;, &true; ou &false;</link>
</simpara>
</listitem>
</orderedlist>
</para>
<sect2 xml:id="language.namespaces.faq.shouldicare">
<title>Se não usar namespaces, devo me importar com esta documentação?</title>
<para>
Não. Namespaces não afetam nenhum código existente de forma alguma, ou qualquer
código ainda a ser escrito que não contenha namespaces. Você pode
escrever este código se desejar:
</para>
<para>
<example>
<title>Acessando classes globais fora de um namespace</title>
<programlisting role="php">
<![CDATA[
<?php
$a = new \stdClass;
?>
]]>
</programlisting>
</example>
</para>
<para>
O exemplo acima é equivalente ao seguinte código:
</para>
<para>
<example>
<title>Acessando classes globais fora de um namespace</title>
<programlisting role="php">
<![CDATA[
<?php
$a = new stdClass;
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.globalclass">
<title>Como usar classes internas ou globais em um namespace?</title>
<para>
<example>
<title>Acessando classes internas em namespaces</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
$a = new \stdClass;
function test(\ArrayObject $exemplo_com_tipo_de_parametro = null) {}
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
// estendendo uma classe interna ou global
class MinhaExcecao extends \Exception {}
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.innamespace">
<title>
Como usar classes, funções ou constantes de namespace em seu próprio
namespace?
</title>
<para>
<example>
<title>Acessando classes, funções ou constantes internas em namespaces</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
class MinhaClasse {}
// usando uma classe do namespace atual como tipo de parâmetro
function test(MinhaClasse $exemplo_com_tipo_de_parametro = null) {}
// outra forma de usar a classe do namespace atual como tipo de parâmetro
function test(\foo\MinhaClasse $exemplo_com_tipo_de_parametro = null) {}
// estendendo uma classe do namespace atual
class Estendida extends MinhaClasse {}
// acessando uma função global
$a = \funcao_global();
// acessando uma constante global
$b = \INI_ALL;
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.full">
<title>
Como nomes como <literal>\meu\nome</literal> ou <literal>\nome</literal>
são resolvidos?
</title>
<para>
Nomes que começam com uma barra invertida (<literal>\</literal>) sempre são resolvidos
para seu conteúdo exato, então <literal>\meu\nome</literal> é o mesmo que <literal>meu\nome</literal>
e <literal>\Exception</literal> é o mesmo que <literal>Exception</literal>.
<example>
<title>Nomes totalmente qualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
$a = new \meu\nome(); // instancia um objeto da classe "meu\nome"
echo \strlen('olá'); // invoca a função "strlen"
$a = \INI_ALL; // define $a com o valor da constante "INI_ALL"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.qualified">
<title>Como um nome como <literal>meu\nome</literal> é resolvido?</title>
<para>
Nomes que contêm barra invertida, mas não começam com uma barra invertida, como
<literal>meu\nome</literal> podem ser resolvidos de duas maneiras diferentes.
</para>
<para>
Se houver
uma instrução de importação que cria o apelido <literal>meu</literal> para outro nome, então
o apelido da importação será aplicado ao <literal>meu</literal> em <literal>meu\nome</literal>.
</para>
<para>
Caso contrário, o nome do namespace atual será prefixado a <literal>meu\nome</literal>.
</para>
<para>
<example>
<title>Nomes qualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use bla\bla as foo;
$a = new meu\nome(); // instancia um objeto da classe "foo\meu\nome"
foo\bar::nome(); // chama o método estático "nome" na classe "bla\bla\bar"
minha\bar(); // chama a função "foo\minha\bar"
$a = minha\BAR; // define $a com o valor da constante "foo\minha\BAR"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.shortname1">
<title>Como um nome de classe não qualificado como <literal>nome</literal> é resolvido?</title>
<para>
Nomes de classes que não contêm barra invertida como
<literal>nome</literal> podem ser resolvidos de duas maneiras diferentes.
</para>
<para>
Se houver
uma instrução de importação que cria o apelido <literal>nome</literal> para outro nome, então
o apelido da importação será aplicado.
</para>
<para>
Caso contrário, o nome do namespace atual será prefixado a <literal>nome</literal>.
</para>
<para>
<example>
<title>Nomes de classe não qualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use bla\bla as foo;
$a = new nome(); // instancia um objeto da classe "foo\nome"
foo::nome(); // chama o método estático "nome" na classe "bla\bla"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.shortname2">
<title>
Como um nome de função não qualificado ou nome de constante não qualificado
como <literal>nome</literal> é resolvido?
</title>
<para>
Nomes de funções ou constantes que não contêm barra invertida como
<literal>nome</literal> podem ser resolvidos de duas maneiras diferentes.
</para>
<para>
Primeiro, o nome do namespace atual será prefixado a <literal>nome</literal>.
</para>
<para>
Finalmente, se a constante ou função <literal>nome</literal> não existir
no namespace atual, uma constante ou função global <literal>nome</literal>
será usada se existir.
</para>
<para>
<example>
<title>Nomes de funções ou constantes não qualificados</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use bla\bla as foo;
const FOO = 1;
function minha() {}
function foo() {}
function sort(&$a)
{
\sort($a); // chama a função global "sort"
$a = array_flip($a);
return $a;
}
minha(); // chama "foo\minha"
$a = strlen('hi'); // chama a função global "strlen" porque não existe "foo\strlen"
$arr = array(1,3,2);
$b = sort($arr); // chama a função "foo\sort"
$c = foo(); // chama a função "foo\foo" - a importação não é aplicada
$a = FOO; // define $a com o valor da constante "foo\FOO" - a importação não é aplicada
$b = INI_ALL; // define $b com o valor da constante global "INI_ALL"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.conflict">
<title>Nomes de importação não devem entrar em conflito com classes definidas no mesmo arquivo</title>
<para>
As seguintes combinações de script são válidas:
<informalexample>
<simpara>arquivo1.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace minha\coisa;
class MinhaClasse {}
?>
]]>
</programlisting>
<simpara>outra.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace outra;
class coisa {}
?>
]]>
</programlisting>
<simpara>arquivo2.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace minha\coisa;
include 'arquivo1.php';
include 'outra.php';
use outra\coisa as MinhaClasse;
$a = new MinhaClasse; // instancia um objeto da classe coisa do namespace outra
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Não há conflito de nomes, mesmo que a classe <literal>MinhaClasse</literal> exista
dentro do namespace <literal>minha\coisa</literal>, porque a definição de MinhaClasse está
em um arquivo separado. No entanto, o próximo exemplo causa um erro fatal de conflito de nomes
porque MinhaClasse está definida no mesmo arquivo que a declaração use.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace minha\coisa;
use outra\coisa as MinhaClasse;
class MinhaClasse {} // erro fatal: MinhaClasse está em conflito com a declaração de importação
$a = new MinhaClasse;
?>
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.nested">
<title>Namespaces aninhados não são permitidos</title>
<para>
O PHP não permite aninhar namespaces.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace minha\coisa {
namespace aninhada {
class foo {}
}
}
?>
]]>
</programlisting>
</informalexample>
No entanto, é fácil simular namespaces aninhados da seguinte forma:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace minha\coisa\aninhada {
class foo {}
}
?>
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.quote">
<title>Nomes de namespace dinâmicos (identificadores entre aspas) devem escapar a barra invertida</title>
<para>
É muito importante perceber que, como a barra invertida é usada como um caractere de escape
dentro de strings, ela sempre deve ser duplicada quando usada em uma string. Caso contrário,
existe o risco de consequências não desejadas:
<example>
<title>Perigos do uso de nomes com namespace em uma string com aspas duplas</title>
<programlisting role="php">
<![CDATA[
<?php
$a = "\nome\perigoso"; // \n é uma nova linha dentro de strings com aspas duplas!
$obj = new $a;
$a = 'nada\perigoso'; // não há problemas aqui.
$obj = new $a;
?>
]]>
</programlisting>
</example>
Dentro de uma string com aspas simples, a sequência de escape da barra invertida é muito mais segura de usar, mas
ainda é uma prática recomendada escapar as barras invertidas em todas as strings.
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.constants">
<title>Constantes indefinidas referenciadas usando qualquer barra invertida geram erro fatal</title>
<para>
Qualquer constante indefinida não qualificada como <literal>FOO</literal> gerará
um alerta explicando que o PHP assumiu que <literal>FOO</literal> era o valor
da constante. Qualquer constante, qualificada ou totalmente qualificada, que contenha
uma barra invertida produzirá um erro fatal se não for encontrada.
<example>
<title>Constantes não definidas</title>
<programlisting role="php">
<![CDATA[
<?php
namespace bar;
$a = FOO; // Produz um alerta - constante indefinida FOO assumiu "FOO"
$a = \FOO; // Erro fatal, constante de namespace indefinida FOO
$a = Bar\FOO; // Erro fatal, constante de namespace indefinida bar\Bar\FOO
$a = \Bar\FOO; // Erro fatal, constante de namespace indefinida Bar\FOO
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.builtinconst">
<title>Não é possível substituir as constantes especiais &null;, &true; ou &false;</title>
<para>
Qualquer tentativa de definir uma constante de namespace que seja uma constante especial nativa
resultará em um erro fatal.
<example>
<title>Constantes não definidas</title>
<programlisting role="php">
<![CDATA[
<?php
namespace bar;
const NULL = 0; // Erro fatal
const true = 'verdadeiro'; // Também um erro fatal
// etc.
?>
]]>
</programlisting>
</example>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->