Magic autoload function
Moderator: General Moderators
Magic autoload function
I'm in the early stages of coding my own framework; I must be crazy.
At the moment I have the autoload function pick up any instantiated classes not found which then begins to scourge around my directories - either in the Model or Controller. If it cannot find the class it outputs a pretty little error message saying so. If it finds it then it simply includes it and makes a log of the event. I find myself more and more often forgetting (or rather not being smacked on the hand by PHP) to include files - just because I don't have to!
This brings me onto the question. How many of you guys have simply given up manually including each class and have just left it for the autoloader? I think I am at the stage in my career (if you can call it that) whereby I see the benefits of such languages as Java and C# where everything is in neat and tidy namespaces, no need of the bother of including everything manually.
The other question is the overhead this puts on the project. I can imagine numerous new objects, file queries, etc would make the overall site run a little slower - but is this a acceptable compromise? Should the autoloader simply be left as a fail safe? Or once the project is almost complete you should go around and clear up all the missing includes?
Also, I think I am right in saying that namespaces are a planned feature for PHP6? If so I can't wait.
At the moment I have the autoload function pick up any instantiated classes not found which then begins to scourge around my directories - either in the Model or Controller. If it cannot find the class it outputs a pretty little error message saying so. If it finds it then it simply includes it and makes a log of the event. I find myself more and more often forgetting (or rather not being smacked on the hand by PHP) to include files - just because I don't have to!
This brings me onto the question. How many of you guys have simply given up manually including each class and have just left it for the autoloader? I think I am at the stage in my career (if you can call it that) whereby I see the benefits of such languages as Java and C# where everything is in neat and tidy namespaces, no need of the bother of including everything manually.
The other question is the overhead this puts on the project. I can imagine numerous new objects, file queries, etc would make the overall site run a little slower - but is this a acceptable compromise? Should the autoloader simply be left as a fail safe? Or once the project is almost complete you should go around and clear up all the missing includes?
Also, I think I am right in saying that namespaces are a planned feature for PHP6? If so I can't wait.
How slow autoload runs depends on how you code it.
If you make it so it does a search of directories, then its probably going to hurt performance as file scans and directory reads are expensive.
However, if you make a namespace class to register class names, or if you make it so the path can be extrapolated from the class name, then it will be efficient.
For instance, having a class called MyApp_Model_Products then having the class file be in a directory like MyApp/Model/Products.php. That would make it efficient.
Personally I use __autoload a lot. It can sometimes make your app more efficient so that you aren't including everything, only the classes that actually get used are included.
If you make it so it does a search of directories, then its probably going to hurt performance as file scans and directory reads are expensive.
However, if you make a namespace class to register class names, or if you make it so the path can be extrapolated from the class name, then it will be efficient.
For instance, having a class called MyApp_Model_Products then having the class file be in a directory like MyApp/Model/Products.php. That would make it efficient.
Personally I use __autoload a lot. It can sometimes make your app more efficient so that you aren't including everything, only the classes that actually get used are included.
Wow, moment of clarity.
That's actually quite interesting. I always sniggered inside when I read Zend's code and see their class naming structure; however, now you mention it, it does goes hand-in-hand with the autoloader... can't believe I didn't think of that before.
I might just have to change my whole approach to suit this.
That's actually quite interesting. I always sniggered inside when I read Zend's code and see their class naming structure; however, now you mention it, it does goes hand-in-hand with the autoloader... can't believe I didn't think of that before.
I might just have to change my whole approach to suit this.
Re: Magic autoload function
I'm at a point where i don't believe in 'magic' anymore... If you want to tie your project structure to your namespaces autoload can be very useful..Zu wrote: At the moment I have the autoload function pick up any instantiated classes not found which then begins to scourge around my directories - either in the Model or Controller. If it cannot find the class it outputs a pretty little error message saying so. If it finds it then it simply includes it and makes a log of the event. I find myself more and more often forgetting (or rather not being smacked on the hand by PHP) to include files - just because I don't have to!
Actually, you still have to make sure the references to assemblies are provided, and that the right 'using' statements are there, so i fail to see the benefit...Zu wrote: I think I am at the stage in my career (if you can call it that) whereby I see the benefits of such languages as Java and C# where everything is in neat and tidy namespaces, no need of the bother of including everything manually.
Imho, there are two options: use autoload and make sure it's clearly documented or stay away from it... I would expect that there are a zillion of IDE's that can resolve missing class definitions?Zu wrote: The other question is the overhead this puts on the project. I can imagine numerous new objects, file queries, etc would make the overall site run a little slower - but is this a acceptable compromise? Should the autoloader simply be left as a fail safe? Or once the project is almost complete you should go around and clear up all the missing includes?
How would namespaces help in the problem of making sure all class definitions are loaded? Unless all the classes of a given namespace are in a predefined location you just can't be sure all classes have been loaded...Zu wrote: Also, I think I am right in saying that namespaces are a planned feature for PHP6? If so I can't wait.
I can even provide an example where namespaces lead to problems
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Re: Magic autoload function
You are calling a collection of classes rather than individually... I fail to see how this wouldn't be beneficial. I don't think I have ever once had a problem with using Java not being able to find the right class; admittedly the most expansive application I have produced was around 20 classes.timvw wrote:Actually, you still have to make sure the references to assemblies are provided, and that the right 'using' statements are there, so i fail to see the benefit...
Using it as I am now, I think if it wasn't for the usefulness of it I would consider it bad practice. There is that niggle which is telling me that I shouldn't be using it, but I just keep coming back to fact I think it is nifty :/Hockey wrote:I personally say __autoload is bad programming practice.
That was what I was trying to get at with my OP. I am already using it as an error logger (and that is what it was originally intended for, as well as a fail safe), however it has moulded into something which I now find integral.Hockey wrote:However feyd a while back sold me on it's useful-ness as an error logger.
Last edited by Zu on Wed Apr 25, 2007 10:35 am, edited 2 times in total.
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
It's analogous to error surpression operator really, helping you get out of a bad design. 
Why not make sure you have your includes before your objects and use autoload() to log when an include was used properly.
Additionally, it has the added bonus of allowing third party source browsers to generate cross references between files.
Cheers
Why not make sure you have your includes before your objects and use autoload() to log when an include was used properly.
Additionally, it has the added bonus of allowing third party source browsers to generate cross references between files.
Cheers
- aaronhall
- DevNet Resident
- Posts: 1040
- Joined: Tue Aug 13, 2002 5:10 pm
- Location: Back in Phoenix, missing the microbrews
- Contact:
I wouldn't go so far to say that dynamically loading files on an as-needed basis is poor design; it's certainly not error suppression.Hockey wrote:It's analogous to error surpression operator really, helping you get out of a bad design.
It's an annoyance. So long as the autoloader is designed properly, why not let a single piece of code handle that for me? For 30-file projects that conditionally load only a few classes at a time, I'll be rewriting the same include calls several times over.Hockey wrote:Why not make sure you have your includes before your objects
__autoload is only called if the class hasn't already been defined. And why would I want to log expected behavior?Hockey wrote:...and use autoload() to log when an include was used properly.
I guess I don't use source browsers that muchHockey wrote:Additionally, it has the added bonus of allowing third party source browsers to generate cross references between files.
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
I meant, use autoload to log when classes are not included so you can fix it.aaronhall wrote:I wouldn't go so far to say that dynamically loading files on an as-needed basis is poor design; it's certainly not error suppression.Hockey wrote:It's analogous to error surpression operator really, helping you get out of a bad design.It's an annoyance. So long as the autoloader is designed properly, why not let a single piece of code handle that for me? For 30-file projects that conditionally load only a few classes at a time, I'll be rewriting the same include calls several times over.Hockey wrote:Why not make sure you have your includes before your objects__autoload is only called if the class hasn't already been defined. And why would I want to log expected behavior?Hockey wrote:...and use autoload() to log when an include was used properly.I guess I don't use source browsers that muchHockey wrote:Additionally, it has the added bonus of allowing third party source browsers to generate cross references between files.
The point is, magic methods or techniques in PHP are tricky to follow when you enter a source base thats a couple 1000 lines in size. I can't stand PHP caveats like that
These are what I like to call implicit programming practices and are generally more difficult to scan through when just entering a codebase than had you stuck to a known standard, such as including files statically. Not just the source browsers that can't scan your source tree.
Think about the developer whose been thrown into your class. He exepcted to fix a bug, he spends a few hours learning the class only to realize the class has a dependency on a superclass and several composites.
Now, had you used static includes, what files it depends on would be immeditaley obvious to the developer without having to leave source file. Instead he or she has to fire grep or similar and scan for the damn class names. What happens if there are two or more classes exist with the same namespace but in different files? Now how do you tell which file is the one in question? You have to poke through the entire process and your magic autoloader function to discover how and why things are loaded they way they are.
PITA. It's these little automation tricks that developers use that drive me nutts - as someone who gets called in to fix problems I see this *ALL* the time and it drives me crazy.
If you have to conditionally include classes, I have the two solutions:
1) Have a centralized init.php script which acts something like a service locator (maybe still use hardcoded paths if possible).
2) Refactor your source tree and codebase to minimize this requirement.
Cheers
Re: Magic autoload function
But namespaces do *not* give you the ability to *load* a collection of classes... All they do is logically group a set of classes... (Just as prefixing all your methods with xxx_ is a technique, although it has flaws, to accomplish that grouping).Zu wrote:You are calling a collection of classes rather than individually... I fail to see how this wouldn't be beneficial. I don't think I have ever once had a problem with using Java not being able to find the right class; admittedly the most expansive application I have produced was around 20 classes.timvw wrote:Actually, you still have to make sure the references to assemblies are provided, and that the right 'using' statements are there, so i fail to see the benefit...
If you don't make sure that your jar file is in the classpath, no matter how many using (or is it import?) statements in your code you won't be able to load the classes...
Source browsers? I use exclusivley __autoload in a project that has about 300 files so far and Zend Studio, Eclipse, and PHPDoc have no trouble linking classes and files together.Hockey wrote: These are what I like to call implicit programming practices and are generally more difficult to scan through when just entering a codebase than had you stuck to a known standard, such as including files statically. Not just the source browsers that can't scan your source tree.
Assuming that __autoload isn't written badly (like scanning folders and looking for a class) this should not be an issue. Most people who implement autoload use a very logical implementation where its easy to deduce the location of the file from the name of the class. Additionally using eclipse or zend studio you can simply right click on any class, method, or function and go directly to the source and the IDE will open up the file. This is common in other IDEs as well.Hockey wrote: Think about the developer whose been thrown into your class. He exepcted to fix a bug, he spends a few hours learning the class only to realize the class has a dependency on a superclass and several composites.
It should also be somewhat apparent if a class is dependent on a super class or a composite. If you can't figure that out from looking at the code or comments then the code was probably badly written to begin with.
Your app has problems if there are two classes with the exact same name some in a project. This is a problem in itself and will give you grief in most IDEs particularly eclipse and zend studio.Hockey wrote: Now, had you used static includes, what files it depends on would be immeditaley obvious to the developer without having to leave source file. Instead he or she has to fire grep or similar and scan for the damn class names. What happens if there are two or more classes exist with the same namespace but in different files? Now how do you tell which file is the one in question? You have to poke through the entire process and your magic autoloader function to discover how and why things are loaded they way they are.
Another point of view: What if you use static includes, an outside developer sees a class get used somewhere. After lunch he reopens his IDE and wants to use that class but doesn't remember where he saw it included. How is he going to know what file its in or where its located without using grep or similar to scan for the damn class names?
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
_autoload() is a valid optimisation for servers without opcode caches. Cuts down all those pesky crufty require_once calls. On the flipside it buries who includes what and when making it slightly more difficult to locate "dead" classes nothing references any longer. On the plus side again it offers no significant performance issue in combination with an opcode cache than explicit includes do. On the flipside, once more, it's easy to over engineer it (a la ZF's Zend_Loader class which is almost ridiculously overweight for most includes).It's analogous to error surpression operator really, helping you get out of a bad design. Smile
Why not make sure you have your includes before your objects and use autoload() to log when an include was used properly.
Additionally, it has the added bonus of allowing third party source browsers to generate cross references between files. Smile
End of the day? It's not bad practice - in the right hands it's simply another tool to size up.
I disagree somewhat with this. Error supression is deliberatly removing the output from snippets which would otherwise likely cause errors. Using the autoloader is not a means to supression but performs a valid role in helping to maintain the system, in perhaps a more efficient working environment.Hockey wrote:It's analogous to error surpression operator really, helping you get out of a bad design.
Upon reflection of what I said, I was referring to packages not namespaces. However, I was not trying to state that you were loading them, rather you were "including" (calling upon) them for use.timvw wrote:But namespaces do *not* give you the ability to *load* a collection of classes... All they do is logically group a set of classes... (Just as prefixing all your methods with xxx_ is a technique, although it has flaws, to accomplish that grouping).
Java uses 'import', .Net uses 'using'.timvw wrote:... no matter how many using (or is it import?) statements...
- Kieran Huggins
- DevNet Master
- Posts: 3635
- Joined: Wed Dec 06, 2006 4:14 pm
- Location: Toronto, Canada
- Contact: