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