RE: AW: A rebuttal to Re: RFC: Dropping Namespace

php.internals

Ford, Mike [LSS]

18 years ago
On 07 December 2007 17:36, Gregory Beaver wrote:
> The suggestion to make "namespace __php__;" implicit is very > interesting, but would defeat its purpose, which is to separate > declarations from use.
Oh, I missed that little wrinkle -- I did say I was only skimming! I guess it could still be done, but at somewhat greater cost in the engine than I was imagining, which probably isn't worthwhile. Cheers! Mike --------------------------------------------------------------------- Mike Ford, Electronic Information Services Adviser, JG125, The Headingley Library, James Graham Building, Leeds Metropolitan University, Headingley Campus, LEEDS, LS6 3QS, United Kingdom Email: m.ford@leedsmet.ac.uk Tel: +44 113 812 4730 Fax: +44 113 812 3211 To view the terms under which this email is distributed, please go to http://disclaimer.leedsmet.ac.uk/email.htm

Jessie Hernandez

18 years ago
Hi Greg, How about this: any non-namespaced file that uses "use" statements is implicitly put into the __php__ namespace (or whatever other name is chosen, or having the namespace name be the path of the file)? With this, "use" will never import any symbols into the global namespace. Regards, Jessie Ford, Mike wrote:

Greg Beaver

18 years ago
Jessie Hernandez wrote:
> Hi Greg, > > How about this: any non-namespaced file that uses "use" statements is > implicitly put into the __php__ namespace (or whatever other name is > chosen, or having the namespace name be the path of the file)? With > this, "use" will never import any symbols into the global namespace.
Hi Jessie, Imagine how that would affect this code: file1.php: <?php function doSomething() {} ?> PEAR2/DB.php: <hypothetical> <?php namespace PEAR2; class DB {} ?> file2.php: <?php include 'file1.php'; include 'PEAR2/DB.php'; use PEAR2::DB; $a = new DB; $b = doSomething(); ?> In file2.php, because there is a "use" statement, the rest of the file is assumed to be in the __php__ namespace. As such, the file can be expanded into this code: new_file2.php: <?php namespace __php__; include 'file1.php'; include 'file2.php'; $a = new PEAR2::DB; $b = doSomething(); ?> On the last line, when PHP calls doSomething(), it first checks to see if the function "doSomething" is available as an internal function. Then, it tries __php__::doSomething() and fails on a fatal error because the function does not exist. The only way that your idea would work is if the check for "doSomething" consisted of checking for any non-namespaced function (not just internal functions), but the sole purpose of the fall-through is to allow users to call internal functions/classes without explicitly specifying ::strlen or ::count and so on. Allowing fall-through to any global class/function would serve to dilute the namespacing effect, but perhaps this is a good thing? I have not thought about this long enough to have a definitive opinion yet. I think one safe way to handle this might be to have an E_STRICT if class/function/const is declared in the __php__ namespace, so that PHP provides a clear mechanism for enforcing the convention. Users wishing to avoid this E_STRICT need only use another namespace name or adhere to the coding convention of only putting stuff that uses code into the __php__ namespace. Greg

Jessie Hernandez

18 years ago
I thought global names were considered in the patch, but now that I re-read Dmitry's post, only symbols in the namespace and internal symbols are considered. I read through most of the posts regarding namespaces, but could not find a reason why global names are not looked up. Classes/functions should first be looked up in the current namespace, if not found, then they should be looked up in the global namespace, and if it is not found there either, then there should be a check to see if there is an internal class/function with the same name. Dmitry, what's the reason this lookup logic wasn't used in your patch? Regards, Jessie Gregory Beaver wrote:

Sam Barrow

18 years ago
I agree with this 100%, is this something that could be changed? I don't see a reason behind it. On Sun, 2007-12-09 at 16:24 -0500, Jessie Hernandez wrote:

Greg Beaver

18 years ago
Sam Barrow wrote:
> I agree with this 100%, is this something that could be changed? I don't > see a reason behind it. > > On Sun, 2007-12-09 at 16:24 -0500, Jessie Hernandez wrote: > >> internal class/function with the same name. >> >> Dmitry, what's the reason this lookup logic wasn't used in your patch?
Hi, Actually, there several good reasons. For one, every single unknown class declaration inside a namespace would require a double check of class existence, hitting performance. Here's another example showing the "gotcha" that is inherent: file1.php: <?php namespace Foo; class IwantThis {} ?> file2.php: <?php class IwantThis {} ?> file3.php: <?php namespace Foo; include 'file2.php'; function __autoload($class) { include 'file1.php'; // stupid but illustrates the point } $a = new IwantThis; ?> Currently, executing file3.php would result in this logic chain: 1) does Foo::IwantThis exist? no => step 2 2) does internal class IwantThis exist? no => step 3 3) try autoloading Foo::IwantThis, loads file1.php, now Foo::IwantThis exists If this logic chain were changed to instead check for any globally defined class of that name, the logic chain would be: 1) does Foo::IwantThis exist? no => step 2 2) does ::IwantThis class exist? yes => use ::IwantThis In other words, it would completely break autoloading for namespaced classes. Of course, this is the same problem as conflicting with internal classnames, but the scope of the problem is far larger because there are so few classes internal to PHP, and even fewer that are likely to conflict with unqualified names. So, it could be changed (patch attached for 5.3 to prove the concept, it's not the best way to do this but shows the way it could be done), but the price would be an absolute requirement that all classes be explicitly "use"d in some manner inside a namespace. Greg

Dmitry Stogov

18 years ago
Jessie Hernandez wrote:
> I thought global names were considered in the patch, but now that I > re-read Dmitry's post, only symbols in the namespace and internal > symbols are considered. > > I read through most of the posts regarding namespaces, but could not > find a reason why global names are not looked up. > Classes/functions should first be looked up in the current namespace,
right.
> if not found, then they should be looked up in the global namespace,
never. I have no idea why do you think they should look there...
> and if it is not found > there either, then there should be a check to see if there is an > internal class/function with the same name.
Today all internal classes/functions are in the global namespace. We allowed usage of internal names in namespaces, because it would be terrible to prefix each usage of internal function like strlen(), write(). Dmitry.