Re: autoload with namespace

From: Date: Wed, 02 Apr 2008 16:59:55 +0000
Subject: Re: autoload with namespace
References: 1 2  Groups: php.general 
Request: Send a blank email to php-general+get-272451@lists.php.net to get a copy of this message
Nathan Nobbe schreef:
On Tue, Apr 1, 2008 at 8:28 PM, Ryan Panning <rpanning@gmail.com> wrote:
I haven't been keeping an eye on this list so if this has come up before please point me in the right direction. :) Playing around with dev PHP 5.3 and namespaces, I'm finding it hard to write an autoload function. Since autoload will be triggered on any namespace call, the request could be for a namespace function or constant. Ex: FOO::BAR::me() ## A namespace function or class static function? FOO::BAR::ME ## A namespace constant or class constant? Since there isn't really a way for PHP to know what it is looking for, what would be a good method to write the autoload? Assuming the file structure: - Namespaces are in separate directories NS1::NS2::Class1 == NS1/NS2/class.Calss1.php - Namespace files and class files are prefixed with ns.*.php and class.*.php (respectively)
i havent gotten the chance to work w/ 5.3 yet (been burried w/ other crap lately) anyways ive been wondering about an autoloader in 5.3 so this is a cool thread ;) well i would probly just extend my mechanism for pre-5.3 and that is essentially to populate an array of absolute paths to your files. in ur case each path would map directly to a package followed by the class that contains it. so then ur autoloader just looks at the mapping when a request comes in, checks the appropriate index in this array and calls require or w/e on the abs path. there is one curiosity / caveat underlying the 5.3 implementation... so does the namespace get supplied to the autoload function as well as the class name? is it just one big string or are they separate?
one big string. how does php know before hand whether foo::get() is a namespaced function call or a static class method call? the OP has a point about autoloading this stuff - I can only see problems arising, mostly because the namespace seperator is the same as class/method seperator ... something that seems to be compounded by the fact that you can spoof nested namespaces ala: namespace My::Pseudo::Nested::NS; I have been following the namespace developments and have my doubt that it solves the symbol clashing issues in a way that doen't just move the headache to somewhere else (as opposed to eradicate it). I haven't bothered to play with it yet ... I figure the functionality will require a few version before the wrinkles are ironed out. much like the php5.0 OO functionality was a fast moving target, much less so in more recent versions. one day namespaced php code will be the norm, one that day Richard Lynch will either announce his retirement (I hope not) or that he's decided to move over to the OO camp (one man can only offer so much resistance ;-). an issue I have with namespaces is that they aren't packages as you might fin d in other langs, but you do seem to be tied into a particular development model (one namespace per file, namespaces in their own file) ... something php has not really done before: upto now you have complete control over how you split your code into files ... one big 'compiled' file is fine ... that is something not yet possible if namespaces are used (this is the point your supposed to STA the internals list for the brackets/no-brackets and multiple-namespaces-per-file discussions) I wouldn't bother trying to figure out an autoloading strategy for namespaces until the namespaces api/functionality has settled properly, otherwise your likely to have to rewrite the autoloader over and over. essentially it boils down to replacing '::' with '/' to determine the path from the namespace in your case - that is easy enough, your still stuck with finding out whether your being asked to load a namespace, class, or function (do namespaced functions even trigger an autoload, if not that obviously makes things simpler. maybe the autoloader can just match the path as deep it can and then load every file inside the determine path. e.g: $c = 'MY::NS::Cls'; function __autoload($c) { $r = '/usr/var/myproj/lib`'; $p = explode('::', $c); if (count($p) == 1) { // load a class return; } do { $d = $p.'/'.join('/', $p); if (is_dir()) { recursivelyRequireMyPhpFiles($d); return; } array_pop($p); } while (count($p)); }
-nathan


« previous php.general (#272451) next »