__autoload()

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

__autoload()

Post by alex.barylski »

Edit Please read from start to finish before replying...as I realized something while writing half way through...

So me and my good pal Oren ;) were having a disscussion today about __autoload() which I had never used before, but was aware of it's existance...

I read the docs and I must say I'm not overly impressed with the idea of __autoload()

For starters, I'm trying to think how PHP would implement such functionality...

It parses all code in every file directly referenced...it detects any classes which haven't been defined and uses those names to include() a class interface/implementation...???

How does it locate these files? I assume it must recursively scan the entire directory looking for a filename that matches the classname??? what if the classname and the file names are not named exactly alike? For instance, I use lower case letters for my filenames and camelcase for class names...???

So there is a performance implication in using __autoload() I would think...???

That file which contains __autoload() and the class definietion could be stored *anywhere* so how else does PHP find that file???

Ok I just had an epiphany :P

__autoload() is not a member function, but it appears to be a global magic function...which the scripting engine calls...whenever it stumbles across an undefined class :oops:

So there goes my argument for performance issues... :P

But still the spaghetti code issue...and forcing of conventions when naming your class exactly as you would the name of your class filename...the second is probably not important to anyone but me, but the spaghetti code...???

I suppose inside the __autoload() I could convert camelcase to filename convention...

But there goes any include() information for auto-documentors... :P

Plus, the dynamic nature of it all really hides details from you, making it possibly difficult to locate where and when an object was included (maybe not when cuz that's obvious)...??

I don't know how many of you used GOTO: back in the day, but I did, as it's conveinent(sp?) but sooner or later you realize that it's not the best way to do things, at least for large project longevity/readability, etc...

Opinions, thought, etc???
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Re: __autoload()

Post by feyd »

Hockey wrote:__autoload() is not a member function, but it appears to be a global magic function...which the scripting engine calls...whenever it stumbles across an undefined class :oops:
Bingo.
Hockey wrote:But still the spaghetti code issue...and forcing of conventions when naming your class exactly as you would the name of your class filename
There's absolutely nothing that says you have to name the file the same as the class. In the manual it mentions that many of us name our files in a patterened way that relates to the class or classes it contains.
Hockey wrote:the second is probably not important to anyone but me, but the spaghetti code...???
What spaghetti code?
Hockey wrote:I suppose inside the __autoload() I could convert camelcase to filename convention.
You can do any number of transforms, or none at all. It's your choice. I've posted a possible __autoload() that doesn't even look for files, but generates a stub class which says "I'm not loaded!" basically.
Hockey wrote:But there goes any include() information for auto-documentors...
Only if the documentor is built poorly.
Hockey wrote:Plus, the dynamic nature of it all really hides details from you, making it possibly difficult to locate where and when an object was included (maybe not when cuz that's obvious)...??
debug_backtrace() anyone?
Hockey wrote:I don't know how many of you used GOTO: back in the day, but I did, as it's conveinent(sp?) but sooner or later you realize that it's not the best way to do things, at least for large project longevity/readability, etc.
I used it, and very effectively too. It was a function cleanup tool for me. Destroy variables in a stack fashion and you can jump past spots that'd break with undefined errors.

The aforementioned post of an __autoload that generates stubs and tracks usage: viewtopic.php?p=292508#292508
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: __autoload()

Post by alex.barylski »

What spaghetti code?
It's not really spaghetti code...I agree, but I was using that as an anology to GOTO which is notorious for making spaghetti out of your code...

__auotload() doesn't cause your code to jump around in impossible to trace fashions...it does IMHO make it harder to follow from start to finish...as looking at __autoload() itself won't tell you which files are included and which aren't...

I'll have alooksie at your stub function you speak of...see if that changes my mind...
You can do any number of transforms, or none at all. It's your choice. I've posted a possible __autoload() that doesn't even look for files, but generates a stub class which says "I'm not loaded!" basically
Ok, so you use it as an error handler more than a tool to make your code more automated? Now that's smart...and makes sense :D
Only if the documentor is built poorly.
I suppose, depends if the documentor scans the source tree or navigates via links in which case, in PHP it wouldn't be a good way to do things anyways :)
I used it, and very effectively too. It was a function cleanup tool for me. Destroy variables in a stack fashion and you can jump past spots that'd break with undefined errors.
Here I'll argue with you...I used it too...and sure it's effective...sometimes a quick way to get out of a bind too...but it's lazy and clear indication of poor design IMHO...

It's like a get out of jail for free card...yes sometimes it's *really* handy but mostly it's used to get out of jail for free :P and thus creates the impossible to follow spaghetti code...jumping, branching, etc...OMG

As for a function clean up tool? In what language? Most compilers automatically push/pop vairables from a stack as the go out of scope anyways, so how would GOTO assist in doing this? unless you create a variable on the heap using new or specify you wanted to use a register...all variables work in a stack like fashion...

I'm missing something here...

Cheers :)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Re: __autoload()

Post by feyd »

Hockey wrote:Ok, so you use it as an error handler more than a tool to make your code more automated? Now that's smart...and makes sense :D
I've used __autoload() in many ways: error handling by creating a stub, service locator-like fetching, tree searching, etc etc.
Hockey wrote:PHP it wouldn't be a good way to do things anyways :)
Not sure I understand that bit.
Hockey wrote:Here I'll argue with you...I used it too...and sure it's effective...sometimes a quick way to get out of a bind too...but it's lazy and clear indication of poor design IMHO...

It's like a get out of jail for free card...yes sometimes it's *really* handy but mostly it's used to get out of jail for free :P and thus creates the impossible to follow spaghetti code...jumping, branching, etc...OMG
My professors thought it was quite clever. :)
Hockey wrote:As for a function clean up tool? In what language?
C/C++.
Hockey wrote:unless you create a variable on the heap using new or specify you wanted to use a register...all variables work in a stack like fashion...
That's the clean up I'm talking about.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: __autoload()

Post by alex.barylski »

I've used __autoload() in many ways: error handling by creating a stub, service locator-like fetching, tree searching, etc etc.
Like I said, that's a good use for the __autoload() the way it's promoted though...I was under the impression it was somewhat of a cheater function...which makes things easier but more garbage in the long run...

Although, if all you do is spit an error out to the screen, isn't that kind of redundant? PHP would inform you that XXX class was refered to but not defined??? Or do you additionally include the class, and just keep a log so you can later update the code so that error isn't generated anymore???
Not sure I understand that bit.
What I meant was some documentors scan the entire source tree and open all files which are of .xyz extensions whereas others *may* actually start with an specific file and navigate the source tree by following the includes() which in PHP's case wouldn't make much sense, as it's too dynamic...
My professors thought it was quite clever.
I'm not sure what it is you did, but like I said, at times, sure GOTO could be cleverly used...but most of the time...like MI...it's bad design and should be avoided like the plague... :P

It's been so long since I used GOTO I can't think of an example...and when I did use it I likely used it naively(sp?) but I clearly have an understanding now of what it does and what it could do...and see it's pitfalls more than it's benefits...

It's like using a shift instead of division operator to increase execution time on x86 processors...sure it's a neat little hack to swueeze out some extra performance, especially in loops, but it's clarity balanced against performance increase...

I don't know, like we've argued about PHP file size not being important. Perhaps it is and perhaps it isn't...maybe it's a matter of personal choice... :)
That's the clean up I'm talking about.
Hmmm...so you used GOTO to clean up pointers in C++...why wouldn't you use smart pointers? :P

Unless it was strictly C in which case that wouldn't work...

By i'm still confused as to how GOT could be used cleverly free memory...

Code: Select all

function _test()
{
  CObject* pObject = new CObject();
  goto cleanup:

cleanup:  
  delete pObject;
}
You could use cleanup: as a centralized cleanup JUMP instead of having to call delete on the same object namespace more than once...

But again, of all my years using C/C++ I've never done or seen(that I recognized anyways) that technique...

You wouldn't happen to to still have that function would you? I'd like to see the source...perhaps it very well was an instance where GOTO would suffice...or rather was the better choice...

Cheers :)
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

Well, I wouldn't call it a discussion Hockey... I just wanted to make sure it was impossible to catch errors which are thrown within the __autoload() function, that's all :P

feyd: Why do you use it as an error handler instead of using it to include the needed files?

I believe that this:

Code: Select all

include 'autoload.php';
looks much better than this:

Code: Select all

include 'classes/class_1.php';
include 'classes/class_2.php';
.
.
.
include 'classes/class_n.php';
Moreover, when you do all these include()'s, you have to give the exact path to the file relative to the path of the script in which you put all these include()'s.
Now that is stupid in my opinion since we all store our classes in a certain path - a directory called classes for this example.
If we had to include everything manually, then in one file it would probably look like this:

Code: Select all

include 'classes/class_1.php';
include 'classes/class_2.php';
.
.
.
include 'classes/class_n.php';
in another file it would be:

Code: Select all

include '../../../classes/class_1.php';
include '../../../classes/class_2.php';
.
.
.
include '../../../classes/class_n.php';
and so on...

There is a much better way. I know that my autoload.php file is located inside the directory include and this include directory is located in the root directory of my application. I also know that the classes directory is located in the root directory of my application.
Therefore, all that my autoload.php file has to contain is this:
(I name my class files in the form of: class.[class_name].php)

Code: Select all

<?php


	function __autoload($class_name)
	{
		require_once dirname(__FILE__) . '/../classes/class.' . $class_name . '.php';
	}
Thanks to dirname(__FILE__) I save for myself the need to type manually the relative path to the classes directory and at the same time avoid from making mistakes in the file path.
The only path I have to type manually is the path to my autoload.php file 8)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Re: __autoload()

Post by feyd »

Hockey wrote:Although, if all you do is spit an error out to the screen, isn't that kind of redundant?
That depends on how you implement it. If you just echo straight away, yes, it's silly. But if you aggregate the information for later dispensation, then it's something else. :)
Hockey wrote:What I meant was some documentors scan the entire source tree and open all files which are of .xyz extensions whereas others *may* actually start with an specific file and navigate the source tree by following the includes() which in PHP's case wouldn't make much sense, as it's too dynamic...
Yes, it's a bit more difficult to walk the code programmaticly in PHP.
Hockey wrote:see it's pitfalls more than it's benefits...
I will agree that most people should avoid it.
Hockey wrote:It's like using a shift instead of division operator to increase execution time on x86 processors...sure it's a neat little hack to swueeze out some extra performance, especially in loops, but it's clarity balanced against performance increase.
All our code was about performance. You need to remember, I was game programming. Shifting is faster, so we used it.
Hockey wrote:I don't know, like we've argued about PHP file size not being important. Perhaps it is and perhaps it isn't...maybe it's a matter of personal choice... :)
You could write some tests and see how your computer handles it versus mine. :)
Hockey wrote:Hmmm...so you used GOTO to clean up pointers in C++...why wouldn't you use smart pointers? :P
Again, high-performance requirement. Objects were fairly expensive, so they were used somewhat sparingly.
Hockey wrote:By i'm still confused as to how GOT could be used cleverly free memory...

Code: Select all

function _test()
{
  CObject* pObject = new CObject();
  goto cleanup:

cleanup:  
  delete pObject;
}
I'll see if I can cook up an example on the spot.. if memory serves.

Code: Select all

function foo(SomeObject &boo)
{
  int bar = 2;
  float x, y = x = 33.14f;
  char *floob = calloc(50, sizeof(char));

  // do some initial calculation based on some input, maybe set some data in floob.
  if (bad)
  {
    goto sanityCheckBad;
  }

  unsigned int *floob2 = calloc(300, sizeof(unsigned int));
  // do some other junk as normal doing whatever to floob2.

  free(floob2);
  floob2 = null;

  sanityCheckBad:
  free(floob);
  floob = null;

  return bar;
}
Yes, it could be reordered into other ways.. No I don't care to get into a debate over it.
Hockey wrote:You wouldn't happen to to still have that function would you? I'd like to see the source...perhaps it very well was an instance where GOTO would suffice...or rather was the better choice...
Unfortunately, the source is not my property, so no.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: __autoload()

Post by alex.barylski »

You could write some tests and see how your computer handles it versus mine.
Yea right...I've seen your posts...I run a measly 950Mhz computer...with 264 RAM or something to that effect...

Are you sure you want to race??? :P
Yes, it could be reordered into other ways.. No I don't care to get into a debate over it.
Well...at least your upfront about it... :P

All I needed to hear

Cheers :)
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

You are going off-topic guys...
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Oren wrote:Why do you use it as an error handler instead of using it to include the needed files?
I can't justify that my __autoload() should supersede another developer's or make the end user, or another developer, try to integrate two of them into their code. Proper includes (or however one chooses to load them "correctly") is the proper route to go.
Oren wrote:Moreover, when you do all these include()'s, you have to give the exact path to the file relative to the path of the script in which you put all these include()'s.
set_include_path() or $_SERVER['DOCUMENT_ROOT'] (or similar facsimile) anyone?
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

As for set_include_path() - I don't want to use it. I try to avoid changing the default settings, and besides, I'll have to type it on every file.

As for $_SERVER['DOCUMENT_ROOT'], this:

Code: Select all

include 'autoload.php';
over this:

Code: Select all

include $_SERVER['DOCUMENT_ROOT'] . 'classes/class_1.php';
include $_SERVER['DOCUMENT_ROOT'] . 'classes/class_2.php';
.
.
.
include $_SERVER['DOCUMENT_ROOT'] . 'classes/class_n.php';
What would you choose?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

It's not a matter of choice, as I've already said, I can't justify my __autoload() being more important than another's.

Placed in some always included file, or just genericly at the top of each page controller.

Code: Select all

set_include_path(get_include_path().PATH_SEPARATOR.$_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'classes');
Post Reply