Certo, então vamos lá... Realmente me expressei mal. É possível utilizar namespaces sem autoload utilizando a técnica que você disse, usando require
. Veja como seria o certo:
Arquivo 014_namespaces_01.php
:
<?php
namespace xadai\oie;
class Animal
{
public function speak(): void
{
echo 'I am an animal' . PHP_EOL;
}
}
Arquivo 015_namespaces_02.php
:
<?php
namespace xadai\oie;
class Person extends Animal
{
}
Arquivo teste-namespace.php
:
<?php
use xadai\oie\Person;
require '014_namespaces_01.php';
require '015-namespaces_02.php';
$person = new Person();
$person->speak();
Eu criei um arquivo de testes separadamente apenas para ficar organizado e seguir boas práticas. Nele eu faço a inclusão dos dois arquivos de classe, após crio umas instância de Person
e chamo seu método speak
. Nesse caso como ambos os arquivos estão no mesmo diretório, deve funcionar corretamente.
Veja que na classe Person
não preciso do use
pois ambas classes estão no mesmo namespace, fazendo isso ser desnecessário.
Eu poderia fazer como no seu exemplo, criando a instância de Person
no mesmo arquivo que eu declaro a classe, nesse caso ficando assim:
Arquivo 015_namespaces_02.php
:
<?php
namespace xadai\oie;
require '014_namespaces_01.php';
class Person extends Animal
{
}
$person = new Person();
$person->speak();
Veja que eu estou fazendo o require
do arquivo com a classe Animal
. Com isso consigo corretamente fazer o extends
dela.
O autoload é apenas um forma de facilitar a sua aplicação, pois ele será chamado sempre que uma classe for requisitada e não for de conhecimento do PHP onde ela está. Nesse caso o autoload é chamado para fazer a procura a partir de suas regras e fazer automaticamente o require da class.
Para o autoload funcionar, algumas coisas precisam ser alteradas...
Primeiro o nome do arquivo precisa ser o mesmo nome que o do classe, pois assim facilita o uso do autoload de forma mais genérica.
Depois, as suas classes precisam estarem todas dentro de um mesmo diretório base, visando identificar em qual diretório o autoload vai procurar.
Com isso, teríamos algo assim:
Arquivo src/Animal.php
:
<?php
namespace xadai\oie;
class Animal
{
public function speak(): void
{
echo 'I am an animal' . PHP_EOL;
}
}
Arquivo src/Person.php
:
<?php
namespace xadai\oie;
class Person extends Animal
{
}
Arquivo autoload.php
:
<?php
spl_autoload_register(function (string $nomeCompletoDaClasse){
$caminhoArquivo = str_replace('xadai\\oie', 'src', $nomeCompletoDaClasse);
$caminhoArquivo = str_replace('\\', DIRECTORY_SEPARATOR, $caminhoArquivo);
$caminhoArquivo .= '.php';
if(file_exists($caminhoArquivo)) {
require_once $caminhoArquivo;
}
});
Arquivo teste-namespaces.php
:
<?php
use xadai\oie\Person;
require 'autoload.php';
$person = new Person();
$person->speak();
Veja que os arquivos de classe Person
e Animal
ambos eu movi para a pasta src
pois é nela que o autoload começara a procurar.
E no arquivo de teste testes-namespaces.php
, que é o que irei executar, eu fiz a inclusão do autoload e a partir disso comecei a utilizar as classes.