tags:

views:

147

answers:

4

One bad thing about using the autoloader is, that it doesn't know where to look at. My framework already has about 70 classes in about 15 different directories. Because of that, I didn't go for autoload, but instead struggle around with generating paths. So I have an associative paths array that give me paths from my root file to where I want to go. It works, but it's really becoming a pain.

First, the user of my framework will very likely have no big idea where a class resides. So creating a FormViewController is already a pain just because you need the path to include it.

For the beginning, I think it would be just fine if PHP had to "search" for the file through multiple directories when it wants to autoload it. So what? Shall PHP do so and save us a lot of pain. But how could I do that most efficently?

Ther's an array called $paths which I get out of a global context object. The paths could be defined in the array in the most reasonable order: Starting with the most frequently used paths.

I know the PEAR library has a funny naming convention like system_views_specialviews_SpecialView.php which gets converted in the Autoloader to system/views/specialviews/SpecialView.php ...but honestly, that's horrible. Don't want to mess up my file names like this. For the developer who creates his own classes that would suck just straight away.

Before I re-invent the wheel for this task, maybe someone knows a solution for this?

+1  A: 

NB: I'm presuming you're creating your own custom autoloader via spl_autoload_register, etc.

If you're creating an autoloader and the classes you're looking to include are spread across 15 different directories, I don't see how you can hope to avoid using some form of class name to directory path mapping, although this obviously doesn't need to be quite as deep as the example you quote.

At a simple level, if you keep all of your system libraries in a single area, then a quick case match as such...

switch(true) {

    case substr($className, 0, 6) == 'System': { $libraryPath = 'xxx'; break; }
    ...
}

...should be reasonably efficient approach, although it obviously depends on how many paths you need to manually check.

Additionally, I presume you're checking for the existance of the class prior to attempting to autoload? (i.e.: You're doing a class_exists($className) to ensure it's not already been included.) Then again, the requirement for this depends on how often you re-use objects.

middaparka
A: 

I'm sure you already know this, but just in case, you can write an __autoload() (API) function that takes the class name as a parameter in your front controller (or in any file included by it) that searches your directories based on any criteria that you want. All you do is require_once the correct file once you've found it, or throw an exception if the class name isn't valid.

From your description, I didn't get any indication that you were doing this. It sounds like you are just appending PHP's include path with values in unwieldy global arrays.

Marc W
Hmm... I just presumed he was using spl_autoload_register, etc. Good call. :-)
middaparka
In fact, I used __autoload() and messed around with a path array. This is not a good solution though, since I have to remember to add an include path as soon as I create a new directory. Really bad thing.
openfrog
+1  A: 

You might want to look at Nette Framework's RobotLoader.

Basic idea is that it scans through directories you specify, parses .php (token_get_all) files and finds out in which file are which classes/interfaces. Locations of classes/interfaces are cached, so it is fast. Loader is registered with spl_autoload_register() and when PHP interpreter cannot find some class, it calls loader's tryLoad() method.

Jakub Kulhan
A: 

The PHP Autoloader does all you want. If you have different locations you just have to create several instances of the autoloader for each class path.

It seems it does the same like the mentioned RobotLoader, except the first searching is done with some intelligence. Files with lower Levenshtein distance to the class name are prefered as potential class definitions. But this is only relevant for the first search without the index.

Markus Malkusch