Anyone who hasn't been hiding under a rock knows that the PHP 5.3 alpha has come and gone, and one of its "selling points" is a new namespace implementation.
The first thing to clarify is that I like the new implementation overall, it's fairly light and although it isn't really namespacing or packaging in any sense of the word, the best way to describe it is aliasing, it does help keep code easy to use. In fact I have a couple of projects and even a PHP extension that's all namespaced code.
However, there are 5 things that drive me nuts about it (well 4 and 1/2, the last one has a workaround), that I really think should be fixed before the namespace implementation is finalized.
1. multiple namespaces in a file -
currently there's ...odd support... for multiple namespaces in a file. I won't reiterate all the arguments this way or that way about whether multiple namespaces in a file is a good or bad thing. Bottom line is people WILL want to put more than one namespace in a file at some point. I'm pretty easy to please on this point though. If your file only has one namespace, then you should use the current syntax
[php] ?php
namespace foo;
// code goes here
?>[/php]
If you have more than one namespace in a file, then block syntax should be used.
[php] ?php
namespace foo {
// foo code goes here
}
namespace bar {
//bar code goes here
}
//this is global code
?>[/php]
Pretty simple and easy to understand.
2. My second issue with namespaces is you can't have ANYTHING before the namespace statement but an opening ?php tag
some might argue "well you don't want anything" - but why should it fatal error because I have a space before that opening
--FILE BEGINNING --
?php
namespace foo;
?>
--FILE BEGINNING --
?php
namespace foo;
?>
You can't tell me that won't be a WTF for new users.
3. The autoload and resolution paths
This is one that although it annoys me, I could live with the current implementation. However it is odd. If you do not explicitly have a use statement for every class, your load order could affect which class is actually used. Greg describes this a lot better than I do, so you can judge for yourself which resolution and autoload order would work better.
4. Functions in namespaces
You can't use a function like you can a namespace or class - you can never "import" a function from a namespace into your global scope with a use statement. That means you'll always need to use Foo::bar(); instead of just bar(); I've argued my head off about WHY I'd want to import into the global scope, but all I get is "you shouldn't design code that way" or "being able to override internal php functions will let users shoot themselves in the foot" (ahem...goto anyone?) even though it's perfectly legal with classes... rather than a good technical or architectural reason why it shouldn't be done.
So functions in namespaces won't work like classes in namespaces - just a warning to anyone doing procedural code thinking this will help them without total retraining to call all functions as though they were static methods. Oh, and a warning. Since you can't alias in a function you can get ambiguity if a function in a namespace and a static method in a class end up having the same name - the function becomes unusable. Great huh? You don't even get a warning if you do something that silly.
5. No use * and three million use statements
To get autoload to work right, you need an explicit use statement. To not have to use some kind of prefix on your code, you have to use a use statement. To make namespaces function right, you have to use LOTS of use statements. Unless you just want to "shorten up" the code - so instead of PEAR2::HTTP::Request you could alias it in as Request - and then use Request::URI and Request::Exception and Request::Adapter::PHPStream I don't know about you, I thought the point was to avoid that and just have Exception and PHPstream and URI - anyway.
This issue has a workaround. There's a nifty (undocumented) function called class_alias that you can use to, well, alias classes. A clever static method in PEAR2::HTTP::Request - maybe named import_package? - could do the equivalent of all those use statements for you using class_alias, and you'd be all set to use it in your code as though it was in global scope. Anyway, that's why this only counts as half a gripe - it can be worked around although the solution could be termed "hackish".
Dreaming of Dawn








Joshua Eichorn
The biggest issue to me is #4
1: function calls in a namespace looking like static method calls is not a matter of taste its a huge WTF
2: class with same name as namespace and static method hiding functions in namespace is a bug and should have a fix
3: I want to override built in php functions (maybe i want to fix a string function not covered by mbstring without auditing all my code)
4: I it would be nice to be able to alias over other userland functions if I want. Maybe i'm transitioning from one functional library to another etc
And an overall comment
To me namespaces are a solution to _ organization of code that lets me type less due to use aliasing. I don't need namespaces to organize my code, I can prefix with long names easily enough as it is. I need namespaces to organize my code without punishing end users of libraries with lots of typing.
2008-09-08 3:29 pm