2009-09-17 6 views
2

Je prévois d'utiliser la fonction de chargement automatique de PHP pour charger de façon dynamique uniquement les fichiers de classe nécessaires. Maintenant, cela pourrait créer un énorme gâchis si chaque fonction a un fichier séparé, donc je suis en espérant et demander est-il un moyen d'avoir des classes liées restent dans 1 fichier de classe et être encore chargés automatiquement-Comment charger automatiquement des classes étendues?

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

Disons que il y a un nom de classe animaux et une autre classe nommée chiens. La classe des chiens étend la classe des animaux, maintenant si je devais appeler la classe des chiens mais pas appeler la classe des animaux, le fichier de classe des animaux serait-il encore chargé?

+0

Je vous recommande de regarder également les normes de codage Pear/Zend pour les conventions de nommage de fichiers comme fournir de bonnes directives. À mon humble avis, en utilisant .class.php dans le nom de fichier est redondant et non encouragé. Vous pouvez auto-charger en utilisant quelque chose comme: require (str_replace ('_', DIRECTORY_SEPARATOR, $ className), pour le rendre facile et organisé – Tres

+0

BTW, ayant plusieurs classes par fichier n'est généralement pas considéré comme une bonne pratique pour la maintenabilité du code – Tres

+0

Haha, désolé A propos de tous les commentaires mais fyi, ma ligne "require" ci-dessus n'est pas correcte, elle devrait être: require (str_replace ('_', DIRECTORY_SEPARATOR, $ className). '.php'); – Tres

Répondre

5

si je devais appeler la classe des chiens mais appelez pas la classe des animaux, serait le fichier de classe animaux toujours chargé?

Oui. Lorsque vous chargez une classe qui étend une autre classe, PHP doit charger la classe de base afin qu'elle sache ce qu'elle étend. Re: l'idée de stocker plusieurs classes par fichier: Cela ne fonctionnera pas avec la fonction de chargement automatique que vous avez fournie. Une classe par fichier est vraiment la meilleure pratique, en particulier pour les classes autoloaded.

Si vous avez plus d'une classe dans un fichier, vous ne devriez pas essayer de charger automatiquement les classes de ce fichier.

0

Oui, il va charger à moins que vous n'incluez pas/require le fichier de classe.

Vous devez toujours importer tous les fichiers contenant le code PHP nécessaire. PHP lui-même ne peut pas deviner le nom que vous avez donné à votre fichier de classe. Contrairement à Java par exemple, PHP n'a pas d'exigence de nommage de fichiers pour les classes.

La manière courante de résoudre ce problème consiste à regrouper les classes liées dans un seul fichier. Créer un "module"

+0

Je pense que vous avez mal interprété la question légèrement, je ne demande pas si php va deviner où un fichier est ou est nommé, je demande si j'ai auto charger pour charger un fichier nommé comme une classe, mais appelez ensuite une classe est dans le même fichier que la classe car il ne fait que prolonger la classe et n'a pas son propre nom – JasonDavis

9

Avez-vous considéré des définitions explicites de vos emplacements de classe? Parfois, cela a beaucoup de sens de regrouper des classes liées.

Voici une façon éprouvée de le manipuler.

Ce code est placé dans un auto_prepend_file (ou inclus premier)

class Import 
{ 
    public static $_AutoLoad = array(); 
    public static $_Imported = array(); 

    public static function Load($sName) 
    { 
     if(! isset(self::$_AutoLoad[$sName])) 
      throw new ImportError("Cannot import module with name '$sName'."); 

     if(! isset(self::$_Imported[$sName])) 
     { 
      self::$_Imported[$sName] = True; 
      require(self::$_AutoLoad[$sName]); 
     } 
    } 

    public static function Push($sName, $sPath) 
    { 
     self::$_AutoLoad[$sName] = $sPath; 
    } 

    public static function Auto() 
    { 
     function __autoload($sClass) 
     { 
      Import::Load($sClass); 
     } 
    } 
} 

Et dans votre fichier d'amorçage, définissez vos classes, et quel fichier ils sont.

//Define autoload items 
Import::Push('Admin_Layout',  App::$Path . '/PHP/Admin_Layout.php'); 
Import::Push('Admin_Layout_Dialog', App::$Path . '/PHP/Admin_Layout.php'); 
Import::Push('FileClient',   App::$Path . '/PHP/FileClient.php'); 

Enfin, activer le chargement automatique en appelant

Import::Auto() 

Une des belles choses est que vous pouvez définir des « modules »:

Import::Push('MyModule',   App::$Path . '/Module/MyModule/Init.php'); 

Et puis les charger explicitement en cas de besoin:

Import::Load('MyModule'); 

Et l'une des meilleures parties est que vous pouvez avoir Import::Push supplémentaire lignes dans le module, qui définira toutes ses classes au moment de l'exécution.

+0

Belle solution, mais consultez la norme plus avancée PSR-4 ici, qui est une extension de la même méthode: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md –

0

Il y a une solution, je l'ai juste utilisé et il semble fonctionner:

Supposons que nous avons une classe appelée animaux auto-chargement stockés dans animals.class.php. Dans le même fichier que vous pourriez avoir d'autres classes qui étend les animaux

class animals{ 
     static function load(){ 
      return true; 
     } 
    } 


    class dogs extends animals{ 

    } 

    class cats extends animals{ 

    } 

maintenant ... quand vous devez utiliser votre classe dogs vous avez besoin PHP autoload il est classe parent (et ce faisant, vous êtes sûr qu'il analysera aussi toutes les classes à l'intérieur du même générale élargie fichier) il vous suffit d'écrire:

animals::load(); 
$fuffy = new dogs(); 
Questions connexes