Come includere () tutti i file PHP da una directory?


230

In PHP posso includere una directory di script?

cioè invece di:

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

c'è qualcosa come:

include('classes/*');

Non è riuscito a trovare un buon modo per includere una raccolta di circa 10 sottoclassi per una determinata classe.

Risposte:


437
foreach (glob("classes/*.php") as $filename)
{
    include $filename;
}

4
Ho pensato che ci sarebbe stato un modo più pulito usando include (). Ma questo andrà bene. Grazie a tutti.
occhiso

5
Costruirò un sistema di moduli adeguato con un file di configurazione, ma è solo perché lo trovo molto più flessibile che includere semplicemente tutto . :-)
staticsan

3
Attenzione, funziona solo per includere file nella directory corrente. Sarebbe possibile iterare attraverso get_include_path (), ma questo diventa noioso rapidamente.
nalply

20
Questo metodo non è utile quando si richiedono classi che estendono una classe base: ad es. Se BaseClass si presenta nell'array DOPO ExtendedClass, non funzionerà!
Carmageddon,

2
@nalply get_include_path()non riesce ancora a determinare automaticamente l'ordine di caricamento (la classe base può essere caricata DOPO la classe estesa, con conseguenti errori)
Raptor

50

Ecco il modo in cui includo molte classi da diverse cartelle in PHP 5. Questo funzionerà solo se hai delle classi.

/*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;
        }
    }
}

3
Il caricamento automatico non è pertinente perché questa domanda riguardava l'inclusione di tutto in una directory, in genere si troverebbe in directory diverse: ad es. DataClass definita nella directory BE e BL.class.php definita nella directory BL.
Carmageddon,

1
L'uso dei globi non è una soluzione
Peter,

Vorrei consigliare l'utilizzo di compositore ( getcomposer.org ) se è necessario il caricamento automatico anziché una soluzione di caricamento automatico personalizzata come quella mostrata qui.
Kelt

32

Mi rendo conto che questo è un post più vecchio MA ... NON INCLUDERE LE TUE CLASSI ... invece usa __autoload

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

$user = new User();

Quindi ogni volta che chiami una nuova classe che non è stata ancora inclusa, php genererà automaticamente __autoload e lo includerà per te


1
Mentre questa è stata una risposta solida quando è stato pubblicato, a partire da PHP7.2.0 questo metodo è stato deprecato e non dovrebbe essere usato. Utilizzare invece spl_autoload_register .
frozenjakalope,

1
Questa è una risposta migliore se lo scopo è includere le CLASSI.
Blackbam,


20

questa è solo una modifica del codice di Karsten

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

include_all_php("my_classes");

12
Questo non aggiunge nulla di rilevante alla risposta accettata.
Moopet,

grazie, questo è stato l'unico codice che ha funzionato per qualche motivo.
Joseph Astrahan,

19

Come fare questo nel 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
} );

Consigliato dalla documentazione PHP qui: Classi di caricamento automatico


Questo non risponde a una domanda, perché autoloadentrerà in gioco solo quando qualcuno prova ad esempio a creare un oggetto della classe che non è stato ancora caricato.
The Godfather


1

Se vuoi includere tutto in una directory E nelle sue sottodirectory:

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

Non dimenticare che utilizzerà l'ordine alfabetico per includere i tuoi file.


3
"Non dimenticate che userà ordine alfabetico" Sbagliato ... The entries are returned in the order in which they are stored by the filesystem.- php.net/manual/en/function.readdir.php
NemoStein

1
Questo potrebbe non funzionare se i file sono dipendenti l'uno dall'altro e l'ordine non corrisponde alla dipendenza
Amanuel Nega,

1

Se stai cercando di includere un gruppo di classi senza dover definire ciascuna classe contemporaneamente puoi utilizzare:

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

In questo modo puoi semplicemente definire la classe sul file php contenente la classe e non un intero elenco di $thisclass = new thisclass();

Quanto bene gestisce tutti i file? Non sono sicuro che potrebbe esserci una leggera riduzione della velocità con questo.


1

Se non ci sono dipendenze tra i file ... ecco una funzione ricorsiva per includere_una volta TUTTI i file php in TUTTI i sottodir:

$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');

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"); 
}

Per favore, aggiungi qualche spiegazione in più al tuo codice, specialmente perché questa domanda ha già molte risposte votate
Nico Haase,


-1

Non scrivere una funzione () per includere i file in una directory. È possibile perdere gli ambiti variabili e potrebbe essere necessario utilizzare "globale". Basta passare in rassegna i file.

Inoltre, potresti riscontrare difficoltà quando un file incluso ha un nome di classe che si estenderà all'altra classe definita nell'altro file, che non è ancora inclusa. Perciò stai attento.


2
Cosa intendi con "perdere gli ambiti variabili"?
Piyush,

3
Dovresti sempre usare una funzione se stai per riutilizzare, o semplicemente per rendere il codice più "auto-documentante". Il problema di "portata globale" penso che sia un'aringa rossa. Ogni volta che si utilizza "ambito globale", si vuole pensare seriamente alla riscrittura del codice per evitarlo.
Stave Escura,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.