Comment inclure () tous les fichiers PHP d'un répertoire?

230

En PHP, puis-je inclure un répertoire de scripts?

c'est-à-dire au lieu de:

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

y a-t-il quelque chose comme:

include('classes/*');

Impossible de trouver un bon moyen d'inclure une collection d'environ 10 sous-classes pour une classe particulière.

occhiso
la source

Réponses:

437
foreach (glob("classes/*.php") as $filename)
{
    include $filename;
}
Karsten
la source
4
Je pensais qu'il y aurait une façon plus nette d'utiliser include (). Mais cela fera très bien l'affaire. Merci tout le monde.
occhiso
5
Je construirais un système de modules approprié avec un fichier de configuration, mais c'est simplement parce que je trouve cela beaucoup plus flexible que de simplement tout inclure . :-)
staticsan
3
Attention, ne fonctionne que pour inclure des fichiers dans le répertoire courant. Il serait possible d'itérer via get_include_path (), mais cela devient rapidement fastidieux.
2011
20
Cette méthode n'est pas bonne lorsque vous avez besoin de classes qui étendent une classe de base: par exemple, si BaseClass apparaît dans le tableau APRÈS ExtendedClass, cela ne fonctionnera pas!
Carmageddon
2
@nalply get_include_path()ne peut toujours pas déterminer automatiquement l'ordre de chargement (la classe de base peut être chargée APRÈS la classe étendue, les erreurs en résultant)
Raptor
50

Voici la façon dont j'inclus beaucoup de classes de plusieurs dossiers dans PHP 5. Cela ne fonctionnera que si vous avez des classes.

/*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
la source
3
Le chargement automatique n'est pas pertinent car cette question portait sur l'inclusion de tout dans un répertoire - généralement ce serait dans différents répertoires: par exemple DataClass défini dans le répertoire BE et BL.class.php défini dans le répertoire BL.
Carmageddon
1
Utiliser les globaux n'est pas une solution
Peter
Je conseillerais d'utiliser Composer ( getcomposer.org ) si vous avez besoin du chargement automatique au lieu d'une solution de chargement automatique personnalisée comme celle présentée ici.
Kelt
32

Je me rends compte que c'est un article plus ancien MAIS ... N'INCLUREZ PAS VOS COURS ... utilisez plutôt __autoload

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

$user = new User();

Ensuite, chaque fois que vous appelez une nouvelle classe qui n'a pas encore été incluse, php lance automatiquement __autoload et l'inclut pour vous

Interdiction
la source
1
Bien que ce fut une réponse solide lors de sa publication, à partir de PHP7.2.0, cette méthode est obsolète et ne devrait pas être utilisée. Utilisez plutôt spl_autoload_register .
freezjakalope
1
C'est une meilleure réponse si le but est d'inclure des CLASSES.
Blackbam
20

ce n'est qu'une modification du code de Karsten

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

include_all_php("my_classes");
foobar
la source
12
Cela n'ajoute rien de pertinent à la réponse acceptée.
moopet
merci, c'était le seul code qui fonctionnait réellement pour une raison quelconque.
Joseph Astrahan
19

Comment faire cela 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
} );

Recommandé par la documentation PHP ici: Classes de chargement automatique

Sorin C
la source
Cela ne répond pas à une question, car autoloadn'entrera en jeu que lorsque quelqu'un essaiera de créer un objet de la classe qui n'a pas encore été chargé.
The Godfather
1

Si vous souhaitez inclure tout dans un répertoire ET ses sous-répertoires:

$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'oubliez pas qu'il utilisera l'ordre alphabétique pour inclure vos fichiers.

Matthieu Chavigny
la source
3
"N'oubliez pas qu'il utilisera l'ordre alphabétique" Faux ... The entries are returned in the order in which they are stored by the filesystem.- php.net/manual/en/function.readdir.php
NemoStein
1
Cela pourrait ne pas fonctionner si les fichiers dépendent les uns des autres et que l'ordre ne correspond pas à la dépendance
Amanuel Nega
1

Si vous cherchez à inclure un tas de classes sans avoir à définir chaque classe à la fois, vous pouvez utiliser:

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

De cette façon, vous pouvez simplement définir la classe sur le fichier php contenant la classe et non une liste complète de $thisclass = new thisclass();

Quant à la façon dont il gère tous les fichiers? Je ne suis pas sûr qu'il puisse y avoir une légère diminution de la vitesse avec cela.

Scott Dawson
la source
1

S'il n'y a PAS de dépendances entre les fichiers ... voici une fonction récursive pour inclure_once TOUS les fichiers php dans TOUS les sous-répertoires:

$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
la source
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"); 
}
M. Genesis
la source
Veuillez ajouter plus d'explications à votre code, d'autant plus que cette question a déjà beaucoup de réponses votées
Nico Haase
0

Je vous suggère d'utiliser une fonction readdir () puis de boucler et d'inclure les fichiers (voir le 1er exemple sur cette page).

Stiropor
la source
-1

N'écrivez pas de fonction () pour inclure des fichiers dans un répertoire. Vous risquez de perdre les portées variables et devrez peut-être utiliser «global». Bouclez simplement les fichiers.

En outre, vous pouvez rencontrer des difficultés lorsqu'un fichier inclus a un nom de classe qui s'étendra à l'autre classe définie dans l'autre fichier - qui n'est pas encore inclus. Donc sois prudent.

bimal
la source
2
Qu'entendez-vous par «perdre les portées variables»?
piyush
3
Vous devez toujours utiliser une fonction si vous comptez réutiliser, ou tout simplement pour rendre le code plus "auto-documenté". La question de la "portée mondiale" est, je pense, un sujet redoutable. Chaque fois que vous utilisez la «portée globale», vous voulez sérieusement penser à réécrire votre code pour l'éviter.
Stave Escura