¿Cómo incluir () todos los archivos PHP de un directorio?

230

¿En PHP puedo incluir un directorio de scripts?

es decir, en lugar de:

include('classes/Class1.php');
include('classes/Class2.php');

hay algo como:

include('classes/*');

Parece que no puede encontrar una buena manera de incluir una colección de aproximadamente 10 subclases para una clase en particular.

occhiso
fuente

Respuestas:

437
foreach (glob("classes/*.php") as $filename)
{
    include $filename;
}
Karsten
fuente
44
Pensé que habría una forma más limpia de usar include (). Pero esto funcionará bien. Gracias a todos.
occhiso
55
Construiría un sistema de módulos adecuado con un archivo de configuración, pero eso es solo porque me parece mucho más flexible que simplemente incluir todo . :-)
staticsan 02 de
3
Atención, solo funciona para incluir archivos en el directorio actual. Sería posible iterar a través de get_include_path (), pero esto se vuelve tedioso rápidamente.
2011
20
Este método no es bueno cuando se requieren clases que extienden una clase base: por ejemplo, si BaseClass aparece en la matriz DESPUÉS de ExtendedClass, ¡no funcionará!
Carmageddon
2
@nalply get_include_path()todavía no puede determinar automáticamente el orden de carga (la clase base se puede cargar DESPUÉS de la clase extendida, errores resultantes)
Raptor
50

Esta es la forma en que incluyo muchas clases de varias carpetas en PHP 5. Sin embargo, esto solo funcionará si tiene clases.

/*Directories that contain classes*/
$classesDir = array (
    ROOT_DIR.'classes/',
    ROOT_DIR.'firephp/',
    ROOT_DIR.'includes/'
);
function __autoload($class_name) {
    global $classesDir;
    foreach ($classesDir as $directory) {
        if (file_exists($directory . $class_name . '.php')) {
            require_once ($directory . $class_name . '.php');
            return;
        }
    }
}
Mario
fuente
3
La carga automática no es relevante porque esta pregunta se refería a incluir todo en un directorio; por lo general, esto estaría en diferentes directorios: por ejemplo, DataClass definido en el directorio BE y BL.class.php definido en el directorio BL.
Carmageddon
1
Usar globals no es una solución
Peter
Aconsejaría usar composer ( getcomposer.org ) si necesita carga automática en lugar de una solución de carga automática personalizada como la que se muestra aquí.
Kelt
32

Me doy cuenta de que esta es una publicación anterior PERO ... NO INCLUYA TUS CLASES ... en su lugar usa __autoload

function __autoload($class_name) {
    require_once('classes/'.$class_name.'.class.php');
}

$user = new User();

Luego, cada vez que llame a una nueva clase que aún no se haya incluido, php activará automáticamente __autoload y lo incluirá por usted

Prohibición
fuente
1
Si bien esta fue una respuesta sólida cuando se publicó, a partir de PHP7.2.0, este método ha quedado en desuso y no debe usarse. En su lugar, use spl_autoload_register .
frozenjakalope
1
Esta es una respuesta mucho mejor si el propósito es incluir CLASES.
Blackbam el
20

esto es solo una modificación del código de Karsten

function include_all_php($folder){
    foreach (glob("{$folder}/*.php") as $filename)
    {
        include $filename;
    }
}

include_all_php("my_classes");
foobar
fuente
12
Esto no agrega nada relevante a la respuesta aceptada.
moopet
Gracias, este fue el único código que realmente funcionó por alguna razón.
Joseph Astrahan
19

Cómo hacer esto en 2017:

spl_autoload_register( function ($class_name) {
    $CLASSES_DIR = __DIR__ . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR;  // or whatever your directory is
    $file = $CLASSES_DIR . $class_name . '.php';
    if( file_exists( $file ) ) include $file;  // only include if file exists, otherwise we might enter some conflicts with other pieces of code which are also using the spl_autoload_register function
} );

Recomendado por la documentación de PHP aquí: clases de carga automática

Sorin C
fuente
Esto no responde una pregunta, porque autoloadentrará en juego solo cuando alguien intente, es decir, crear un objeto de la clase que aún no se haya cargado.
El padrino
1

Si desea incluir todo en un directorio Y sus subdirectorios:

$dir = "classes/";
$dh  = opendir($dir);
$dir_list = array($dir);
while (false !== ($filename = readdir($dh))) {
    if($filename!="."&&$filename!=".."&&is_dir($dir.$filename))
        array_push($dir_list, $dir.$filename."/");
}
foreach ($dir_list as $dir) {
    foreach (glob($dir."*.php") as $filename)
        require_once $filename;
}

No olvide que usará el orden alfabético para incluir sus archivos.

Matthieu Chavigny
fuente
3
"No olvides que usará el orden alfabético" Incorrecto ... The entries are returned in the order in which they are stored by the filesystem.- php.net/manual/en/function.readdir.php
NemoStein
1
Esto podría no funcionar si los archivos dependen unos de otros y el orden no coincide con la dependencia
Amanuel Nega
1

Si desea incluir un grupo de clases sin tener que definir cada clase a la vez, puede usar:

$directories = array(
            'system/',
            'system/db/',
            'system/common/'
);
foreach ($directories as $directory) {
    foreach(glob($directory . "*.php") as $class) {
        include_once $class;
    }
}

De esta manera, puede definir la clase en el archivo php que contiene la clase y no una lista completa de $thisclass = new thisclass();

¿En cuanto a qué tan bien maneja todos los archivos? No estoy seguro de que pueda haber una ligera disminución de la velocidad con esto.

Scott Dawson
fuente
1

Si NO hay dependencias entre archivos ... aquí hay una función recursiva para incluir_una vez TODOS los archivos php en TODOS los subdirectorios:

$paths = array();

function include_recursive( $path, $debug=false){
  foreach( glob( "$path/*") as $filename){        
    if( strpos( $filename, '.php') !== FALSE){ 
       # php files:
       include_once $filename;
       if( $debug) echo "<!-- included: $filename -->\n";
    } else { # dirs
       $paths[] = $filename; 
    }
  }
  # Time to process the dirs:
  for( $i=count($paths)-1; $i>0; $i--){
    $path = $paths[$i];
    unset( $paths[$i]);
    include_recursive( $path);
  }
}

include_recursive( "tree_to_include");
# or... to view debug in page source:
include_recursive( "tree_to_include", 'debug');
Sergio Abreu
fuente
1
<?php
//Loading all php files into of functions/ folder 

$folder =   "./functions/"; 
$files = glob($folder."*.php"); // return array files

 foreach($files as $phpFile){   
     require_once("$phpFile"); 
}
Señor Génesis
fuente
Agregue alguna explicación más a su código, especialmente porque esta pregunta ya tiene muchas respuestas votadas
Nico Haase
0

Le sugiero que use una función readdir () y luego repita e incluya los archivos (vea el primer ejemplo en esa página).

Stiropor
fuente
-1

No escriba una función () para incluir archivos en un directorio. Puede perder los ámbitos variables y puede que tenga que usar "global". Simplemente bucle en los archivos.

Además, puede tener dificultades cuando un archivo incluido tiene un nombre de clase que se extenderá a la otra clase definida en el otro archivo, que aún no está incluido. Así que ten cuidado.

bimal
fuente
2
¿Qué quiere decir con "perder los ámbitos variables"?
piyush
3
Siempre debe usar una función si va a reutilizar, o simplemente para hacer que el código sea más "autodocumentado". La cuestión del "alcance global", creo, es una pista falsa. Cada vez que utilice el "alcance global", debe pensar seriamente en reescribir su código para evitarlo.
Stave Escura