2010-09-07 9 views
0

c'est ma troisième question jusqu'à présent sur stackoverflow: Dà l'aide PHP.scandir() pour analyser les fichiers et les require_once

je suis en train de définir les fichiers et leur emplacement sur mes fichiers first_run.php, les fichiers i définir ici est les fichiers contenant des classes, des fonctions d'aide et tous les autres fichiers nécessaires

au début du développement, ce first_run.php ne contient que quelques lignes de codes mais la ligne augmente progressivement à mesure que j'ajouter de nouvelles classes ou de nouvelles fichiers à inclure

et puisque je grouper l'emplacement du fichier dans un dossier particulier, je me dis que je peux scanner le dossier, mettre le nom des fichiers récupérés dans un tableau puis boucler le require_once, de sorte que je n'ai pas besoin d'éditer first_run.php j'ajoute un nouveau fichier dans le dossier.

mon approche fisrt utilise scandir()

avant:

defined('INC_PATH') ? null : define('INC_PATH', SITE_ROOT.DS.'includes'); 
defined('MEMBERS') ? null : define('MEMBERS', INC_PATH.DS.'models'.DS.'members'); 

require_once(MEMBERS.DS.'member.php'); 
require_once(MEMBERS.DS.'phone.php'); 
require_once(MEMBERS.DS.'profile.php'); 
require_once(MEMBERS.DS.'talent.php'); 
require_once(MEMBERS.DS.'profile_picture.php'); 
require_once(MEMBERS.DS.'audio.php'); 
require_once(MEMBERS.DS.'video.php'); 
require_once(MEMBERS.DS.'gallery.php'); 
require_once(MEMBERS.DS.'statistik.php'); 
require_once(MEMBERS.DS.'inbox.php'); 
require_once(MEMBERS.DS.'comment.php'); 
require_once(MEMBERS.DS.'picked_stat.php'); 
require_once(MEMBERS.DS.'log.php'); 

après est quelque chose comme:

$member_files = scandir(MEMBERS); 
foreach($member_files as $member_file): 
    require_once(MEMBERS.DS.$member_file); 
endforeach; 

i nai essayer le 'après' code bien. est-ce possible? ou y a-t-il une autre approche? ou devrais-je simplement laisser cette façon (continuer à ajouter les lignes sans scanner les fichiers)

merci à l'avance

+0

Pour répondre à votre question, oui cela devrait fonctionner. Cela ne veut pas dire que vous devriez le faire. – NullUserException

+0

donc la meilleure pratique pour faire ceci est que je devrais m'en tenir à ce que je fais actuellement (éditant first_run.php si un nouveau fichier est créé) ?? – littlechad

+0

salut, ce n'est probablement pas les meilleures solutions. Que faire si vous avez des sous-dossiers qui ont plus de fichiers. J'ai dun avoir la solution complète avec moi maintenant (comme je suis au travail). mais si vous pouviez tenir un peu, je pourrais vous donner plus tard =) – nuttynibbles

Répondre

3

Pensez à utiliser Autoloading à la place.

Avec le chargement automatique, vous n'avez pas à vous soucier d'inclure des fichiers. Chaque fois que vous instanciez une nouvelle classe qui n'est pas connue de PHP à ce stade, PHP va déclencher la fonction de chargement automatique enregistré. La fonction inclut les fichiers requis ensuite. De cette façon, vous ne chargez que ce dont vous avez besoin quand vous en avez besoin, ce qui devrait augmenter les performances.

Exemple simple avec PHP5.3

spl_autoload_register(function($className) { 
    include "/path/to/lib/and/$className.php";  
}); 
$foo = new Foo; 

Lorsque vous appelez new Foo, la fonction de chargement automatique enregistrée essaiera d'inclure la classe de /path/to/lib/and/Foo.php. Il est conseillé d'utiliser une convention de nom de classe, comme f.i. PEAR, pour faciliter la recherche de fichiers et réduire la quantité de include_paths.

Pour plus de sécurité et de rapidité, vous pouvez fournir un sophisticated Autoloader that uses an array to map from classname to filename plus, s'assurant ainsi que seuls les fichiers qui font réellement partie de votre application peuvent être inclus.

Pour en savoir plus:

+0

en train de lire le manuel .... merci – littlechad

+0

lotta travail à domicile à faire, merci pour cette précieuse information – littlechad

1

Il est possible, mais pas recommandé, comme si quelqu'un pouvait créer un fichier php sur ce répertoire, vous allez finir par inclure, en plus, vous ne pouvez pas prédire l'ordre d'inclusion.

Essayez ceci:

$includes=array(
    'member', 
    'phone', 
    'profile', 
    'talent', 
); 

foreach($includes as $fname) { 
    require_once(MEMBERS.DS.$fname. '.php'); 

} 

Si vous utilisez des classes, envisagez d'utiliser autoloading, comme @Gordon suggéré. Et si vous n'utilisez pas les classes, pensez à les utiliser :)

+0

+1 sur l'incapacité de prédire l'ordre d'inclusion. – janosrusiczki

+0

même question posée à @NullUserException; donc la meilleure pratique pour faire ceci est que je devrais m'en tenir à ce que je fais actuellement (éditant first_run.php si un nouveau fichier est créé) ?? – littlechad

+0

Si ces fichiers contiennent des classes, le meilleur moyen est d'utiliser le chargement automatique, si certains d'entre eux contiennent des paramètres ou des classes de base (ceux qui sont _always_ used). Je crois que le code que vous avez posté est le meilleur moyen, la façon dont j'ai posté minimiser le code et rend un peu plus rapide d'ajouter un nouveau fichier d'inclusion, pour démontrer comment une telle chose peut être faite, mais ce n'est pas mieux :) – aularon

0

À première vue, votre code pourrait fonctionner, même si vous devez ignorer "." et ".." dans la boucle foreach. De plus, je voudrais vérifier, si le fichier se termine par ".php":

$member_files = scandir(MEMBERS.DS); 
foreach($member_files as $member_file) { 
    // Ignore non php files and thus ".." & "." 
    if (!preg_match('/\.php$/', $member_file) { 
     continue; 
    } 
    require_once(MEMBERS.DS.$member_file); 
} 
0

créer 2 fonctions

function GetFiles($directory,$exempt = array('.','..','.ds_store','.svn'),&$files = array()) { 
    $handle = opendir($directory); 
    while(false !== ($resource = readdir($handle))){ 
     if(!in_array(strtolower($resource),$exempt)){ 
      if(is_dir($directory.$resource.'/')) 
       array_merge($files, self::GetFiles($directory.$resource.'/',$exempt,$files)); 
      else 
       $files[] = $directory.$resource; 
     } 
    } 
    closedir($handle); 
    return $files; 
    } 


    function Autoload($includes = array()){ 
    $files = array(); 
    foreach($includes as $directory) 
     $files[] = self::GetFiles($directory); 

    foreach($files as $k=>$v){ 
     foreach($v as $k1=>$v1) 
     require_once($v1); 
    } 
    } 

to use it: 
$includes = array(
    'C:WWW/project/helpers/', 
    'C:WWW/project/lang/', 
    'C:WWW/project/lib/', 
    'C:WWW/project/mod/', 
); 
Autoload($includes);