Autor Tema: Cargar varias clases php con str_autoload_register desde varios directorios  (Leído 5524 veces)

gatoher

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 86
    • Ver Perfil
Estoy viendo un metodo para cargar varias clases simultáneamente con PHP, estoy haciéndolo asi:

   
Código: [Seleccionar]
   spl_autoload_register(function($class){
            $class = str_replace("..", "", $class);
            require_once("validar/$class.php");
           
        });
   

   Así funciona perfectamente pero las clases están en el mismo directorio. A mi me gustaría que estuvieran en directorios distintos por el tema de orden. Estoy wampServer Windows y intento:

 
Código: [Seleccionar]
spl_autoload_register(function($class){
            $class = str_replace("..", "", $class);
            set_include_path('.;validar;entidades');//los dos directorios donde tengo los archivos
            require_once("validar/$class.php");
           
        });
 

  Pero me da error.
« Última modificación: 22 de Abril 2016, 22:21 por César Krall »

gatoher

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 86
    • Ver Perfil
Re:Cargar varias clases php con str_autoload_register
« Respuesta #1 en: 20 de Abril 2016, 12:38 »
   Encontre la solución pero a medias. A ver haciendolo asi funciona y carga las clases:

   
Código: [Seleccionar]
   spl_autoload_register(function($class){
            $class = str_replace("..", "", $class);
            set_include_path('.;validar;.;entidades');
            require_once("/$class.php");
            //throw new Exception("Imposible cargar $class.");
        });
 

    La excepcion esta comentada por que me salta. Tengo en una carpeta una clase validar y una interfaz llamada interfazValidar. La clase validar implementa esta interfaz. Cual puede ser el motivo si los dos archivos estan en el mismo directorio.

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Re:Cargar varias clases php con str_autoload_register
« Respuesta #2 en: 22 de Abril 2016, 22:20 »
Hola! Quizás te resulte útil este código que en teoría te permite rescatar todas las clases de todos los directorios a partir del raíz (recursivamente recorriendo todos los directorios a partir del especificado en $dir = '/path/to/project' ; )

Código: [Seleccionar]

   spl_autoload_register( 'autoload' );
 
 
  /**
   * autoload
   *
   * @author Joe Sexton
   * @param  string $class
   * @param  string $dir
   * @return bool
   */
  function autoload( $class, $dir = null ) {
 
    if ( is_null( $dir ) )
      $dir = '/path/to/project';
 
    foreach ( scandir( $dir ) as $file ) {
 
      // directory?
      if ( is_dir( $dir.$file ) && substr( $file, 0, 1 ) !== '.' )
        autoload( $class, $dir.$file.'/' );
 
      // php file?
      if ( substr( $file, 0, 2 ) !== '._' && preg_match( "/.php$/i" , $file ) ) {
 
        // filename matches class?
        if ( str_replace( '.php', '', $file ) == $class || str_replace( '.class.php', '', $file ) == $class ) {
 
            include $dir . $file;
        }
      }
    }
  }

Saludos!
Responsable de departamento de producción aprenderaprogramar.com

gatoher

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 86
    • Ver Perfil
   Hola Cesar, he estado viendo y probando y nada. No me funciona. Te paso un script de prueba que he hecho. La parte de saber si es un directorio la comprendo, pero la parte de buscar los archivos no. A ver:
   
Código: [Seleccionar]
if ( substr( $file, 0, 2 ) !== '._' && preg_match( "/.php$/i" , $file ) )
   

   La primera condición le substraes dos caracteres y compruebas que sea distinto de ('._'). Ese guión no se que hace. Y la segunda condición que buscas que empareje ("/.php$/i") No lo comprendo.

   Mira te pongo el script que he hecho de prueba para que lo veas:

   
Código: [Seleccionar]
   <body>
        <?php
    
    
         spl_autoload_register
'autoload' );

  function 
autoload$class$dir null ) {
      echo 
'la clase es. '.$class.'<br>';//para saber lo que recive
    
if ( is_null$dir ) ){
      
$dir 'C:\xampp\htdocs\Proyecto-Final';
    }
    
    foreach ( 
scandir$dir ) as $file ) {
 
      
// directory?
      
if ( is_dir$dir.$file ) && substr$file0) !== '.' )
     
//Esto lo he modificado ya que estoy hacienda las pruebas en wampServer Windows
        
autoload$class$dir.$file.'\\' );
 
      
// php file?
      
if ( substr$file0) !== '._' && preg_match"/.php$/i" $file ) ) {
 
        
// filename matches class?
        
if ( str_replace'.php'''$file ) == $class || str_replace'.class.php'''$file ) == $class ) {
 
            include 
$dir $file;
        }
      }
      
// throw new Exception('Imposible encontrar clase');
    
}
   
  }
  
  
/**
     * Creamos una clase que hereda
     * de la clase que nos va a permitir 
     * validar el formulario.
     */    
    
class prueba extends ValidoForm {
         public function 
__construct($a,$b){
         
parent::__construct($a,$b);
         } 
    }
  
  
//try{
     //Este script esta en la raiz del proyecto
     //$obj es un objeto de la clase prueba que extiende a la clase ValidaForm,
     //ValidaForm implementa la interfaz Interf_comprobar, Ambas estan en la ruta /validar/ValidoForm.php y /validar/Interf_comprobar.php
     
$obj = new prueba(array(), array());
     
//$objUsu; Objeto de la clase usuarios su ruta es: /entidades/Usuarios
     
$objUsu = new Usuarios();
//     }catch (Exceptio $e){
//        echo $e->getMessage()."\n"; 
//     }
        
?>

    </body>
 

   Me funciona correctamente.

   El metodo autoload lo tengo asi:

   
Código: [Seleccionar]


        spl_autoload_register(function($class){
            $class = str_replace("..", "", $class);
            set_include_path('.;validar;.;entidades');//aqui soluciono el problema
            require_once("/$class.php");
           // throw new Exception("Imposible cargar $class.");
        });

   
   

   Funciona perfectamente, pero como ves tengo comentado el lanzador de excepción. Si lo descomento me responde:

    Fatal error: Uncaught exception 'Exception' with message 'Imposible cargar Interf_comprobar.' in C:\xampp\htdocs\Proyecto-Final\index.php on line 44

   Lo que me extraña es que esa interfaz esta en el mismo directorio que la clase que la implementa  'ValidoForm', que es el constructor que tengo.

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Hola!

throw new Exception("Imposible cargar $class."); lo que hace es lanzar una excepción. Una excepción normalmente se lanza después de comprobar que algo no va bien, y esa comprobación se hace utilizando un if (condicional para detectar que hay una condición no válida, error o excepción). No veo que tengas un if antes del throw, entonces siempre te lanzará una excepción  ::)

Saludos!
Responsable de departamento de producción aprenderaprogramar.com

gatoher

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 86
    • Ver Perfil
   Hola Cesar,he estado unos días fuera por eso he respondido. Si a ver, ya he visto que falta el if, el copia y pega  :-\ .
   El error estaba que no había puesto el include_once en la clase validaForm.
   Muchas gracias

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".