473,398 Members | 2,403 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

include_once/__autoload/namespace emulation ...

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 leads to a secondary
problem involving php's __autoload feature. Since you cannot specify a
namespace when calling a class that may not have been included, you are
forced to store all of your classes in the same folder in your file
system. This can get quite unwieldy. I've also read that __autoload has
a performance hit over using a standard include (I'm not sure if this is
still true). Finally, I've read that require_once can be very buggy in
the php documentation comments. (Is that true?)

After thinking about the namespace problem, I've concluded that php's
conditional include nature keeps the runtime environment pretty clean
(if I have two classes with the same name, I don't usually have to worry
about it, since I will usually only include one at a time) and its
runtime footprint small. While it's not perfect, it does provide enough
of something like runtime namespace protection, at least enough to keep
me from creating a bulky framework to emulate more robust namespaces.

This left me with the problem of organizing all of my class files on the
file system. I do not want to keep 100s of classes in the same one
folder - especially since there are many classes in there that will
probably not be used, but I'd like to keep around for just in cases.
Since __autoload seems to have performance issues, I decided not to use
that either. (Is this still an issue?)

Since I've decided that for my needs php's include functions are a good
enough substitute for real namespace imports I just needed a way to load
class files that are organized in a namespaces like folder structure. I
would have just used require_once, but it has those bugs I mentioned. So
I came up with a single function that I named "using" (borrowed from
..NET and Prado - which actually has a pretty spiffy solution to the
namespace problem that uses __autoload).

Here is the function (it is horribly unoptimized and probably buggy):

$namespaces = array();
$classPath = 'C:/Inetpub/wwwroot/_domains/adcecart/_includes/';
/**
* Includes class files, which are stored in Namespace like folders
* @param string colon delimited namespace string.
*/
function using($namespace) {
global $namespaces, $classPath;

// quick return if repeat import
if(isset($namespaces[$namespace])) return;

// convert $namespace to path
$path = $classPath . str_replace(':','/',$namespace);

if (is_dir($path)) {
// add namespace to hash (to avoid double import)
$namespaces[$namespace] = $namespace;

// add all files in the directory
$dir = dir($path);
while (false !== ($entry = $dir->read()) ) {
if (preg_match('/.php$/i', $entry)) {
$newNamespace = str_replace('/',
':', substr($namespace.'/'.$entry, 0, -4));

if (!isset($namespaces[$newNamespace])) {
$namespaces[$newNamespace] = $newNamespace;
require_once($path.'/'.$entry);
}
}
}
$dir->close();

} else if (is_file($path.'.php')) {
$namespaces[$namespace]=$namespace;
require_once($path.'.php');
} else
exit('Error importing namespace.');
}

// used like this
using('unFocus:Feature:ClassName');
This actually does one more thing than a simple enhanced require_once -
it can import all of the php files in a specific folder (or namespace).
I don't use this feature, and will probably remove it unless I find some
need for it.

This function works differently (and I use it differently) than a
regular namespace implementation would. In other languages, namespace
imports (or using) are tied to the specific class file scope, and only
applied to class within that class. As far as I can tell, php has no
similar scoping rules (since it is an inline interpreter, unless
something has changed that I am unaware of), so this will just include a
class file (and anything else that might be in that file actually - like
spare functions or variables), and dump all that into the global scope
(except variables).

This can also be used with performance in mind - let's say you want to
use a class from another class, and you will only need it if conditions
are met. You don't have to import the class if you don't need it, saving
memory, parsing, and cpu time. To me this is a benefit, since php is
really an inline interpretor at the end of the day (unless you use an
opcode cache I guess).

At this point really just rambling, so I'll just finish up with a summary.

The goal was to be able to organize and group my class files in some
kind of reasonable way - namespaces provided that way, but are
unavailable in php. Understanding the nature of php's inline
interpretation, conditional includes and __autoload's inability to cope
with a namespace like directory structure and its possible performance
consideration convinced me that a simple require_once function used with
classes named carefully would actually be adequate to make sure I was
only importing classes that I needed and that they would not clash with
one another or with built in php classes (I've never run into that
problem yet). After trying out a bunch of different namespace solutions,
I wrote a simple function (which can be a lot simpler) that will include
the necessary class files only once, when they are needed, and not
before, from within their namespace like directory structure.

Now the question! :-) Basically - What do you think of my reasoning and
rational?

Also, if I'm wrong about any of the details of how PHP works, I'd
appreciate some clarification on anything I got wrong.

Thanks,

Kevin N.
Nov 28 '05 #1
4 3065
Namespaces and PHP are certainly an issue, some of the things you wrote
I have never heard of before, like require_once being bugged.

Pear is a good example of how namespaces should be done but I would
suggest an even simpler solution.

Say you have a folder structure like:
classes

XML
Parser.inc.php
Transformer.inc.php
DB
Mysql.inc.php
FILE_SYSTEM
File.inc.php


They you should have an auto load function like:

function __autoload( $class )
{
$load = strtolower( str_replace( "_", "/classes/", $class ) ) .
".inc.php";
if( file_exists( $load ) )
{
include_once( $load );
}
else
{
die( "Can't find a file for class: $class \n" );
}
}

Now you can have

$obj = new XML_Parser();

(example adapter from http://www.wiki.cc/php/Overload_autoload).

This makes things allot easier. The drawback is it is not php4
compatible.

Nov 29 '05 #2
Sean wrote:
Namespaces and PHP are certainly an issue, some of the things you wrote
I have never heard of before, like require_once being bugged.

Pear is a good example of how namespaces should be done but I would
suggest an even simpler solution.

Say you have a folder structure like:
classes

XML
Parser.inc.php
Transformer.inc.php DB
Mysql.inc.php FILE_SYSTEM
File.inc.php


They you should have an auto load function like:

function __autoload( $class )
{
$load = strtolower( str_replace( "_", "/classes/", $class ) ) .
".inc.php";
if( file_exists( $load ) )
{
include_once( $load );
}
else
{
die( "Can't find a file for class: $class \n" );
}
}

Now you can have

$obj = new XML_Parser();

(example adapter from http://www.wiki.cc/php/Overload_autoload).

This makes things allot easier. The drawback is it is not php4
compatible.


I thought of that, but doesn't it try to load "XML_Parser" from within
the class file, instead of just "Parser"? In some cases that would lead
to to huge class names (and a lot of typing).

Also, I've read that there is a performance problem with __autoload -
has that been taken care of? (I read that php 5.1 improved some of the
performance issues with magic functions.)

I really wish the php guys would just implement at least class level
namespaces (they already have a patch).

Kevin N.
Nov 29 '05 #3
I think I messed up my example $obj = new XML_Parser(); should load
/classes/xml/parser.inc.php which simplifies things (if I did mess up
the website I quoted has it done right). And it also means allot less
typing. No more 10 lines of includes at the beginning of your scripts.
Just an autoload.

Again I have never heard of performance issues with autoload. In work I
do in php I don't even use that function though.

There are allot of improvements to php that need to be made. Class
level namespaces probably being one of them, removal of magic quotes
and register globals and so on. Where php is at the moment they can't
really change too much without the risk of breaking backwards
compatibility.

Nov 29 '05 #4
On Tue, 29 Nov 2005 15:33:06 GMT, Kevin Newman <Ca******@unFocus.com>
wrote:
I thought of that, but doesn't it try to load "XML_Parser" from within
the class file, instead of just "Parser"? In some cases that would lead
to to huge class names (and a lot of typing).
Huge class names really isn't an issue. You just don't 'new' objects
very often. Unlike in C# or Java, you don't have to declare the types
of variables so you just don't end up using full class names very
often at all.

I have a PHP5 project with 446 classes, arranged in the hierarchy
(XML_Parser is in XML/Parser.php) and I use __autoload.
Also, I've read that there is a performance problem with __autoload -
has that been taken care of?
I never experienced any performance issues with __autoload. In fact,
a quick googling for "__autoload performance" leads to a number of
posts/articles saying how it has improved performance of applications.

This makes sense, as __autoload only loads classes on demand. With
require/include you're loading classes whether or not you are actually
using them.
I really wish the php guys would just implement at least class level
namespaces (they already have a patch).


I honestly think you're over-thinking this. In reality, namespaces
are simply not the issue in PHP as they are for other languages. I
just use nice long class names.

Nov 29 '05 #5

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

Similar topics

14
by: Berislav Lopac | last post by:
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...
16
by: Chris | last post by:
Is there any way to make the class Z behave the same way as class Y? Chris class Y: value = 42 def __hasattr__(self, name): if name == '__int__': return True def __getattr__(self, name):
3
by: Richard A. DeVenezia | last post by:
Any recommendations for deploying small to middling JavaScript system that encompasses 10-20 functions ? The problem is the potential that another other JavaScript system running on the same...
3
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 ...
15
by: Mikhail Kovalev | last post by:
Hi all, I have a file which is to be included in another script and which takes several seconds to load(!), and which is actually not always used by the script, so instead of using include or...
1
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
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
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??...
4
by: Andrew G. Koptyaev | last post by:
Is I can use include_once() or require_once() in function or only include()?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
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
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.