Namespace PHP

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, storee crie um novo index.phparquivo no diretório.

Segundo, crie srcum diretório no diretório do projeto e Modelum diretório no srcdiretório.

Terceiro, crie um novo arquivo chamado Customer.phpno Modeldiretó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.phpLinguagem de código:  texto simples  ( texto simples )

Definir um namespace

Para definir um namespace, você coloca a namespacepalavra-chave seguida de um nome no topo da página. O exemplo a seguir fornece à Customerclasse 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 srcdiretório o Storenamespace. E você pode substituir Storepelo 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 Customerclasse 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 useoperador 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 useoperador para importar a Customerclasse do Store\Modelnamespace. 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.phpno src/Modeldiretório:

<?php

namespace Store\Model;

class Product
{
}Linguagem de código:  HTML, XML  ( xml )

Para fins de demonstração, a Productclasse está vazia. Agora, a estrutura de diretórios se parece com a seguinte:

.
├── index.php
└── src
    └── Model
        ├── Customer.php
        └── Product.phpLinguagem de código:  texto simples  ( texto simples )

Para usar as classes Customere Productdo 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 Databaseno diretório do projeto e coloque um novo arquivo Logger.phpno Databasediretó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 Utilsno diretório do projeto e crie um novo Logger.php no Utilsdiretó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.phpLinguagem de código:  texto simples  ( texto simples )

Terceiro, importe Loggerclasses de ambos os namespaces Store\Utilse Database\Loggerpara o index.phparquivo:

<?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 à DatabaseLoggerclasse um alias para a Store\Database\Loggerclasse:

<?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 useoperador para importar um namespace ou uma classe de um namespace.
  • Use a aspalavra-chave para atribuir um alias a um namespace ou a uma classe de namespace.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *