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. 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 XMLParser.inc.php Transformer.inc.php
DBMysql.inc.php
FILE_SYSTEMFile.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.
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.
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.
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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):
|
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...
|
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
...
|
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...
|
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...
|
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...
|
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??...
|
by: Andrew G. Koptyaev |
last post by:
Is I can use include_once() or require_once() in function or only include()?
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
|
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...
|
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...
|
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,...
|
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...
| |