Como incluir () todos os arquivos PHP de um diretório?

230

No PHP posso incluir um diretório de scripts?

Em vez de:

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

existe algo como:

include('classes/*');

Não foi possível encontrar uma boa maneira de incluir uma coleção de cerca de 10 subclasses para uma classe específica.

occhiso
fonte

Respostas:

437
foreach (glob("classes/*.php") as $filename)
{
    include $filename;
}
Karsten
fonte
4
Eu pensei que haveria uma maneira mais limpa usando include (). Mas isso vai dar certo. Obrigado a todos.
Occhiso 01/03/09
5
Eu criaria um sistema de módulo adequado com um arquivo de configuração, mas isso é apenas porque acho muito mais flexível do que apenas incluir tudo . :-)
staticsan 02/03/2009
3
Atenção, funciona apenas para incluir arquivos no diretório atual. Seria possível iterar através de get_include_path (), mas isso se torna tedioso rapidamente.
Nalply
20
Este método não é bom ao exigir classes que estão estendendo uma classe base: por exemplo, se BaseClass aparecer na matriz AFTER ExtendedClass, isso não funcionará!
Carmageddon
2
@nalply get_include_path()ainda não pode auto determinar a ordem de carregamento (classe de base pode ser carregado depois classe estendida, erros resultante)
rapina
50

Aqui está a maneira como incluo muitas classes de várias pastas no PHP 5. Isso só funcionará se você tiver aulas.

/*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;
        }
    }
}
Marius
fonte
3
O carregamento automático não é relevante porque esta pergunta consistia em incluir tudo em um diretório - normalmente isso seria em diretórios diferentes: por exemplo, DataClass definido no diretório BE e BL.class.php definido no diretório BL.
Carmageddon
1
Usando globals não é uma solução
Peter
Eu recomendaria usar o compositer ( getcomposer.org ) se você precisar de carregamento automático em vez de uma solução personalizada de carregamento automático, como o que é mostrado aqui.
Kelt
32

Sei que este é um post antigo, MAS ... NÃO INCLUI SUAS AULAS ... Em vez disso, use __autoload

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

$user = new User();

Então, sempre que você chamar uma nova classe que ainda não foi incluída, o php disparará __autoload automaticamente e incluirá para você

Proibição
fonte
1
Embora esta tenha sido uma resposta sólida quando foi publicada, a partir do PHP7.2.0 este método foi descontinuado e não deve ser usado. Em vez disso, use spl_autoload_register .
Frozenjakalope 13/08/1918
1
Essa é uma resposta muito melhor se o objetivo for incluir CLASSES.
Blackbam
20

isso é apenas uma modificação do código de Karsten

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

include_all_php("my_classes");
foobar
fonte
12
Isso não adiciona nada de relevante à resposta aceita.
moopet
obrigado, este foi o único código que realmente funcionou por algum motivo.
Joseph Astrahan
19

Como fazer isso em 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 pela documentação do PHP aqui: Carregamento automático de classes

Sorin C
fonte
Isso não responde a uma pergunta, porque autoloadentrará em jogo somente quando alguém tentar, ou seja, criar um objeto da classe que ainda não foi carregado.
The Godfather
1

Se você deseja incluir tudo em um diretório E seus subdiretórios:

$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;
}

Não esqueça que ele usará a ordem alfabética para incluir seus arquivos.

Matthieu Chavigny
fonte
3
"Não se esqueça que ele vai usar ordem alfabética" errado ... The entries are returned in the order in which they are stored by the filesystem.- php.net/manual/en/function.readdir.php
NemoStein
1
Isso pode não funcionar se os arquivos são dependentes uns dos outros e a ordem não corresponde à dependência
Amanuel Nega
1

Se você deseja incluir várias classes sem precisar definir cada classe de uma vez, você pode usar:

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

Dessa forma, você pode apenas definir a classe no arquivo php que contém a classe e não uma lista completa de $thisclass = new thisclass();

Quanto ao quão bem ele lida com todos os arquivos? Não tenho certeza se pode haver uma ligeira diminuição de velocidade com isso.

Scott Dawson
fonte
1

Se NÃO houver dependências entre arquivos ... aqui está uma função recursiva para incluir todos os arquivos php em todos os subdiretórios:

$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
fonte
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"); 
}
Mr. Genesis
fonte
Por favor, adicione um pouco mais de explicação ao seu código, especialmente porque esta questão já tem um monte de respostas upvoted
Nico Haase
0

Sugiro que você use uma função readdir () e faça um loop e inclua os arquivos (veja o 1º exemplo nessa página).

Stiropor
fonte
-1

Não escreva uma função () para incluir arquivos em um diretório. Você pode perder os escopos variáveis ​​e pode ter que usar "global". Apenas faça um loop nos arquivos.

Além disso, você pode ter dificuldades quando um arquivo incluído possui um nome de classe que será estendido para a outra classe definida no outro arquivo - que ainda não está incluído. Por isso tem cuidado.

bimal
fonte
2
O que você quer dizer com "perder os escopos variáveis"?
piyush 25/09/12
3
Você sempre deve usar uma função para reutilizar ou simplesmente tornar o código mais "auto-documentável". A questão do "escopo global" eu acho que é um arenque-vermelho. Sempre que você estiver usando o "escopo global", deseje pensar seriamente em reescrever seu código para evitá-lo.
quer