On Thu, 6 Dec 2007, Gregory Beaver wrote: > I've been thinking a *lot* about your provocative email in the past > couple of days, and have come to a different conclusion from my original > reply (which, as a reminder stated I saw no problem with removing > namespaces as long as we kept the import facility to alias classes via > use). After a few hours of thinking practically about the > implementation, I realized that this would be impossible for the same > reasons as your first argument. So, I set out to find a solution that > keeps namespaces and solves the problems.
Right, that was the idea behind the mail :) As yours is pretty long, I'm only going to respond to the main points. > 1) recommend all global non-namespaced code that wishes to import > namespaced code via "use Namespace::Classname" add a "namespace > __php__;" at the top of the file, and that the __php__ namespace be > reserved for use by end-user applications. > > 2) use Name::*; is technically impossible without some kind of > autoloading mechanism, but can be reasonably approximated by importing a > long namespace name as a shorter one. "use PEAR2::Really::Long::Name as > a;" then allows referring to PEAR2::Really::Long::Name::Classname as > a::Classname, and PEAR2::Really::Long::Subnamespace::Classname as > a::Subnamespace::Classname. > Yeah, I know... I don't really care about this myself anyway - it's just something that I heard in discussions. [snip] > > Detailed answers: > > Derick Rethans wrote: > > 1. As it is impossible to do "use XXX as NativeClass" we get to the > <snip> > > extension (DateTime, DateTimeZone). However introducing the new class > > DateTimeSpan might break people's code that do things like: > > > > <?php > > use myNamespace::DateTimeZone as DateTimeZone; > > ?> > > This is indeed the biggest problem. However, it only exists in the > global "namespace" (non-namespaced code). An example script using the > non-existing hypothetical PEAR2::DateTime class: > > <?php > include 'PEAR2/Autoload.php'; > use PEAR2::DateTime; // fatal error - use name conflicts with internal class > $a = new DateTime; > ?> > > However, the answer is simple and elegant. PHP applications that take > advantage of namespaces should use a namespace *in the application > global code* that is reserved for application code, like __php__. > > <?php > namespace __php__; > include 'PEAR2/Autoload.php'; > use PEAR2::DateTime; > $a = new DateTime; // $a is an object of class PEAR2::DateTime after > autoloading, or if a previously included file has declared class > DateTime in namespace PEAR > ?> > > Note that the only difference here is the addition of 1 line of code at > the top of the file. On the same token, this code: > > <?php > namespace __php__; > $a = new DateTime; // $a is an object of class ::DateTime > ?> > > works as expected, accessing the internal DateTime class directly. > > In other words, 1 line of code is needed to take advantage of > namespace's full protection and ability to import conflicting class > names into the "global" (in this case unqualified, not containing :: in > the name) scope, while at the same time preserving BC with existing code > (no modification needed beyond addition of "namespace __php__;"). > > I recommend that the manual specify this convention, and will happily > take on the documentation of it. > > 2. You have to import every class yourself. You can currently not do: > > > > use myNamespace::* as *; // or similar syntax [snip] > > There are ways of simulating "use myNamespace::* as *;" that are almost > as complete and are actually better for long-term maintenance. For > instance, let's say you want to use several classes from > PEAR2::Ultra::Long::Package::Name. You don't need to use each class > individually, you can import the entire namespace: > > <?php > namespace __php__; > use PEAR2::Ultra::Long::Package::Name; > $a = new Name::ExampleClass; > $b = new Name::SecondThing; > $c = new Name::ThirdThing; > ?> Sounds like a good idea. > I have no strong opinion on {}, but I do see a compelling argument in > favor of not using {} for performance reasons if you're only going to > use 1 namespace per file except in extraordinary circumstances. The only thing that in the case you *have* a multi-namespace file, using braces would editors allow to the start and end of a namespace easily (f.e. VIM's %). > A larger danger is this example: > > <?php > namespace foo; > echo strlen('hi'); > include 'maliciousfile.php'; > echo strlen('hi'); > ?> > > maliciousfile.php: > <?php > namespace foo; > function strlen($a) > { > // do bad stuff > echo "I'm evil" > return ::strlen($a); > } > ?> > > The above script outputs "2I'm evil2" - foo::strlen() is called for the > second call to strlen(). I thought only constants and classes could be parts of namespaces? regards, Derick -- Derick Rethans http://derickrethans.nl | http://ezcomponents.org | http://xdebug.org -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php