Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:33827 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 99254 invoked by uid 1010); 7 Dec 2007 14:47:54 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 99238 invoked from network); 7 Dec 2007 14:47:54 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Dec 2007 14:47:54 -0000 Authentication-Results: pb1.pair.com header.from=derick@php.net; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=derick@php.net; spf=unknown; sender-id=unknown Received-SPF: unknown (pb1.pair.com: domain php.net does not designate 82.94.239.7 as permitted sender) X-PHP-List-Original-Sender: derick@php.net X-Host-Fingerprint: 82.94.239.7 mail.jdi-ict.nl Linux 2.6 Received: from [82.94.239.7] ([82.94.239.7:34716] helo=mail.jdi-ict.nl) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 45/16-00959-81D59574 for ; Fri, 07 Dec 2007 09:47:53 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.jdi-ict.nl (8.13.7/8.12.11) with ESMTP id lB7Elk7Z013191; Fri, 7 Dec 2007 15:47:46 +0100 Date: Fri, 7 Dec 2007 15:47:48 +0100 (CET) X-X-Sender: derick@kossu.ez.no To: Gregory Beaver cc: PHP Developers Mailing List In-Reply-To: <4758A390.4040402@chiaraquartet.net> Message-ID: References: <4758A390.4040402@chiaraquartet.net> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=UTF-8 Subject: Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace From: derick@php.net (Derick Rethans) 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 > > > extension (DateTime, DateTimeZone). However introducing the new class > > DateTimeSpan might break people's code that do things like: > > > > > 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: > > 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__. > > 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: > > 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: > > 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: > > namespace foo; > echo strlen('hi'); > include 'maliciousfile.php'; > echo strlen('hi'); > ?> > > maliciousfile.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