2011-09-09 3 views
4

Lors de la création d'une bibliothèque, je fournis toujours une classe Autoloader qui gère le chargement automatique de la bibliothèque. Le chargeur automatique est inscrit comme ceci:Comment gérer le chargement automatique des dépendances

require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php'; 
PHPParser_Autoloader::register(); 

Je ne sais pas si la façon de traiter si ma bibliothèque dépend d'une autre bibliothèque. Imaginez que PHPParser dépend d'un PHPLexer. Maintenant, lorsque vous utilisez la bibliothèque on aurait besoin d'écrire:

require_once 'path/to/PHP-Lexer/lib/PHPLexer/Autoloader.php'; 
PHPLexer_Autoloader::register(); 

require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php'; 
PHPParser_Autoloader::register(); 

S'il y a plus d'une dépendance ou les dépendances ont des dépendances eux-mêmes, cela peut se salir rapidement.

Alors Comment devrait-on gérer l'auto-chargement des dépendances? Une idée que j'avais était que la bibliothèque devrait gérer le chargement automatique pour ses dépendances aussi, mais cela ne me semble pas juste. Une autre idée serait de ne pas fournir un autochargeur du tout et de supposer que les gens utilisent le UniversalClassLoader. Cela ne semble pas correct non plus.

+0

'Une idée que j'avais était que la bibliothèque devrait aussi gérer le chargement automatique pour ses dépendances, mais cela ne va pas.'- quand tous les fournisseurs supportent PSR-0, cette idée fonctionne bien –

Répondre

8

Eh bien, il y a quelques façons de résoudre ce problème, chacun avec leurs propres avantages et les inconvénients:

  1. Utilisez un chargeur automatique PSR-0 commun pour toutes les bibliothèques, et juste enregistrer l'emplacement du autre projet lors de l'initialisation.

    • Avantages:
      1. Très simple à mettre en œuvre
      2. Utilise même code, donc un seul chargeur automatique d'utiliser
      3. Vous pouvez enregistrer tous les chemins dans votre fichier de démarrage de l'application, de sorte que tous autoloading bibliothèque défini en un seul endroit
    • Inconvénients
      1. Nécessite toutes les bibliothèques pour implémenter une structure de fichier compatible PSR-0
      2. Leaks le niveau d'abstraction un peu puisque le bootstrap de l'application doit tout faire dans l'application, y compris chaque bibliothèque individuelle.
      3. Collée couples structure de fichiers de la bibliothèque à votre chargeur automatique (si une bibliothèque implémente un nouveau fichier qui est en conflit, il va casser votre chargeur automatique, même si leurs œuvres fichier)
  2. Définir un chargeur automatique personnalisé pour chaque bibliothèque.

    • Avantages
      1. Très simple à mettre en œuvre.
      2. Conserve la sémantique de chargement automatique de la bibliothèque dans la bibliothèque.
      3. meilleur code maintenable en raison de la séparation des responsabilités
    • Inconvénients
      1. Beaucoup de classes codées en dur dans votre fichier d'amorçage (pas une grosse affaire si)
      2. Performance depuis une classe autochargée doit aller à travers de multiples autoloaders
      3. Fuites le niveau d'abstraction depuis une bibliothèque peut avoir besoin de plus d'efforts pour amorcer qu'un simple chargement automatique
  3. Mettre en oeuvre un bootstrap.php pour chaque bibliothèque (de préférence fournies par la bibliothèque)

    • Avantages
      1. assez simple à mettre en oeuvre.
      2. Garde sémantique de chargement automatique bibliothèque dans la bibliothèque
      3. meilleur code en raison de la séparation des préoccupations
      4. Possibilité de définir le code d'amorçage de la bibliothèque non triviale sans opacification d'autres parties de l'application
    • Inconvénients
      1. Encore besoin d'un require_once '/path/to/lib/dir/bootstrap.php'; pour initialiser
      2. Performances (pour la même raison que la 2ème solution)
      3. La plupart des bibliothèques 3pd n'implémentent pas un fichier d'amorçage, vous devrez donc en gérer un.

Personnellement, j'utiliser la troisième option. Un exemple est le bootstrap.php file dans ma bibliothèque CryptLib. Pour l'initialiser, appelez simplement bootstrap. Vous pouvez également utiliser n'importe quel chargeur automatique PSR-0 et ne pas appeler bootstrap.php, et cela fonctionnera très bien. Mais avec l'option bootstrap, si j'ajoutais une fonctionnalité qui devait s'inscrire au démarrage, je pourrais juste l'ajouter au fichier bootstrap.php et il serait automatiquement exécuté (plutôt que de dire aux utilisateurs qu'ils devront faire "x, y , z "au démarrage) ...

En ce qui concerne l'option universelle de chargeur de classe que vous avez mentionnée (appelant spl_autoload_register() sans arguments), personnellement, je n'aime pas cette option. Tout d'abord, il met en minuscules le nom de la classe (qui est en violation de PSR-0, et je ne l'aime pas, je me suis habitué à la classe sensible à la casse -> mappage de chemin, et je préfère réellement ça maintenant). Deuxièmement, il utilise toujours des chemins relatifs, donc il va vaincre la plupart des caches d'opcode. Il y a d'autres problèmes, mais ce sont les grands problèmes ...

-1

ajouter au constructeur de la classe

public function __construct(){ 
$this->Register(); 
} 

après que la page où vous whant pour faire la charge créer un objet

$obj = new PHPParser_Autoloader(); 
+0

Je ne suis pas sûr de savoir comment cela aide le problème de dépendance. Pourriez-vous élaborer? – NikiC

+0

constructeur en classe statique? –

2

Si les classes dans la bibliothèque nommée par convention PSR-0, qu'il est possible de utiliser un autochargeur pour toutes les bibliothèques. Sinon, la bibliothèque devrait fournir son propre autochargeur.

+0

D'accord. @NikiC Jetez un oeil à un exemple [https://github.com/symfony/symfony-standard/blob/master/app/autoload.php] de l'autochargeur universel (voir '$ loader-> registerPrefixes') de symfony, puisque votre PHPParser fait partie de symfony2. – atma

Questions connexes