473,480 Members | 3,098 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Flexible __autoload scheme

With the advent of PHP5, with its OO support and the new __autoload
function, I was thinking of implementing some king of scheme to organize
classes in such a way that they can be easily found by the __autoload
function, yet at the same time would have clear organization of classes.

Currently (in PHP4) I'm using a Java-like scheme, borrowed from ActiveLink
IORCA (www.active-link.com), which uses a special import() function and
classes organized in files and directories. Each time I need a certain
class, I must manually import the appropriate class or package. This works
nicely, and intuitively especially for those with experience in Java, but as
PHP5 offers us such a nice feature as the __autoload function, I would much
prefer to take advantag of it.

For those who don't know, __autoload is a magical function that is called
each time a previously undefined class, with the called class name passed as
the argument. Andi and Zeev in their upcoming book (see
http://www.zend.com/php5/andi-book-excerpt.php) give the simplest example:

function __autoload($class_name) {
include_once($class_name . "php");
}

However, this leads to a clutter of class files in a single directory, and
the whole system calls for a little more organization. First of all, I would
at least change the above code to:

define('AUTOLOAD_CLASS_DIR', '/classes/');

function __autoload($class_name) {
require_once(AUTOLOAD_CLASS_DIR . $class_name . ".class.php");
}

This would give me a single central classes directory where all my classes
are stored, as well as a distinct extension (class.php) for class files;
also the class file is now required instead of included. However, it is
still a bit spartan: what if I want to organize my classes by projects,
package etc?

I was thinking of a system where all the class.php files would be organized
in directories, and the __autoload function would somehow be able to find
the right one.

Going through all the directories would potentionally be too slow,
especially in a large classes hierarchy. One approach is that the __autoload
includes a file defining an array which effectively mirrors the filesystem
structure. This means that we need to edit the array each time we add (or
move) a class, or perhaps implementing a mechanism that would, if a class
isn't found, swoop through the directories and recreate the structure.
Another downside would still remain, which is that each class would still
have to have a different name to be recognized by the system.

This seems like it might work (I still have to write it, though), but I am
curious if anyone has some different and preferably better idea to implement
this.

Berislav

--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.
Jul 17 '05 #1
14 2133
Berislav Lopac wrote:
This would give me a single central classes directory where all my
classes are stored, as well as a distinct extension (class.php) for
class files; also the class file is now required instead of included.
However, it is still a bit spartan: what if I want to organize my
classes by projects, package etc?


You could use a naming convention for your classes like:

Package_class.php

and apply the __autoload method as follows:

function __autoload($class) {
list($package, $name) = explode("_", $class, 2);
include "{$package}/{$name}.php";
}

Now, if you want to include a class named Net_HTTP, it will include
HTTP.php, which should reside in a dir called Net.

Of course, the class defined in HTTP.php should also have the name Net_HTTP.

Another possibility would be to adapt the way PEAR handles this...
JW

Jul 17 '05 #2
Janwillem Borleffs wrote:
Another possibility would be to adapt the way PEAR handles this...


Which is?

Berislav

--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.
Jul 17 '05 #3
Berislav Lopac wrote:
Janwillem Borleffs wrote:
Another possibility would be to adapt the way PEAR handles this...


Which is?


Never looked at the PEAR library? In short it goes like this:

* The include_path directive points to the PEAR installation dir (contains
all classes)
* Example structure:

Net.php
HTTP/
HTTP/HTTP.php

* Net.php is the parent class which contains all base methods
* HTTP.php extends Net.php
* The script that implements the Net::HTTP class includes "HTTP/HTTP.php"

Quite basic, but it does enforce a clear structure for your classes.

Until PHP supports namespaces like Java and Perl do, there aren't many
options.
JW

Jul 17 '05 #4
Janwillem Borleffs wrote:

Until PHP supports namespaces like Java and Perl do, there aren't many
options.


I don't really see how would that help with the __autoload concept.

Tangential to this, I'm not that big a fan of namespaces, as they promote
some bad programming habits, while come handy not that often.

Berislav

--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.
Jul 17 '05 #5

"Berislav Lopac" <be************@dimedia.hr> wrote in message news:ch**********@ls219.htnet.hr...
With the advent of PHP5, with its OO support and the new __autoload
function, I was thinking of implementing some king of scheme to organize
classes in such a way that they can be easily found by the __autoload
function, yet at the same time would have clear organization of classes.

Currently (in PHP4) I'm using a Java-like scheme, borrowed from ActiveLink
IORCA (www.active-link.com), which uses a special import() function and
classes organized in files and directories. Each time I need a certain
class, I must manually import the appropriate class or package. This works
nicely, and intuitively especially for those with experience in Java, but as
PHP5 offers us such a nice feature as the __autoload function, I would much
prefer to take advantag of it.

For those who don't know, __autoload is a magical function that is called
each time a previously undefined class, with the called class name passed as
the argument. Andi and Zeev in their upcoming book (see
http://www.zend.com/php5/andi-book-excerpt.php) give the simplest example:

function __autoload($class_name) {
include_once($class_name . "php");
}

However, this leads to a clutter of class files in a single directory, and
the whole system calls for a little more organization. First of all, I would
at least change the above code to:

define('AUTOLOAD_CLASS_DIR', '/classes/');

function __autoload($class_name) {
require_once(AUTOLOAD_CLASS_DIR . $class_name . ".class.php");
}

This would give me a single central classes directory where all my classes
are stored, as well as a distinct extension (class.php) for class files;
also the class file is now required instead of included. However, it is
still a bit spartan: what if I want to organize my classes by projects,
package etc?

I was thinking of a system where all the class.php files would be organized
in directories, and the __autoload function would somehow be able to find
the right one.

Going through all the directories would potentionally be too slow,
especially in a large classes hierarchy. One approach is that the __autoload
includes a file defining an array which effectively mirrors the filesystem
structure. This means that we need to edit the array each time we add (or
move) a class, or perhaps implementing a mechanism that would, if a class
isn't found, swoop through the directories and recreate the structure.
Another downside would still remain, which is that each class would still
have to have a different name to be recognized by the system.

This seems like it might work (I still have to write it, though), but I am
curious if anyone has some different and preferably better idea to implement
this.

Berislav

--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.


I also want to know how to nicely deal with this problem.
My current approach is a mixed one which is like Java searching for
relevant class files according to classpath.
The classpath is a sequence of search paths and files, where
a search file is a mapping between class names and class file locations.
Caching technique is used to save time for repetitive inclusion
of the same classes.
Jul 17 '05 #6
In article <ch**********@ls219.htnet.hr>, Berislav Lopac wrote:
With the advent of PHP5, with its OO support and the new __autoload
function, I was thinking of implementing some king of scheme to organize
classes in such a way that they can be easily found by the __autoload
function, yet at the same time would have clear organization of classes.

Don't know if the following would work in that case:
$bigInt = new Math_BigInteger();

Would allow you to store BigInteger.class.php in a $include_path$/Math
directory.

function __autoload($class)
{
return using($class);
}

function using($class)
{

$class = str_replace('_', '/', $class);

$include_path = ini_get('include_path');
$paths = explode(':', $include_path);

foreach($paths as $path)
{
if (file_exists($path . $class . '.class.php'))
{
require_once($path . $class . '.class.php');
return true;
}
}
trigger_error("Class {$path}{$class}.class.php not found.", E_USER_ERROR);
}

--
Tim Van Wassenhove <http://home.mysth.be/~timvw>
Jul 17 '05 #7
Tim Van Wassenhove <eu**@pi.be> wrote in message news:<2q************@uni-berlin.de>...
<snip>
function using($class)
{

$class = str_replace('_', '/', $class);

$include_path = ini_get('include_path');
$paths = explode(':', $include_path);

foreach($paths as $path)
{
if (file_exists($path . $class . '.class.php'))
{
require_once($path . $class . '.class.php');
return true;
}
}
trigger_error("Class {$path}{$class}.class.php not found.", E_USER_ERROR);
}


Hmm... I guess, you're duplicating the code. When you invoke,
include or require, it will search the file in _all_
"include_path"(s). Isn't it? Please correct me, if I'm wrong.

--
| Just another PHP saint |
Email: rrjanbiah-at-Y!com
Jul 17 '05 #8
Berislav Lopac wrote:
With the advent of PHP5, with its OO support and the new __autoload
function, I was thinking of implementing some king of scheme to organize
classes in such a way that they can be easily found by the __autoload
function, yet at the same time would have clear organization of classes.

Currently (in PHP4) I'm using a Java-like scheme, borrowed from ActiveLink
IORCA (www.active-link.com), which uses a special import() function and
classes organized in files and directories. Each time I need a certain
class, I must manually import the appropriate class or package. This works
nicely, and intuitively especially for those with experience in Java, but
as PHP5 offers us such a nice feature as the __autoload function, I would
much prefer to take advantag of it.


There are couple of options.

1. First of all, one option is like PEAR does it as others already pointed
out - i.e. replacing _ from a class name with / and loading a class from a
directory. So, if you have

$myHTTPClient = new net_http_HTTPClient;

then you would load

net/http/HTTPClient.php

However, I personally don't really prefer this model. I believe that it's
extremely important to explicitly state what the dependencies of a
particular class/script/etc. are. So, anything that discourages this
behavior I would try to avoid.

So, my other suggestion is:

2. Parse for * in import function of ActiveLink IORCA. If you find "*" then
add that directory to an array of dirs to autoload from. So, if you have:

import("org.active-link.xml.*);

then

$myXML = new XML();
$myXMLDoc = new XMLDoc();

should autoload from org/active-link/xml directory.

This way, you don't have to parse through all the directory tree for all
classes, and you don't have to import each class individually from one
package.

Hope this helps.

Disclaimer: I am the author of ActiveLink IORCA and ActiveLink PHP XML
Package ;)
Jul 17 '05 #9
In article <ab**************************@posting.google.com >, R. Rajesh Jeba Anbiah wrote:
Tim Van Wassenhove <eu**@pi.be> wrote in message news:<2q************@uni-berlin.de>...
<snip>
function using($class)
{

$class = '/' . str_replace('_', '/', $class);

$include_path = ini_get('include_path');
$paths = explode(':', $include_path);

foreach($paths as $path)
{
if (file_exists($path . $class . '.class.php'))
{
require_once($path . $class . '.class.php');
return true;
}
}
trigger_error("Class {$path}{$class}.class.php not found.", E_USER_ERROR);
}


Hmm... I guess, you're duplicating the code. When you invoke,
include or require, it will search the file in _all_
"include_path"(s). Isn't it? Please correct me, if I'm wrong.


Good point there :)

I've been thinking about __autoload and untill now i don't see how this
function could be really usefull. (Only how it probably generates
overhead)

--
Tim Van Wassenhove <http://home.mysth.be/~timvw>
Jul 17 '05 #10
Zurab Davitiani wrote:
So, my other suggestion is:

2. Parse for * in import function of ActiveLink IORCA. If you find
"*" then add that directory to an array of dirs to autoload from. So,
if you have:

import("org.active-link.xml.*);

then

$myXML = new XML();
$myXMLDoc = new XMLDoc();

should autoload from org/active-link/xml directory.

This way, you don't have to parse through all the directory tree for
all classes, and you don't have to import each class individually
from one package.

Hope this helps.

Disclaimer: I am the author of ActiveLink IORCA and ActiveLink PHP XML
Package ;)


I already did as you suggest -- here's the complete code of my modification
at the end of this post (sorry I didn't properly mark what is the original
and what I added). You'll notice that I've added a nice red error message in
HTML when the class file wasn't found.

I am very grateful for your script, as it gave me a great boost when I
created my internal little framework. I'll keep using it even with PHP5, but
I'd still like to make use of __autoload somehow.

Berislav

PS. Here's the code:

<?php

/*
This file is part of ActiveLink IORCA (www.active-link.com).
Copyright (c) 2002-2003 by Zurab Davitiani

You can contact the author of this software via E-mail at
ag*@mindless.com

ActiveLink IORCA is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

ActiveLink IORCA is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ActiveLink IORCA; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

/**
* Include file for ActiveLink IORCA
*/

// define included package locations
$GLOBALS["IORCA"]["BASE"]["PATH"] = dirname(__FILE__) . "/";

function import($classPath) {
// define extension for classes
$ext = '.class.php';
$errorMessage = '<div style="margin: 10px; padding: 10px; background: Red;
color: white; font-weight: normal; font-size: large;"><strong style="color:
White">'. $classPath .':</strong> Class doesn\'t exist.</div>';
$importFile = str_replace(".", "/", $classPath) . $ext;
$path = pathinfo($GLOBALS["IORCA"]["BASE"]["PATH"] . $importFile);
$requirePath = '';
if($path['basename'] == "*$ext" && $importDir = opendir($path['dirname'])) {
while(false !== ($file = readdir($importDir))) {
if(stristr($file, $ext) == $ext) {
$requirePath = $path['dirname'] . "/$file";
if(file_exists($requirePath)) require_once($requirePath);
else echo($errorMessage);
}
}
}
else {
$requirePath = $GLOBALS["IORCA"]["BASE"]["PATH"] . $importFile;
if(file_exists($requirePath)) require_once($requirePath);
else echo($errorMessage);
}
}

?>
--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.
Jul 17 '05 #11
Berislav Lopac wrote:
I am very grateful for your script, as it gave me a great boost when I
created my internal little framework. I'll keep using it even with PHP5,
but I'd still like to make use of __autoload somehow.
Sure, that's what I suggested. You can delegate parts of your script to
__autoload instead of doing it manually. Let me elaborate:

function __autoload($class_name) {
foreach($GLOBALS["IORCA"]["CLASSPATH"] as $path) {
if(file_exists($path . $class_name . ".php")) {
require_once($path . $class_name . ".php");
break;
}
}
}
function import($classPath) {
// define extension for classes
$ext = '.class.php';
$errorMessage = '<div style="margin: 10px; padding: 10px; background: Red;
color: white; font-weight: normal; font-size: large;"><strong
style="color: White">'. $classPath .':</strong> Class doesn\'t
exist.</div>'; $importFile = str_replace(".", "/", $classPath) . $ext;
$path = pathinfo($GLOBALS["IORCA"]["BASE"]["PATH"] . $importFile);
$requirePath = '';
if($path['basename'] == "*$ext" && $importDir = opendir($path['dirname']))
{ while(false !== ($file = readdir($importDir))) {
if(stristr($file, $ext) == $ext) {
$requirePath = $path['dirname'] . "/$file";
if(file_exists($requirePath)) require_once($requirePath);
else echo($errorMessage);
}
}
}


I think what you are doing here is including every file in the directory
with *. What I am suggesting is, instead you add that path to
$GLOBALS["IORCA"]["CLASSPATH"][] so you can __autoload() classes from them
as necessary.

So, if your import statement looks like

import("org.active-link.xml.*");

Then you do not load any classes yet from import function - just add that
path to the classpath array and then when you do:

$myXML = new XML();

the XML class is __autoload() -ed by that function automatically as
required.

I hope I expressed myself clearer this time and hope this helps.
Jul 17 '05 #12
Zurab Davitiani wrote:
Berislav Lopac wrote:
I am very grateful for your script, as it gave me a great boost when
I created my internal little framework. I'll keep using it even with
PHP5, but I'd still like to make use of __autoload somehow.
Sure, that's what I suggested. You can delegate parts of your script
to __autoload instead of doing it manually. Let me elaborate:

function __autoload($class_name) {
foreach($GLOBALS["IORCA"]["CLASSPATH"] as $path) {
if(file_exists($path . $class_name . ".php")) {
require_once($path . $class_name . ".php");
break;
}
}
}


< snip>

I think what you are doing here is including every file in the
directory with *. What I am suggesting is, instead you add that path
to $GLOBALS["IORCA"]["CLASSPATH"][] so you can __autoload() classes
from them as necessary.

So, if your import statement looks like

import("org.active-link.xml.*");

Then you do not load any classes yet from import function - just add
that path to the classpath array and then when you do:

$myXML = new XML();

the XML class is __autoload() -ed by that function automatically as
required.

I hope I expressed myself clearer this time and hope this helps.


Yes, now I see what you mean. Basically, the import function adds the path
of a directory instead of including a specific file. This seems interesting,
as it forces the user to manually state which packages his class uses,
without the need to include specific class, or the entire package even if
not all classes are used. This seems quite reasonable and I'll look further
into it.

I was thinking of making an Autoloader class that whould handle all this, so
it could even include several different autoloading policies, chosen when
called by the __autoload.

A tangential question: does anyone has an idea which would have a better
performance -- iterating through an array as you suggest above, or finding
in an XML file using XPath and SimpleXML, assuming the same number of nodes?

Berislav

--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.
Jul 17 '05 #13
Berislav Lopac wrote:
A tangential question: does anyone has an idea which would have a better
performance -- iterating through an array as you suggest above, or finding
in an XML file using XPath and SimpleXML, assuming the same number of
nodes?


What would be the purpose of an XML file if all you want is a
one-dimensional classpath array that's created on the fly? What other
properties/attributes would you track? Almost certainly, an XML file would
need more memory and create more overhead.
Jul 17 '05 #14
Zurab Davitiani wrote:
Berislav Lopac wrote:
A tangential question: does anyone has an idea which would have a
better performance -- iterating through an array as you suggest
above, or finding in an XML file using XPath and SimpleXML, assuming
the same number of nodes?


What would be the purpose of an XML file if all you want is a
one-dimensional classpath array that's created on the fly? What other
properties/attributes would you track? Almost certainly, an XML file
would need more memory and create more overhead.


Because array must be iterated through, while a DOM document can be searched
via XPath by a simple /*/classname (or something; I must refresh my Xpath
skills). Of course that XML needs more memory, but I'd like to know
generally which is faster, iterating arrays or DOM document creation + Xpath
search. Intuitively I'd also go for the first, but I'm asking if someone has
any first-hand experience.

Berislav

--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.
Jul 17 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

699
33298
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro...
0
1312
by: Philippe Poulard | last post by:
I don't know if anybody already designed an URN scheme for XML; here is a proposal: I call it the "XML URN Scheme", or XUS. ========= URNs are logical names used to identify resources. XUS...
1
1193
by: Dale | last post by:
I am desiging validation method for our application. The application stores configuration and other data in the XML file. I want each time app opens XML file to validate the file against scheme. ...
4
3069
by: Kevin Newman | last post by:
The primary problem I've had with php is the lack of namespaces, which makes OOP very difficult to organize, since you end up with large number of classes cluttering up the same namespace - which...
8
2448
by: ulyses | last post by:
I'm trying to put pointer to flexible array of structures in other structure. I want to have pointer to array of pixels in screen structure. Here is mine code, but I think it isn't quite all right:...
3
2891
by: Giacomo | last post by:
Hi all. I just don't understand the behaviour of this: i have a few-webpages application in which I have these two files (and all the others) classes/class.User.php include/stdinclude.php ...
1
1261
by: turnitup | last post by:
I am rewriting an application to take advantage of the __autoload functionality. If I accidentally declare a variable in the parent class which was previously declared in a child class, the child...
3
1569
realin
by: realin | last post by:
hiya guys its been long since i posted here .. well i am using pattemplate which is a template tool for website development. But in my website's structure i have placed all my classes into a...
2
1964
by: Ixiaus | last post by:
I was curious (and have spent an enormous amount of time on Google trying to answer it for myself) if Python has anything remotely similar to PHP's SPL __autoload() for loading classes on the fly??...
0
6920
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7061
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7110
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7030
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
3015
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3011
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1313
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
574
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
210
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.