Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Então, a minha função __autoload simplesmente nao funciona quando eu faço o require de qualquer classe antes dela, segue abaixo um exemplo o codigo:
NÃO funciona
require("classes/teste.php");
function __autoload($file){
...
}
$app = new Teste;
FUNCIONA
function __autoload($file){
...
}
$app = new Teste;
Alguma ideia?o autoload eh ra carregar a classe automaticamente, por isso o nome de auto load, carga automatica, se você faz um require antes dele, você esta anulando seu efeito, sua funcao...você precisa definir as regras de carregamento do autoload no autoload...lembrando e ele sera chamado pra toda e qq classe, logo defina bem suas regras de carregamento...
>
Eu nunca testei, mas ao que parece o autoload está tendo peso maior do que teu require.
Experimenta trocá-lo por require_once(), dessa forma, seja qual for a formacom que você invoca o arquivo dentro do autoload, se este arquivo já tiver sido incluído, ele não o será de novo.
Claro, isso é apenas especulação, afinal, você não postou lá muitas informações, como por exemplo, o começo da sua classe Teste (ou outra real) e a sua implementação de __autoload().
Já testei colocando o require_once antes do autoload e nada...
>
o autoload eh ra carregar a classe automaticamente, por isso o nome de auto load, carga automatica, se você faz um require antes dele, você esta anulando seu efeito, sua funcao...você precisa definir as regras de carregamento do autoload no autoload...lembrando e ele sera chamado pra toda e qq classe, logo defina bem suas regras de carregamento...
Eu já tentei fazer sem o require_once, mas o que acontecia é que ele chamava o Sytem pelo autoload, só que dentro da classe System, ele faz uma outra chamada de objeto, e esse objeto chamado dentro da classe system não eh carregado pelo autolad.
exemplo:
FUNCIONA(repare que está sem o require da classe system)
function __autoload($file){
...
{
$teste = new System
NÃO FUNCIONA(repare que o autoload nao carrega o nome da classe do obj instaciado dentro da Classe System)
function __autoload($file){
...
{
$teste = new System
$teste->run();
Class System{
public function run(){
$testeChamada = new TesteChamada;
}Foi o que o nosso amigo disse. O __autoload faz a requisição da classe logo quando o documento se inicia. A regra definida para o autoload é essa, carregar algo logo quando o documento iniciar. Você está cometendo um erro de lógica no seu script.
>
Foi o que o nosso amigo disse. O __autoload faz a requisição da classe logo quando o documento se inicia. A regra definida para o autoload é essa, carregar algo logo quando o documento iniciar. Você está cometendo um erro de lógica no seu script.
Mas quando o documento é iniciado o metodo run é chamado, instanciando logo depois o obj, qual seria o erro?
A keyword 'class' não deve ser com letra maiúscula, o nome da classe deve ser idêntico ao nome do arquivo
function __autoload ( $className ) {
require_Once sprintf ( '%s.php' , $className ) ;
}
Utilize também o includePath para setar o diretório em que suas classes estão ..
set_include_path ( get_include_path() . PATH_SEPARATOR . 'classes' ) ;
Dessas regras eu já sei po, mas é que não chama mesmo, eu dei um echo em "$className" dentro de autoload e ele só exibe "system".
exatamente, toda vez q uma classe for instanciada o autoload eh evocado, vamos ver um exemplo
//este exemplo vai chamar todas as classes dentro do diretorio classes
function __autoload($class)
{
require_once("classes/{$class}.php");
}//ex. System_core => System/core.php
//ex. View_Input => View/Input.php
function __autoload($class)require_once(str_replace('_','/',"{$class}.php"));
}>
eu dei um echo em "$className" dentro de autoload e ele só exibe "system".
Isso, esse é o nome interceptado pelo autoLoad, agora você tem que incluir esse arquivo, ele não vai 'fazer' o include pra você .. por isso te disse pra usar o includePath, assim, quando você for incluir X arquivo, o autoLoad vai varrer esses diretórios em busca do arquivo system.php ..
Não entendi esse teu exemplo, mas sim, tecnicamente toda vez q uma classe for instanciada é evocada o autoload, mas comigo, no meu exemplo, instanciando os objetos dentro da classe System, o autoload não está funcionando.
ok, posta o codigo todo...
alias, mostra a arvore das classes...
>
Isso, esse é o nome interceptado pelo autoLoad, agora você tem que incluir esse arquivo, ele não vai 'fazer' o include pra você .. por isso te disse pra usar o includePath, assim, quando você for incluir X arquivo, o autoLoad vai varrer esses diretórios em busca do arquivo system.php ..
Eu sei como funciona o autoload po, o problema aqui é que ele só está chamando o system, e os objs que eu instanciei dentro dele, cade? É isso o q refiro.
>
ok, posta o codigo todo...
alias, mostra a arvore das classes...
Já postei po, é simples, tá num outro topico um pouco acima, é só uma classe que dentro dela tem um metodo q instancia um outro objeto logo que o documento é chamado, documento este, que tem a função autoload.
escrever o nome da funcao nao eh codigo todo...pra você ser ajudado tem q postar o codigo pra vermos onde você esta errando...nao eh possivel q o pesoal d zend iria deixar mais de 59% dos sites mundiais com esse bug...
>
escrever o nome da funcao nao eh codigo todo...pra você ser ajudado tem q postar o codigo pra vermos onde você esta errando...nao eh possivel q o pesoal d zend iria deixar mais de 59% dos sites mundiais com esse bug...
KKKKKK pois é, é pq nao to em casa, então só mostrei o q de fato tava acontecendo, passei a madrugada de hj nesse bug q eu ainda nao sei o q é, mas ele funciona na logica do meu exemplo mostrado anteriormente.
Tenho uma idéia do que possa ser, mas preciso que você poste:
Mesmo que já tenha postado algumas dessas coisas, peço que as repita num único post para facilitar o apontamento de dados.
ok, quando eu chegar em casa eu coloco.
Pronto! Podem até reparar q dei um echo no $file, para ver o que sai, como tem o "require_once" chamando já a classe system, ele não chama ela de novo no autoload, mas como eu falei antes, se caso eu tirar esse require_once, ele chama a tal "system", só que, cade de chamar pelo nome os objetos instanciados pela tal classe?
Classe System:
<?php
class System{
private $_url;
private $_explode = array();
public $_controller;
public $_action;
public $_param = array();
public function __construct(){
$this->setUrl();
$this->setExplode();
$this->setController();
$this->setAction();
$this->setParams();
}
private function setUrl(){
$_GET['url'] = (isset($_GET['url']) && $_GET['url'] != 'index' ? $_GET['url'] : "index/indexAction");
$this->_url = $_GET['url'];
}
private function setExplode(){
$this->_explode = explode('/', $this->_url);
}
private function setController(){
$this->_controller = $this->_explode[0];
}
private function setAction(){
$action = (!isset($this->_explode[1]) || empty($this->_explode[1]) || $this->_explode[1] == "index" ? "indexAction" : $this->_explode[1]);
$this->_action = $action;
}
private function setParams(){
for($i=1;$i<count($this->_explode);$i++)
if($i % 2 == 0)
$this->_param[$this->_explode[$i]] = (!empty($this->_explode[$i+1]) ? $this->_explode[$i+1] : "");
}
public function getUrl(){
return $this->_url;
}
public function getParams($param = null){ return $this->_param; return $this->_param[$param];
}
public function run(){
$controller_patch = CONTROLLERS.$this->_controller.'Controller.php'; 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();
}
}
?>
O index.php
<?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/system.php');
function __autoload_files($file){
echo $file;
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;
$start->run();Você diz nesse método ?
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();
}sim, nesse metodo.
E onde está a árvore de arquivos que foi solicitada ? provavelmente seu problema é este ..
>
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.
>
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
/applications/core/interface/imageproxy/imageproxy.php?img=http://netbeans.org/images_www/articles/67/web/hibernate-webapp/hibernate-projects-libraries.png&key=c6dea50aaa6e2e3e5c685b4cbaef734a2ad88c4cf99ad3e3ee616b4dd22a8dd0" alt="hibernate-projects-libraries.png" />
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:
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).
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!
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.
Eu nunca testei, mas ao que parece o autoload está tendo peso maior do que teu require.
Experimenta trocá-lo por require_once(), dessa forma, seja qual for a formacom que você invoca o arquivo dentro do autoload, se este arquivo já tiver sido incluído, ele não o será de novo.
Claro, isso é apenas especulação, afinal, você não postou lá muitas informações, como por exemplo, o começo da sua classe Teste (ou outra real) e a sua implementação de __autoload().