Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

ro.fonseca

[Resolvido] __autoload nao funciona!

Recommended Posts

E onde está a árvore de arquivos que foi solicitada ? provavelmente seu problema é este ..

Arvore de arquivos? O problema é que ele nao tá chamando pelo nome o obj instanciado pela classe System, nao entendi essa pergunta Andrey.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Arvore de arquivos? O problema é que ele nao tá chamando pelo nome o obj instanciado pela classe System, nao entendi essa pergunta Andrey.

 

Isso .. arvore de arquivos, estrutura de pastas .. tudo a mesma coisa

 

hibernate-projects-libraries.png

Compartilhar este post


Link para o post
Compartilhar em outros sites

A grande maioria das implementações de autoload consiste em mapear um path com base no nome da classe.

 

Ex:

 

function __autoload( $class ) {

   require_once str_replace( '_', DIRECTORY_SEPARATOR, $class ) . '.php';
}

Esse autoloader fará com que instanciar Minha_Classe_Especifica_Para_Fazer_Algo_Que_Preciso inclua o arquivo Preciso.php que estará dentro do diretório Que, que estará dentro de Algo e assim sucessivamente até chegar no Minha que estará na raiz da aplicação.

 

Pelo que entendi do seu problema, do require antes do autoloader estar sabotando e etc. e tal, no seu exemplo, System::run() tem o memso problema.

 

Cara, você TEM UM AUTOLOADER, então PÁRA de usa require_once.

 

Quando você faz:

 

$app = new $this ->_controller;

Automaticamente o autoloader é chamado.

 

Mas veja, seu Controller é algo como QualquerCoisaController.php. Você tenta localizá-lo dentro de /app/controllers mas o seu autoloader busca apenas dentro de /app/models e /app/views.

 

Está havendo um "conflito de interesses" entre o autoloader querendo pegar pra ele a responsabilidade de localizar e incluir o arquivo e tendo o require na aba dele.

 

Resumindo.

 

Para resolver o seu problema, você precisa reestruturar algumas coisas:

 

- Defina uma convenção de nomenclatura para suas classes e crie um autoloader com base nessas regras.

 

No pseudo-code acima, determino que cada underline será trocada pelo separador de diretório do sistema operacional em que o PHP estiver rodando (barra para Windows e barra-invertida para Unix).

 

- Enriqueça seu include_path através de set_include_path() e pare com essas trocentas constantes. Uma só, que aponte para o caminho absoluto do diretório raiz, já basta.

 

- Confie no seu autoloader e páre com esses require's

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entenda uma coisa, o problema aqui não é que o autoload nao esteja achando o arquivo(é antes disso), e sim que o autload não tá nem sequer pegando o nome da classe quando o obj está sendo instanciado, portanto eu não vejo motivo de mostrar essa arvore como tas pedindo, tu tas martelando nesse ponto ainda? Desculpa falar assim Andrey, mas é o terceiro ou quarto post meu que eu reitero sobre isso contigo. E Bruno Augusto, eu vou dar uma lidar melhor no que tu falow mais tarde!

 

abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Poxa pessoal,

 

Quanta dificuldade para uma coisa tão simples. O __autoload não é para ser chamado quando instanciarmos um objeto, o autoload só será executado se, e somente se, a classe não tiver sido definida.

 

<?php
function __autoload( $class ) {
echo 'Se a classe ' , $class , ' não tiver sido definida, o __autoload é chamado.';
}

class Foo {
}

$f = new Foo(); //como a classe Foo foi definida, o __autoload não é executado
$b = new Bar();

 

O que você vai fazer dentro do __autoload é responsabilidade sua. A organização da sua estrutura de arquivos vai ajudá-lo ou não, mas é você que definirá o que fazer ali dentro.

 

Isso significa que você não precisa usar um require ou include, pode fazer qualquer coisa:

 

<?php
function __autoload( $class ) {
echo 'Se a classe ';
echo $class;
echo ' não tiver sido definida, o __autoload é chamado.' , PHP_EOL;

eval( sprintf( '
	class %s {
		public function teste() {
			echo \'Hello world!!!\';
		}
	}',
$class ) );

echo 'A classe ' , $class;
echo class_exists( $class ) ? ' agora existe' : ' ainda não existe';
echo PHP_EOL , PHP_EOL;
}

class Foo {
}

$f = new Foo();
$b = new Bar();
$b->teste();

 

A saída será:

 

Se a classe Bar não tiver sido definida, o __autoload é chamado.

A classe Bar agora existe

 

Hello world!!!

 

Como pode ver, não foi usado um require ou include no __autoload, usamos a função para definir uma classe lá dentro.

 

O ponto é que, após a chamada do __autoload, se a classe ainda não existir, um erro interromperá a execução da aplicação:

 

<?php
function __autoload( $class ) {
echo 'Se a classe ' , $class , ' não tiver sido definida, o __autoload é chamado.';
}

class Foo {
}

$f = new Foo(); //como a classe Foo foi definida, o __autoload não é executado
$b = new Bar();

 

A saída desse fragmento será:

 

Se a classe Bar não tiver sido definida, o __autoload é chamado.

Fatal error: Class 'Bar' not found in ...

 

Isso significa que, se você usar um require que carregue a definição de uma classe, o __autoload jamais será executado, pelo simples motivo de não ser necessário.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entenda uma coisa, o problema aqui não é que o autoload nao esteja achando o arquivo(é antes disso), e sim que o autload não tá nem sequer pegando o nome da classe quando o obj está sendo instanciado, portanto eu não vejo motivo de mostrar essa arvore como tas pedindo, tu tas martelando nesse ponto ainda? Desculpa falar assim Andrey, mas é o terceiro ou quarto post meu que eu reitero sobre isso contigo.

 

Eu não estou me referindo ao autoload, até mesmo porque eu perguntei se o problema era no método, o que provavelmente levaria em conta que sua classe já estivesse definida, porque você usa o require dentro do método ..

 

Te disse pra utilizar include path até mesmo porque pra você não ficar definindo esse monte de constantes, o includePath te serve exatamente pra isso .. evitar que você utilize paths absolutos para encontrar o arquivo ..

 

A Estrutura de arquivos faz toda a diferença nesse tipo de coisa, você tem definido em uma constante 'app/...' ? app é a pasta raiz de todos as outras pastas ? se eu ficar te perguntando cada coisa aqui, teríamos 50 posts e o problema não seria resolvido, o Bruno Augusto mesmo te perguntou a estrutura de arquivos, eu só reforcei a pergunta, porque normalmente esse tipo de erro acontece devido a organização das suas pastas ..

Compartilhar este post


Link para o post
Compartilhar em outros sites

@ro.fonseca

 

Porquê você simplesmente não posta o que eles estão pedindo.

 

Desse jeito vamos ter uns 100 posts desnecessários.

 

Assim não tem como ajudar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

arvore.png

 

Pronto, ae está a arvore dos arquivos.

--

 

Mas a classe do obj que é instanciado dentro da classe System, pelo metodo run não foi definida e a funcao autoload nem sequer tá chamando, o x da questão é essa... De qualquer maneira, já de pra aprender um bocado sobre o autoload.

 

 

Galera, agradeço a todos q postaram por aqui, o bug ainda NÃO(não bem grande, pq eu tinha dado a entender q tinha sido solucionado) foi solucionado, mas a boa vontade de todos aqui e o aprendizado q tive com essa função já valew a pena o topico.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas a classe do obj que é instanciado dentro da classe System, pelo metodo run não foi definida e a funcao autoload nem sequer tá chamando, o x da questão é essa...

 

Amigo, você leu atentamente o que eu escrevi?

 

Veja bem:

 

se você usar um require que carregue a definição de uma classe, o __autoload jamais será executado

 

Agora, olha só:

 

   public function run(){
$controller_patch = CONTROLLERS.$this->_controller.'Controller.php';
if(!file_exists($controller_patch))
   	die('Erro, Controlador inexistente');
require_once($controller_patch);
$app = new $this->_controller;
if(!method_exists($app, $this->_action))
   	die('Metodo Inexistente');
$action = $this->_action;
$app->$action();
   }

 

1. Se o arquivo $controller_path não existir :seta: Mata a execução com a mensagem: "Erro, Controlador inexistente".

Perceba que você nem chegou a instanciar o objeto, se o arquivo não existir a execução morre aqui mesmo.

2. require_once $controller_path :seta: Carrega o arquivo $controller_path que contém, provavelmente, a definição da classe.

3. $app = new $this->_controller :seta: Cria uma instância de um objeto usando as regras que você definiu anteriormente.

 

Perceba que, se o arquivo Controller.php contiver a definição da classe, __autoload jamais será executado, afinal, se o arquivo não existir, você mata a execução ou, se o arquivo existir, você já fez um require dentro do método run().

 

O bug existente não é no __autoload.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites
se você usar um require que carregue a definição de uma classe, o __autoload jamais será executado

 

O autoload jamais será executado para chamar a tal classe definida, pq ele chama outras normalmente, eu testei aqui, e se der pau em uma, caso nao encontre, ele deixa de executar completamente.

 

Perceba que, se o arquivo Controller.php contiver a definição da classe, __autoload jamais será executado, afinal, se o arquivo não existir, você mata a execução ou, se o arquivo existir, você já fez um require dentro do método run().

 

o bug tá nesse metodo, nao sei se é o require, embora no documento do autoload ele tá chamando normalmente, olhe esse código:

 

<?php
//require_once("system/system.php");
//require_once("system/controller.php");
require_once("system/model.php");
DEFINE('CONTROLLERS', 'app/controllers/');
DEFINE('VIEWS', 'app/views/');
DEFINE('MODELS', 'app/models/');
DEFINE('HELPERS', 'system/helpers/');
DEFINE('SYSTEM', 'system/');

function __autoload_files($file){
   echo $file;
   require_once(SYSTEM . $file . '.php');
//    if(file_exists(MODELS . $file . 'Model.php'))
//	require_once(MODELS . $file . 'Model.php');
//    if(file_exists(VIEWS . $file . '/' . $file . '.phtml'))
//	require_once(VIEWS . $file . '/' . $file . '.phtml');
//    if(file_exists(HELPERS . $file . '.php'))
//	require_once(HELPERS . $file . '.php');
//    else
//	die ("Classe inexistente"); 

}
spl_autoload_register('__autoload_files');

$start = new System;
$teste = new Controller;
$teste = new Model;

 

Ele chama a classe System, chama a classe Controller, já a classe Model ele não chama por causa do require, enfim, tá funcionando normalmente, já para chamar a classe que é instanciada dentro do metodo run ele não chama.

 

 

 

 

edit - Bug resolvido galera, e por um motivo bem bobo e obvio, o autoload nao instanciava dentro do metodo run, justamente pq o require_once(dentro da função run) já fazia isso daee bugava td já que nao chamava nem o MODEl e nem o VIEW dentro do autoload, mas é bom ressaltar, o metodo autoload nao cessa pelo fato você definir uma classe, ele somente deixa de chama-la, outra ocasiao em que ele para a execução é quando a classe que você tenta chamar nao existir. Mais uma vez, obrigado a todos.

 

 

 

Abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

post #26

Isso significa que, se você usar um require que carregue a definição de uma classe, o __autoload jamais será executado

 

post #30

2. require_once $controller_path :seta: Carrega o arquivo $controller_path que contém, provavelmente, a definição da classe.

...__autoload jamais será executado, ...você já fez um require dentro do método run().

 

e por um motivo bem bobo e obvio, o autoload nao instanciava dentro do metodo run, justamente pq o require_once(dentro da função run) já fazia isso.

 

<_<

 

ufa!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Galera, só postem se tiverem mais contribuições com o assunto do tópico.

 

Brigas, e discussões, desentendimentos devem ser feitos via MP.

Se tiver mais alguma coisa por aqui, eu fecho o tópico.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.