Resumo : neste tutorial, você aprenderá sobre namespaces PHP, como definir classes que pertencem a um namespace e como usar namespaces.
Por que namespaces
Quando seu projeto crescer em complexidade, você precisará integrar o código de outros. Mais cedo ou mais tarde, você descobrirá que seu código possui classes diferentes com o mesmo nome. Este problema é conhecido como colisão de nomes .
Para resolver isso, você pode usar namespaces. Namespaces suportados pelo PHP desde a versão 5.3.
O que é um espaço para nome
É mais fácil entender os namespaces por analogia com a estrutura de diretórios em um sistema de arquivos.
Um diretório armazena arquivos relacionados, que é semelhante a um namespace que agrupa classes relacionadas.
Um diretório não permite que você tenha dois arquivos com o mesmo nome. No entanto, você pode ter arquivos com os mesmos nomes em diretórios diferentes. Da mesma forma, os namespaces imitam o mesmo princípio.
Por definição, os namespaces fornecem uma maneira de agrupar classes relacionadas e ajudam a evitar possíveis colisões de nomes.
Namespaces não estão limitados a classes de grupo. Eles podem agrupar outros identificadores, incluindo funções , constantes , variáveis , etc.
Configure uma estrutura de diretórios
Primeiro, crie um diretório de projeto, por exemplo, store
e crie um novo index.php
arquivo no diretório.
Segundo, crie src
um diretório no diretório do projeto e Model
um diretório no src
diretório.
Terceiro, crie um novo arquivo chamado Customer.php
no Model
diretório com o seguinte código:
<?php
class Customer
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
Linguagem de código: HTML, XML ( xml )
O diretório se parece com o seguinte:
.
├── index.php
└── src
└── Model
└── Customer.php
Linguagem de código: texto simples ( texto simples )
Definir um namespace
Para definir um namespace, você coloca a namespace
palavra-chave seguida de um nome no topo da página. O exemplo a seguir fornece à Customer
classe um namespace Store\Model
:
<?php
namespace Store\Model;
class Customer
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
Linguagem de código: HTML, XML ( xml )
- É comum atribuir ao
src
diretório oStore
namespace. E você pode substituirStore
pelo nome da sua marca, por exemplo, Apple. - É uma boa prática imitar a estrutura de diretórios com o namespace para encontrar classes com mais facilidade. Por exemplo, cada classe dentro do diretório receberá o namespace
Store\Model
.
Use uma classe que pertence a um namespace
Para usar uma classe que pertence a um namespace no index.php
, você precisa incluir o arquivo e usar a classe:
<?php
require 'src/Model/Customer.php';
$customer = new Customer('Bob');
echo $customer->getName();
Linguagem de código: HTML, XML ( xml )
Se você abrir o index.php
, receberá um erro fatal:
Fatal error: Uncaught Error: Class 'Customer' not found in...
Linguagem de código: JavaScript ( javascript )
Como a Customer
classe agora tem namespace, você precisa usar o nome totalmente qualificado que inclui o namespace como este:
<?php
require 'src/Model/Customer.php';
$customer = new Store\Model\Customer('Bob');
echo $customer->getName();
Linguagem de código: HTML, XML ( xml )
Agora, deve funcionar corretamente.
Importar um namespace
Para evitar o uso de nomes totalmente qualificados de um namespace, você pode importar o namespace com o use
operador assim:
<?php
require 'src/Model/Customer.php';
use Store\Model;
$customer = new Model\Customer('Bob');
echo $customer->getName();
Linguagem de código: HTML, XML ( xml )
Agora, você só precisa prefixar o nome da classe com Model
.
Importar uma classe de um namespace
PHP permite importar uma classe de um namespace em vez de importar o namespace. Por exemplo:
<?php
require 'src/Model/Customer.php';
use Store\Model\Customer;
$customer = new Customer('Bob');
echo $customer->getName();
Linguagem de código: HTML, XML ( xml )
Neste exemplo, usamos o use
operador para importar a Customer
classe do Store\Model
namespace. Portanto, não precisamos prefixar o nome da classe com o namespace.
Importe várias classes de um namespace
Primeiro, crie um novo arquivo chamado Product.php
no src/Model
diretório:
<?php
namespace Store\Model;
class Product
{
}
Linguagem de código: HTML, XML ( xml )
Para fins de demonstração, a Product
classe está vazia. Agora, a estrutura de diretórios se parece com a seguinte:
.
├── index.php
└── src
└── Model
├── Customer.php
└── Product.php
Linguagem de código: texto simples ( texto simples )
Para usar as classes Customer
e Product
do index.php
, você pode importá-las individualmente como antes:
<?php
require 'src/Model/Customer.php';
require 'src/Model/Product.php';
use Store\Model\Customer;
use Store\Model\Product;
$customer = new Customer('Bob');
echo $customer->getName();
$product = new Product();
Linguagem de código: HTML, XML ( xml )
Quando o número de classes importadas aumentar, seu código se tornará mais detalhado. Então, em vez de importar cada classe individual, você pode importar todas as classes usando uma única instrução:
use namespace\{className1, className2, ...}
Linguagem de código: PHP ( php )
Por exemplo:
<?php
require 'src/Model/Customer.php';
require 'src/Model/Product.php';
use Store\Model\{Customer, Product};
$customer = new Customer('Bob');
echo $customer->getName();
$product = new Product();
Linguagem de código: HTML, XML ( xml )
Classes de alias de um namespace
Primeiro, crie um novo diretório chamado Database
no diretório do projeto e coloque um novo arquivo Logger.php
no Database
diretório com o seguinte código:
<?php
namespace Store\Database;
class Logger
{
public function log($message)
{
var_dump('Log ' . $message . ' to the database.');
}
}
Linguagem de código: HTML, XML ( xml )
Segundo, crie um novo diretório Utils
no diretório do projeto e crie um novo Logger.php no Utils
diretório.
<?php
namespace Store\Utils;
class Logger
{
public function log($message)
{
var_dump('Log ' . $message);
}
}
Linguagem de código: HTML, XML ( xml )
Agora, você tem duas classes com o mesmo nome em namespaces diferentes:
.
├── index.php
└── src
├── Database
│ └── Logger.php
├── Model
│ ├── Customer.php
│ └── Product.php
└── Utils
└── Logger.php
Linguagem de código: texto simples ( texto simples )
Terceiro, importe Logger
classes de ambos os namespaces Store\Utils
e Database\Logger
para o index.php
arquivo:
<?php
require 'src/Utils/Logger.php';
require 'src/Database/Logger.php';
use Store\Utils\Logger;
use Store\Database\Logger;
Linguagem de código: HTML, XML ( xml )
PHP gera o seguinte erro:
Fatal error: Cannot use Store\Database\Logger as Logger because the name is already in use in...
Linguagem de código: texto simples ( texto simples )
Para evitar isso, basta importar os namespaces:
<?php
require 'src/Utils/Logger.php';
require 'src/Database/Logger.php';
use Store\Utils;
use Store\Database;
$loggers = [
new Utils\Logger(),
new Database\Logger()
];
Linguagem de código: HTML, XML ( xml )
Ou você pode dar um alias a uma classe ao importá-la:
import namespace\className as newClassName;
Linguagem de código: JavaScript ( javascript )
O exemplo a seguir atribui à DatabaseLogger
classe um alias para a Store\Database\Logger
classe:
<?php
require 'src/Utils/Logger.php';
require 'src/Database/Logger.php';
use Store\Utils\Logger;
use Store\Database\Logger as DatabaseLogger;
$loggers = [
new Logger(),
new DatabaseLogger()
];
Linguagem de código: HTML, XML ( xml )
Use classes do namespace global
Para usar classes globais, como classes integradas ou classes definidas pelo usuário sem namespace, é necessário preceder o nome dessas classes com uma barra invertida ( \
).
O exemplo a seguir mostra como usar a classe DateTime integrada no namespace App:
<?php
namespace App;
$publish_at = new \DateTime();
echo $publish_at->format('Y-m-d H:i:s');
Linguagem de código: HTML, XML ( xml )
Resumo
- Use um namespace para agrupar classes relacionadas.
- Imite a estrutura de diretórios com os namespaces para facilitar a localização das classes.
- Use o
use
operador para importar um namespace ou uma classe de um namespace. - Use a
as
palavra-chave para atribuir um alias a um namespace ou a uma classe de namespace.