Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá pessoal,
Estou com algumas dúvidas referente ao uso da função __autoload(). Consegui usá-la normalmente, mas, tive problemas quando separei os diretorios, então minha dúvida é: Qual a melhor maneira de usar o __autoload() com diversos diretórios?
Em minha aplicação tenho o seguinte:
app/
|_ model/
|_ view/
|_ controller/
|_configs/
|_ autoload.php
Então, a primeira solução que me veio à mente foi usar a função spl_autoload_register, onde eu criaria várias funções e as invocaria usando várias vezes o spl_autoload_register, por exemplo:
<?php
function autoloadControllers( $classname )
{
require_once "controllers/{$classname}.php";
}
function autoloadViews( $classname )
{
require_once "views/{$classname}.php";
}
function autoloadModels( $classname )
{
require_once "models/{$classname}.php";
}
spl_autoload_register( 'autoloadControllers' );
spl_autoload_register( 'autoloadViews' );
spl_autoload_register( 'autoloadModels' );
Procurando pelo fórum, também pensei em alterar a variável do sitema include_path e adicionar todos os caminhos da pasta, e aí usar uma única função para __autoload, mas acabei fazendo dessa maneira:
<?php
function autoloadMVC( $className )
{
$className = ltrim($className, '\\');
$fileName = '';
$namespace = '';
if ( $lastNsPos = strrpos( $className, '\\' ) ) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace( '\\', DIRECTORY_SEPARATOR, $namespace ) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace( '_', DIRECTORY_SEPARATOR, $className ) . '.php';
$directories = array( 'model', 'model/entity', 'view', 'controller', 'util', 'config' );
foreach ( $directories as $dir ) {
if ( stream_resolve_include_path( "{$dir}/{$fileName}" ) ) {
require_once "{$dir}/{$fileName}";
break;
}
}
}
spl_autoload_register( 'autoloadMVC' );
Mas não sei se seria a opção mais 'elegante' e funcional, devido ao loop utilizado dentro da função... Existe alguma maneira mais prática para o uso do __autoload no PHP?
Obrigado!
Cara eu não sei se você vai usar porem tenho essa função de autoload que sempre uso quando tenho classes em vários diretórios.
Qualquer duvida ou problema que você achar no código pode falar que eu arrumo aqui :closedeyes:
function __autoload($classes) {
/* Diretorios das classes */
$diretorios = array('app/', 'assets/', 'class/', 'pages/', 'template/');
foreach ($diretorios as $valor) {
if (file_exists($valor . $classes . '.php')) {
require_once $valor . $classes . '.php';
}
}
}#3.. pelo que entendi, ele quer evitar esse "loop"..
Olá a todos,
#3 Vini, obrigado pela resposta. Se você reparar no meu código, eu uso exatamente um loop parecido com este, tendo pequenas diferenças na implementação. Minha dúvida é referente à performance deste tipo de implementação. Na verdade, queria unir performance + elegância :coolio:
#4 hinom,
Testei com namespaces também, funcionou quando eu nomeei os namespaces com a estrutura dos diretorios, acho que vou fazer assim pois aí já me adapto de vez com os Namespaces também... Mas saberia me dizer se temos ganho de performance neste caso?
Obrigado,
Abs
Desculpa ai Jonas, aqui esta o autoload sem o loop.
Ve se você consegui entender e se vai ser útil pra você, porque se for eu te explico como funciona.
function loadClass($diretorio, $classe) {
$classe = explode('\\', $classe);
$classe = end($classe);
if (file_exists($diretorio . $classe . '.php')) {
require_once $diretorio . $classe . '.php';
}
}
function autoloadClass($classe) {
loadClass('class/', $classe);
}
function autoloadApp($classe) {
loadClass('app/', $classe);
}
spl_autoload_register('autoloadClass');
spl_autoload_register('autoloadApp');queria unir performance + elegância
ahaha. somos dois então. rsrsr
uma solução elegante no post #6.
Mas ainda prefiro com namespaces, pois não precisa nem usar spl_autoload_register().
A melhor prática é seguir a PSR-0.
Beleza pessoal,
Agradeço muito a Ajuda de todos, Vini, Hinom e Enrico. Irei utilizar os namespaces:
spl_autoload_register(
function( $classname ) {
$classname = stream_resolve_include_path( str_replace( '\\', DIRECTORY_SEPARATOR, $classname ) . '.php' );
if( $classname !== FALSE ) {
include $classname;
}
}
);http://forum.imasters.com.br/topic/476066-autoload-sem-perder-performance-e-desempenho/
Para quem interessar...
Abraços
Uma forma de evitar esse loop é usar namespace.
Assim, bastaria definir o namespace de acordo com o path da classe.