Wie kann ich () alle PHP-Dateien aus einem Verzeichnis einschließen?

230

Kann ich in PHP ein Verzeichnis von Skripten einfügen?

dh anstelle von:

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

gibt es so etwas wie:

include('classes/*');

Es scheint keinen guten Weg zu finden, eine Sammlung von ungefähr 10 Unterklassen für eine bestimmte Klasse aufzunehmen.

occhiso
quelle

Antworten:

437
foreach (glob("classes/*.php") as $filename)
{
    include $filename;
}
Karsten
quelle
4
Ich dachte, mit include () würde es sauberer aussehen. Aber das wird gut gehen. Vielen Dank an alle.
occhiso
5
Ich würde ein richtiges Modulsystem mit einer Konfigurationsdatei erstellen, aber das liegt nur daran, dass ich das viel flexibler finde, als nur alles einzuschließen . :-)
staticsan
3
Achtung, funktioniert nur zum Einfügen von Dateien in das aktuelle Verzeichnis. Es wäre möglich, get_include_path () zu durchlaufen, aber dies wird schnell langweilig.
Nalply
20
Diese Methode ist nicht gut, wenn Klassen erforderlich sind, die eine Basisklasse erweitern: Wenn BaseClass beispielsweise NACH ExtendedClass im Array angezeigt wird, funktioniert sie nicht!
Carmageddon
2
@nalply get_include_path()kann die Ladereihenfolge immer noch nicht automatisch bestimmen (Basisklasse kann NACH erweiterter Klasse geladen werden, was zu Fehlern führt)
Raptor
50

Hier ist die Art und Weise, wie ich viele Klassen aus mehreren Ordnern in PHP 5 einbinde. Dies funktioniert jedoch nur, wenn Sie Klassen haben.

/*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
quelle
3
Autoload ist nicht relevant, da es bei dieser Frage darum ging, alles in ein Verzeichnis aufzunehmen - normalerweise in verschiedenen Verzeichnissen: z. B. DataClass im BE-Verzeichnis und BL.class.php im BL-Verzeichnis.
Carmageddon
1
Die Verwendung von Globals ist keine Lösung
Peter
Ich würde empfehlen, Composer ( getcomposer.org ) zu verwenden, wenn Sie ein automatisches Laden anstelle einer angepassten automatischen Ladelösung wie der hier gezeigten benötigen.
Kelt
32

Mir ist klar, dass dies ein älterer Beitrag ist, ABER ... BEINHALTEN SIE IHRE KLASSEN NICHT ... verwenden Sie stattdessen __autoload

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

$user = new User();

Wenn Sie dann eine neue Klasse aufrufen, die noch nicht enthalten ist, wird PHP automatisch __autoload auslösen und für Sie einschließen

Verbot
quelle
1
Während dies eine solide Antwort war, als es veröffentlicht wurde, war diese Methode ab PHP7.2.0 veraltet und sollte nicht verwendet werden. Verwenden Sie stattdessen spl_autoload_register .
Frozenjakalope
1
Dies ist eine viel bessere Antwort, wenn der Zweck darin besteht, KLASSEN einzuschließen.
Blackbam
20

Wenn Sie PHP 5 verwenden, möchten Sie möglicherweise stattdessen Autoload verwenden.

SorinV
quelle
20

Dies ist nur eine Modifikation von Karstens Code

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

include_all_php("my_classes");
foobar
quelle
12
Dies fügt der akzeptierten Antwort nichts Relevantes hinzu.
Moopet
Danke, dies war der einzige Code, der aus irgendeinem Grund tatsächlich funktionierte.
Joseph Astrahan
19

Wie das 2017 geht:

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

Empfohlen von der PHP-Dokumentation hier: Autoloading-Klassen

Sorin C.
quelle
Dies beantwortet keine Frage, da autoloades nur dann ins Spiel kommt, wenn jemand versucht, dh ein Objekt der Klasse zu erstellen, das noch nicht geladen wurde.
Der Pate
1

Wenn Sie alle in ein Verzeichnis UND seine Unterverzeichnisse aufnehmen möchten:

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

Vergessen Sie nicht, dass Ihre Dateien in alphabetischer Reihenfolge angezeigt werden.

Matthieu Chavigny
quelle
3
"Vergessen Sie nicht, dass es alphabetische Reihenfolge verwenden wird" Falsch ... The entries are returned in the order in which they are stored by the filesystem.- php.net/manual/en/function.readdir.php
NemoStein
1
Dies funktioniert möglicherweise nicht, wenn die Dateien voneinander abhängig sind und die Reihenfolge nicht mit der Abhängigkeit übereinstimmt
Amanuel Nega
1

Wenn Sie eine Reihe von Klassen einschließen möchten, ohne jede Klasse gleichzeitig definieren zu müssen, können Sie Folgendes verwenden:

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

Auf diese Weise können Sie einfach die Klasse in der PHP-Datei definieren, die die Klasse enthält, und nicht eine ganze Liste von $thisclass = new thisclass();

Wie gut werden alle Dateien verarbeitet? Ich bin mir nicht sicher, ob dies zu einem leichten Geschwindigkeitsabfall führen könnte.

Scott Dawson
quelle
1

Wenn es KEINE Abhängigkeiten zwischen Dateien gibt ... ist hier eine rekursive Funktion, um ALLE PHP-Dateien in ALLE Unterverzeichnisse einzuschließen:

$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
quelle
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
quelle
Bitte fügen Sie Ihrem Code weitere Erklärungen hinzu, zumal diese Frage bereits viele positive Antworten enthält
Nico Haase,
0

Ich schlage vor, dass Sie eine readdir () -Funktion verwenden und dann die Dateien schleifen und einschließen (siehe das erste Beispiel auf dieser Seite).

Stiropor
quelle
-1

Schreiben Sie keine Funktion (), um Dateien in ein Verzeichnis aufzunehmen. Möglicherweise verlieren Sie die variablen Bereiche und müssen möglicherweise "global" verwenden. Schleifen Sie einfach die Dateien.

Außerdem können Probleme auftreten, wenn eine eingeschlossene Datei einen Klassennamen hat, der sich auf die andere Klasse erstreckt, die in der anderen Datei definiert ist - die noch nicht enthalten ist. Also sei vorsichtig.

bimal
quelle
2
Was meinst du mit "die variablen Bereiche verlieren"?
Piyush
3
Sie sollten immer eine Funktion verwenden, wenn Sie sie wiederverwenden oder den Code einfach "selbstdokumentierender" machen möchten. Das Thema "globaler Geltungsbereich" ist meines Erachtens ein roter Hering. Jedes Mal, wenn Sie "globalen Bereich" verwenden, möchten Sie ernsthaft darüber nachdenken, Ihren Code neu zu schreiben, um dies zu vermeiden.
Stab Escura