Ir para conteúdo

Arquivado

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

Eduardo Giullyanny

[Resolvido] __autoload chato

Recommended Posts

Galera estou com o seguinte autoload.:

 

function __autoload($class) {
$class = str_replace("_", "/", $class) . ".php";
require_once $class;
}

 

fiz este teste aqui.:

class Projeto_Db_Adapter_teste {

function __construct($argument) {
	print "teste.php";
}

}

 

 

E estou chamando ele assim.:

new Projeto_Db_Adapter_teste;

 

eh mais ou menos assim q o zend trabalha, ai estava eu ministrando um curso e o trem num funciona, mas no meu funciona, estou tentando saber o maximo sobre o __autoload() agora q o trem deu pau, pois achei q num tinha duvidas, queria saber a partir de qdo isso esta disponivel, pois no colegio o php é o 5.3;

 

obrigado galera.

Compartilhar este post


Link para o post
Compartilhar em outros sites

opá brothers eu tb tenho um set_include_path e veja só, eu simulei aqui o trem para saber se tava fazendo errado o negocio e deu certo, mas não o __autoload().

 

function no($class) {
$class = str_replace("_", "/", $class) . ".php";
print $class;
require_once $class;
}
no('Projeto_Data_Conn');

 

isso esta imprimindo e também está incluindo o arquivo beleza...

 

o que pode ser????

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esta função mágina funciona assim: Ela só carrega as classes automaticamente caso o nome da classe seja o mesmo nome do arquivo. Pelo menos eu testei sem usar este padrão e não carregou (ou eu não soube fazer corretamente (Ââhhn?)).

 

Faz o teste e retorna.

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu até tentei fazer isso, mas quado eu instancio a classe dá problema, você percebeu que eu até coloquei um print para ver se saia alguma coisa, eu estou testando no meu pc, linux do meu note, nele da certo.

 

fiz um teste aqui agora com a constante directory_separator e num deu nada

 

function __autoload($class) {
$class = str_replace("_", DIRECTORY_SEPARATOR, $class) . ".php";
print $class;
require_once $class;
}

//estou chamando assim.:
Projeto_Data_Conn::Fabrica();

 

parece que qdo eu instancio, ele não executa o autoload.

 

poderia dar uma dica para que eu possa debugar isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu até tentei fazer isso, mas quado eu instancio a classe dá problema, você percebeu que eu até coloquei um print para ver se saia alguma coisa, eu estou testando no meu pc, linux do meu note, nele da certo.

 

fiz um teste aqui agora com a constante directory_separator e num deu nada

 

function __autoload($class) {
$class = str_replace("_", DIRECTORY_SEPARATOR, $class) . ".php";
print $class;
require_once $class;
}

//estou chamando assim.:
Projeto_Data_Conn::Fabrica();

 

1º - Remove este str_replace.

2º - Qual a lógica disso? Substitua o "_" pelo separador de diretório, na classe em que você chama? oO, explica isso ai!

3º - Seu método está público e é estático?

4º - Faça assim:

 

define ("DS", DIRECTORY_SEPARATOR);
function __autoload($class) {
if(class_exists('directory' . DS . $class . '.php')){
            require_once 'directory' . DS . $class . '.php';
       }
}

//estou chamando assim.:
Projeto_Data_Conn::Fabrica();

Compartilhar este post


Link para o post
Compartilhar em outros sites

O arquivo que está fazendo o autoload, está no mesmo nível da pasta projeto?

 

Caso negativo, você setou o diretório, informando a partir de onde o PHP vai buscar as classes com o set_include_path?

Compartilhar este post


Link para o post
Compartilhar em outros sites

function __autoload($class_name) {
print $class_name;
require 'Projeto/Data/Conn.php';
}

 

Amigos, poderia me dizer, que no momento em que eu instancia um classe ele num tem que executar o __autoload().

 

usei ele apenas para imprimir algo e buscar o arquivo direto, num esta vindo nada. o que estou fazendo de errado, o metodo num esta sendo chamado, tudo esta no msm nivel, testei o ultimo exemplo e num tem nada dando certo...

 

estou ficando cada vez com mais dúvida

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faz assim pra debugar:

 

function __autoload($class_name) {
     if(file_exists($class_name. ".php")):
          require_once $class_name . ".php";
     else:
          throw new Exception("A classe {$class_name} não existe!");
     endif;

     print_r($class_name);
}

Poste sua classe pra ficar maais fácil resolver o problema.

Mas diante do seu código, eu percebo que:

- O print imprime strings, e sua classe NÃO é uma string, é um Objeto, são coisas totalmente diferentes.

Pra você debugar se sua classe está mesmo sendo carregada, use o print_r ou var_dump, que provavelmente te retornara algo do tipo:

ClassName Object()

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia amigos;

 

Ontem não pude mais tentar resolver este problema, tinha chegado visita em minha casa, mas continuando...

 

Amigo hunternh eu tinha visto tb sobre o CLI, tem uns testes lah para saber, fiz e não sou.

 

Guilherme_90 bravo.(rsrsrs), fiz aquilo q me pediu para fazer, o maior problema é justamente isso, veja minha estrutura de pastas.:

lib

____Projeto

____Data

____Connection.php

o nome dos meus arquivos são organizados para entrar nestes diretorio através do __autoload(), coloquei da forma que me pediu e fiz alguns teste, estes foram os ultimos.:

/*function __autoload($class) {
$class = str_replace("_",DIRECTORY_SEPARATOR, $class) . ".php";
print_r($class);
require_once $class;
}*/
function __autoload($class_name) {
     if(file_exists(str_replace("_",DIRECTORY_SEPARATOR, $class_name). ".php")):
          require_once str_replace("_",DIRECTORY_SEPARATOR, $class_name) . ".php";
     else:
          throw new Exception('A classe {str_replace("_",DIRECTORY_SEPARATOR, $class_name)} não existe!');
     endif;

     print_r($class_name);
}

este acima é o loader.

 

print_r(Projeto_Db_Connection::Fabrica($config));

como eu o chomo acima

 

 

class Projeto_Db_Connection {
public static function Fabrica($config) {
	print '<br>chamada na fabrica<br>';
	switch ($config['plug']) {
		case 'mysql' :
			return Projeto_Db_Adapter_Mysql::getConnection($config);
			break;
	}
}

}

acima a classe que estou chamando

 

Bom é mais ou menos isso, poderiam me ajudar a saber o porque n funciona. Eu tenho um set_include_path para a pasta lib

Compartilhar este post


Link para o post
Compartilhar em outros sites

você ta incluindo arquivo do autoload né? =X

 

você ta usando set_include_path e __autoload deve ta dando algum problema nessa combinação ai

 

tinha um esquema que era +/- assim e funcionava sussa!

 

load.php

function __autoload($class_name) {
     if(file_exists($file = str_replace("_",DIRECTORY_SEPARATOR, $class_name). ".php")){

      echo $file;
      require_once $file;

    }


}

 

teste.php


include 'app/load.php';

class app_teste {

function __construct(){
echo 'Na classe teste';
}

}

$t = new app_teste();

 

tem que avaliar se __autoload realmente e necessario, include_path por si so e bem eficiente, trabalhando com MVC então, fica bem facil e organizado sem precisa depende do __autoload

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sem querer ser chato e decepcionar vocês. Essa parte do manual deve ser lido:

Autoloading Classes

 

spl_autoload_register() provides a more flexible alternative for autoloading classes. For this reason, using __autoload() is discouraged and may be deprecated or removed in the future.

 

__autoload não deve mais ser usado. No lugar, deve-se usar spl_auto_load_register(). A funcionalidade é a mesma. Só muda um pouco a forma de implementação.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fiz um exemplo que funciona tanto no Windows quanto no Linux.

 

Siga a estrutura de diretórios e arquivos.

 

Bootstrap/Bootstrap.php

<?php

class Bootstrap
{
   /**
    *  @var array Armazena os paths
    *  @access protected
    */
   protected $path;
   /**
    *  @var array Armazena o charset
    *  @access protected
    */
   protected $charset = 'UTF-8';
   /**
    *  @var boolean Mostra ou não os erros
    *  @access protected
    */
   protected $errors = false;
   /**
    *  Construtor da classe
    *  @access public
    *  @return void
    */
   public function __construct( )
   {
       $this->path = array(
              ini_get(  'include_path' )
           );
   }
   /**
    *  Executa as configurações
    *  @access public
    *  @return void
    */
   public function run( )
   {
       $this->errors( );
       $this->paths( );
       $this->timezone( );
       $this->charset( );
   }
   /**
    *  Define se a aplicação mostra os erros
    *  @param string $standard opcional true
    *  @access public
    *  @return void
    */
   public function setErrors( $standard )
   {
       $this->errors = $standard;
   }
   /**
    *  Mostrar todos os erros.
    *  @param boolean $standard opcional true ou false
    *  @access protected
    *  @return void
    */
   protected function errors( )
   {
       if( $this->errors )
       {
           ini_set( 'display_errors', true );
           error_reporting( E_ALL | E_STRICT );
       }
       else
       {
           ini_set( 'display_errors', false );
           error_reporting( 0 );
       }
   }
   /**
    *  Armazena os include paths
    *  @access public
    *  @return void
    */
   public function setIncludePath( $path )
   {
       $this->path[ ] = realpath( $path );
   }
   /**
    *  Define os include paths
    *  @access protected
    *  @return void
    */
   protected function paths( )
   {
       ini_set( 'include_path' , implode( PATH_SEPARATOR , array_unique( $this->path ) ) );
   }
   /**
    *  Configura a timezone padrão a ser utilizada por todas
    *  as funçoes de data e hora em um script para America/Sao_Paulo
    *  @access protected
    *  @return void
    */
   protected function timezone( )
   {
       setlocale( LC_ALL, "pt_BR", "pt_BR.iso-8859-1", "pt_BR.utf-8", "portuguese" );
date_default_timezone_set( 'America/Sao_Paulo' );
   }
   /**
    *  Define a codificação
    *  @param string $charset A codificação
    *  @access protected
    *  @return void
    */
   protected function charset( )
   {
       header( sprintf( 'Content-Type: text/html; charset="%s"', $this->charset ) );
   }
   /**
    *  Armazena a codificação
    *  @param string $charset A codificação
    *  @access public
    *  @return void
    */
   public function setCharset( $charset )
   {
       $this->charset = $charset;
   }
}

 

Loader/Autoloader.php

<?php

final class Autoloader
{
   /**
    *  Inicia o loader
    *  Registra o método na pilha de __autoload da SPL.
    *  @access public
    *  @return void
    */
   public function start( )
   {
       spl_autoload_register( array( $this, 'loader' ) );
   }
   /**
    *  Inclue os arquivos das classes que são instanciadas
    *  @param string $class O nome da classe
    *  @access private
    *  @return void
    */
   private function loader( $class )
   {
       include_once( sprintf( '%s.php', str_replace( '_', DIRECTORY_SEPARATOR, $class ) ) );
   }
}

 

Test/DirectoryTest/ClassTest.php

<?php

class DirectoryTest_ClassTest
{
   public function __construct( )
   {
       echo 'Test ok!';
   }
}

 

index.php

<?php

include( 'Bootstrap/Bootstrap.php' );
include( 'Loader/Autoloader.php' );

$bootstrap = new Bootstrap( );
$bootstrap->setErrors( true ); // true em modo de desenvolvimento, false em modo de produção
$bootstrap->setIncludePath( 'Test/' );
$bootstrap->run( );

$autoloader = new Autoloader( );
$autoloader->start( );

var_dump( new DirectoryTest_ClassTest( ) );

 

Saída

Test ok!
object(DirectoryTest_ClassTest)[3]

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia amigo;

 

Quero agradecer pelas dica

 

fiz e retornou isso.:

object(PDO)#5 (0) { } 

 

Acredito que tenha dado certo. Obrigado Carlos Coelho por disponibilizar o código, e obrigado ao Gabriel Heming por ter me chamado a atenção por um fato que num tinha visto, eu li 90% do php.net sobre o __autoload() e justamente o pedaço que pulei tinha a informação.

 

Será que tem algo a ver sobre o load num funcionar? Bom sei que o cod deu certo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O Carlos, seu exemplo funciona, beleza, mas importante: Seu autoloader deve iniciar uma única vez, portanto esse método poderia ser estático, como Class::initialize ( ) , não vejo nenhuma razão para que a classe Autoloader seja instanciada também.

 

<?php
      class Application {


             static public function initialize ( ) {
                    spl_autoload_register ( function ( $class ) { 
                           $s = str_replace ( '_' , DIRECTORY_SEPARATOR , $class ) . '.php' ;
                           if ( file_exists ( $s ) ) {
                                  require_once $s ;
                           } else {
                                  // ...
                           }
                    } ) ;
             } 

      }

      Application::initialize ( ) ;

Compartilhar este post


Link para o post
Compartilhar em outros sites

dei uma estudada no spl_autoload_register e tentei fazer isso.:

 

final class loader {
 public static function start() {
	spl_autoload_register(
		function ($class) {
			require_once(sprintf('%s.php', str_replace('_', DIRECTORY_SEPARATOR, $class)));
		}
	);
}

}

loader::start();

 

esta dando erro 500 no browser.

PS: quero aprender sobre esta nova função q num conhecia, estou apanhado bastante dela, poderiam me dizer o que esta errado, pois sei que alguns não vão querer ajudar por saber que o codigo que o Carlos deu certo, mas não quero codigo pronto, eu preciso aprender

Compartilhar este post


Link para o post
Compartilhar em outros sites

esta dando esse erro chato!

 

Notice: Undefined variable: this in C:\WEB\Apache2\htdocs\novo\config\loader.php on line 12 Fatal error: Uncaught exception 'LogicException' with message 'Passed array does not specify an existing static method (first array member is not a valid class name or object)' in C:\WEB\Apache2\htdocs\novo\config\loader.php:15 Stack trace: #0 C:\WEB\Apache2\htdocs\novo\config\loader.php(15): spl_autoload_register(Array) #1 C:\WEB\Apache2\htdocs\novo\index.php(3): Autoloader::start() #2 {main} thrown in C:\WEB\Apache2\htdocs\novo\config\loader.php on line 15

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.