Jak dołączyć () wszystkie pliki PHP z katalogu?

230

Czy w PHP mogę dołączyć katalog skryptów?

tj. zamiast:

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

czy jest coś takiego:

include('classes/*');

Nie można znaleźć dobrego sposobu na włączenie kolekcji około 10 podklas dla konkretnej klasy.

occhiso
źródło

Odpowiedzi:

437
foreach (glob("classes/*.php") as $filename)
{
    include $filename;
}
Karsten
źródło
4
Pomyślałem, że można użyć bardziej przejrzystego sposobu za pomocą include (). Ale to wystarczy. Dziękuję wszystkim.
occhiso
5
Zbudowałbym odpowiedni system modułowy z plikiem konfiguracyjnym, ale dzieje się tak tylko dlatego, że uważam to za znacznie bardziej elastyczne niż tylko dołączanie wszystkiego . :-)
staticsan
3
Uwaga, działa tylko w przypadku dołączania plików do bieżącego katalogu. Możliwe byłoby iterowanie przez get_include_path (), ale szybko się to nudzi.
dokładnie
20
Ta metoda nie jest dobra, gdy wymaga się klas rozszerzających klasę podstawową: np. Jeśli BaseClass pojawi się w tablicy PO ExtendedClass, to nie zadziała!
Carmageddon
2
@nalply get_include_path()nadal nie może automatycznie określić kolejność załadunku (klasa bazowa może być załadowany po dłuższym klasy, w wyniku błędów)
Raptor
50

Oto sposób, w jaki dołączam wiele klas z kilku folderów w PHP 5. To zadziała tylko, jeśli masz klasy.

/*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
źródło
3
Automatyczne ładowanie nie ma znaczenia, ponieważ pytanie dotyczyło włączenia wszystkiego do katalogu - zwykle byłoby to w różnych katalogach: np. DataClass zdefiniowana w katalogu BE i BL.class.php zdefiniowana w katalogu BL.
Carmageddon
1
Używanie globałów nie jest rozwiązaniem
Peter
Radziłbym użyć kompozytora ( getcomposer.org ), jeśli potrzebujesz automatycznego ładowania zamiast niestandardowego rozwiązania automatycznego ładowania, takiego jak to pokazano tutaj.
Kelt
32

Zdaję sobie sprawę, że jest to starszy post ALE ... NIE ZAWIERAJ SWOICH ZAJĘĆ ... zamiast tego użyj __autoload

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

$user = new User();

Wtedy za każdym razem, gdy wywołasz nową klasę, która nie została jeszcze uwzględniona, php automatycznie uruchomi __autoload i załączy ją dla ciebie

Banowanie
źródło
1
Chociaż była to solidna odpowiedź, kiedy została opublikowana, od PHP7.2.0 metoda ta jest przestarzała i nie należy jej używać. Zamiast tego użyj spl_autoload_register .
frozenjakalope
1
Jest to zdecydowanie lepsza odpowiedź, jeśli celem jest uwzględnienie ZAJĘĆ.
Blackbam
20

to tylko modyfikacja kodu Karstena

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

include_all_php("my_classes");
foobar
źródło
12
To nie dodaje nic istotnego do zaakceptowanej odpowiedzi.
moopet
dzięki, to był jedyny kod, który faktycznie działał z jakiegoś powodu.
Joseph Astrahan
19

Jak to zrobić w 2017 roku:

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

Zalecane w dokumentacji PHP tutaj: Klasy autoloadingu

Sorin C.
źródło
To nie odpowiada na pytanie, ponieważ autoloadwejdzie do gry tylko wtedy, gdy ktoś spróbuje np. Stworzyć obiekt klasy, który nie został jeszcze załadowany.
Ojciec chrzestny
1

Jeśli chcesz uwzględnić wszystko w katalogu ORAZ jego podkatalogach:

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

Nie zapominaj, że użyje kolejności alfabetycznej, aby dołączyć twoje pliki.

Matthieu Chavigny
źródło
3
„Nie zapominaj, że użyje kolejności alfabetycznej” Źle ... The entries are returned in the order in which they are stored by the filesystem.- php.net/manual/en/function.readdir.php
NemoStein
1
Może to nie działać, jeśli pliki są od siebie zależne, a kolejność nie pasuje do zależności
Amanuel Nega
1

Jeśli chcesz dołączyć kilka klas bez konieczności definiowania każdej klasy na raz, możesz użyć:

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

W ten sposób możesz po prostu zdefiniować klasę w pliku php zawierającym klasę, a nie całą listę $thisclass = new thisclass();

Co do tego, jak dobrze obsługuje wszystkie pliki? Nie jestem pewien, czy może to spowodować nieznaczne zmniejszenie prędkości.

Scott Dawson
źródło
1

Jeśli nie ma żadnych zależności między plikami ... oto funkcja rekurencyjna, aby dołączyć WSZYSTKIE pliki php we WSZYSTKICH podkatalogach:

$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
źródło
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"); 
}
Pan Genesis
źródło
Dodaj więcej wyjaśnień do swojego kodu, zwłaszcza że to pytanie ma już wiele pozytywnych odpowiedzi
Nico Haase
0

Sugeruję użycie funkcji readdir (), a następnie zapętlenie i dołączenie plików (patrz 1. przykład na tej stronie).

Stiropor
źródło
-1

Nie pisz funkcji () w celu dołączenia plików do katalogu. Możesz utracić zakresy zmiennych i być może będziesz musiał użyć „globalnego”. Wystarczy zapętlić pliki.

Możesz również napotkać trudności, gdy dołączony plik ma nazwę klasy, która będzie rozciągać się na inną klasę zdefiniowaną w innym pliku - która nie jest jeszcze uwzględniona. Więc uważaj.

bimal
źródło
2
Co rozumiesz przez „utratę zakresów zmiennych”?
piyush
3
Powinieneś zawsze używać funkcji, jeśli zamierzasz ponownie użyć lub po prostu uczynić kod bardziej „samodokumentującym”. Wydaje mi się, że kwestia „zasięgu globalnego” to śledź czerwony. Za każdym razem, gdy używasz „zakresu globalnego”, poważnie zastanów się nad przepisaniem kodu, aby go uniknąć.
Stave Escura,