How to manage dependency autoload

When creating a library, I always provide an Autoloader class that handles autoload for the library. The autoloader is registered as follows:

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

I'm not sure how to handle this if my library depends on another library. Imagine that PHPParser depends on a PHPLexer . Now, using the library, you need to write:

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

If there is more than one dependency or dependencies depend on the dependencies themselves, this can quickly get confused.

So how should handling dependency loading ?

One of my ideas was that the library should also handle autoload for these dependencies, but that is simply not the case. Another idea would be to not provide an autoloader at all and assume that people are using UniversalClassLoader . This, although it does not seem correct.

+4
source share
3 answers

Well, there are several ways to solve this problem, each of which has its pros and cons:

  • Use the common PSR-0 autoloader for all libraries and simply register the location of another project when it is initialized.

    • Benefits:
      • Very easy to implement
      • Uses the same code, so use only one autoloader
      • You can register all the paths in the boot file of the application, so the entire library load is defined in one place.
    • disadvantages
      • All libraries require a file structure compatible with PSR-0.
      • Accelerates the level of abstraction, since boot loading the application should load everything inside the application, including each individual library.
      • Tightly binds the file structure of the library with your autoloader (if the library implements a new file that conflicts, it will break your autoloader, even if their file works)
  • Define a custom autoloader for each library.

    • Benefits
      • Very easy to implement.
      • Saves the automatic semantics library to the library.
      • Improved support code due to shared responsibility.
    • disadvantages
      • Lots of hardcoded classes in your boot file (unimportant)
      • Performance, since the autoload class must go through several autoloaders
      • Maintains the level of abstraction, since the library may require more effort to load than just autoload
  • Deploy bootstrap.php for each library (preferably provided by the library)

    • Benefits
      • Pretty simple to implement.
      • Saves the automatic semantics library to the library
      • Better code due to separation of concerns
      • Ability to define non-trivial library bootstrap code without clouding other parts of the application
    • disadvantages
      • Still require require_once '/path/to/lib/dir/bootstrap.php'; to initialize
      • Performance (for the same reason as for the second solution)
      • Most 3pd libraries do not implement a boot file, so you may need to support it.

Personally, I use the third option. An example is the bootstrap.php file in my CryptLib library. To initialize it, just call bootstrap. You can also use any PSR-0 autoloader and just do not call bootstrap.php and it will work fine. But with the bootstrap option, if I added the functionality needed to register at startup, I could just add it to the bootstrap.php file and it will be automatically executed (instead of telling users what they will need to do "x , y, z "at startup) ...

As for the universal classloader option that you mentioned (calling spl_autoload_register() with no arguments), I personally don't like this. First of all, it reduces the name of the class (which is a violation of PSR-0, and I don't like it. I'm used to matching the path to the case → class and actually prefer it that way). Secondly, it always uses relative paths, so it defeats most operation caches. There are other problems, but these are big ...

+8
source

If the classes in the library are called the PSR-0 convention, then you can use one autoloader for all libraries. Otherwise, the library must provide its own autoloader.

+2
source

add to class constructor

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

after that, on the page where you want to download, create an object

 $obj = new PHPParser_Autoloader(); 
-1
source

All Articles