Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Fala galera,
Tenho o seguinte autoload no PHP:
define( "CLASS_DIR", __DIR__.DIRECTORY_SEPARATOR."class".DIRECTORY_SEPARATOR );
spl_autoload_register( function( $class ) {
$className = CLASS_DIR.str_replace("\\", DIRECTORY_SEPARATOR, $class).".php";
include( $className );
});
if( $handle = opendir( CLASS_DIR ) ){
while( false !== ( $file = readdir( $handle ) ) ){
if( !is_dir( $file ) && $file != ".DS_Store" ){
$arrayClasses[] = str_replace( ".php", "", $file);
}
}
closedir( $handle );
}
Porém, não gostaria que o mesmo incluísse todas as classes.
Está dando problema quando tenho subdiretórios dentro do diretório /class.
Exemplo:
/class
--- ClasseTeste.php
--- /Recaptcha
-------- Recaptcha.php <- Esta poderia ser incluída, mas o autoload não a encontra.
>
Warning: include(/Applications/XAMPP/xamppfiles/htdocs/common/class/ReCaptcha.php) [function.include]: failed to open stream: No such file or directory in /Applications/XAMPP/xamppfiles/htdocs/common/autoload.php on line 15
Warning: include() [function.include]: Failed opening '/Applications/XAMPP/xamppfiles/htdocs/common/class/ReCaptcha.php' for inclusion (include_path='.:/Applications/XAMPP/xamppfiles/lib/php:/Applications/XAMPP/xamppfiles/lib/php/pear') in /Applications/XAMPP/xamppfiles/htdocs/common/autoload.phpon line 15
Como posso alterá-lo para considerar também sub-diretórios, ou se não é possível, removê-lo através de uma lista de exceções (um array talvez?).
@Gabriel não entendi na real o que fazer.
A PSR-4 (otimização da PSR-0) foi desenvolvida com o intuito de definir uma forma de gerenciamento de classes/namespaces em conjunto com o autoload.
Em um primeiro momento (sem ver código nenhum) concluo que você não está utilizando namespaces nas suas classes. Por esta razão, que o seu autoload não encontra nenhum arquivo desejado.
Primeiro, vamos a definição da PSR-4:
This PSR describes a specification for autoloading classes from file paths. It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0. This PSR also describes where to place files that will be autoloaded according to the specification.
Parafraseando e resumindo: descreve a especificação para o autoload de classes (entenda o que são classes nas regras abaixo) através de caminhos de arquivos. Também descreve aonde os arquivos devem estar para serem carregados automaticamente (conforme as especificações abaixo).
Vamos as regras:
2.1. The term "class" refers to classes, interfaces, traits, and other similar structures.
Até aqui nada de mais, o mais importante vem agora, a definição:
2.2. A fully qualified class name has the following form:\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
1 - The fully qualified class name MUST have a top-level namespace name, also known as a "vendor namespace".
2 - The fully qualified class name MAY have one or more sub-namespace names.
3 - The fully qualified class name MUST have a terminating class name.
4 - Underscores have no special meaning in any portion of the fully qualified class name.
5 - Alphabetic characters in the fully qualified class name MAY be any combination of lower case and upper case.
6 - All class names MUST be referenced in a case-sensitive fashion.
Para exemplificar melhor, veja o repositório Harbinger\Iterator, o qual eu postei aqui.
O meu vendor namespace é "Harbinger". Ele estará presente em todos os pacotes que eu disponibilizar através do Harbinger Project.
"Iterator" é o nome do pacote. Ou seja, possuo \VendorNamespace\NamespaceName <-> \Harbinger\Iterator.
Tudo o que eu desenvolver nesse pacote, será abaixo do namespace acima definido.
Comecemos pela definição do autoload, utilizando PSR-4:
composer.json
{
"autoload": {
"psr-4": { "Harbinger\\Iterator\\": "" }
}
}
Veja bem, tudo que estiver sob o namespace Harbinger\Iterator, estará no root do projeto, ou seja:
Collection.php
<?php
namespace Harbinger\Iterator;
abstract class Collection implements \SeekableIterator , \Countable {
/**
códigos
**/
}
A classe do arquivo Collection.php está definida através do namespace \Harbinger\Iterator\Collection, ou seja, é um fully qualified class name.
Agora veja o caso de um subdiretório:
Filter\Custom.php
<?php
namespace Harbinger\Iterator\Filter;
class Custom extends \FilterIterator {
/**
códigos
**/
}
Veja que, o file path é "Filter/Custom.php", mas o fully qualified class name é "\Harbinger\Iterator\Filter\Custom". Ou seja, além do VendorName e do NamespaceName, foi adicionado o SubnamespaceName, que é convertido de/para uma pasta dentro do projeto (denomidada Filter) e, dessa forma, procura-se a classe (Custom) dentro dessa subpasta.
Mano... hahaha, essas coisas estão aquém do meu conhecimento, acho.
Você comentou que o autoload não encontra nenhum arquivo, mas encontra sim.
O Autoload encontra todos os arquivos que estão na pasta /class... porém, se eu tenho um diretório dentro deste Class, ele não puxa. Este é o problema.
Não tenho como apenas criar uma exceção?
Ainda, sem progresso. Se alguém puder me ajudar, agradeço :)
O autoload trabalha em duas mãos, estrutura de arquivos e estrutura de Namespaces/Classes.
Se um dos dois estiver errado, o autoload não funcionará. Toda a definição da estrutura de namespaces/classes pode ser encontrada na PSR-4.