Hi,
Multiple namespaces per file were introduced to allow certain workflows in PEAR and frameworks like Symphony which can combine multiple classes and namespaces in a single package.
They work like this:
namespace X;
...
namespace Y;
...
The problem is, no one thought of scoping "use" statements, so now those merged files share their "use" imports, thus breaking all the code where collisions occur.
Also we have the problems with name resolution of internal vs user classes and autoloaders, discussed here.
And we also have the non-intuitive differentiation between resolving functions/classes/constant which will most likely lead people to believe functions/constants aren't supported in any way in namespaces (if they try, and it doesn't work, they won't try second time).
Which leads me to the following proposal:
For PHP 5.3 we introduce namespaces with a very limited "safe" set of barebones features, that we won't regret later for releasing and having to modify in a non-BC way. It'll let people start porting their code and be ready for the full featureset later on, which will be a proper superset of the 5.3 release:
-
We disable support for multiple namespaces per file as it is, as it can't be used without ability to scope "use" statements as well.
-
We remove the statement "use" (regarding namespaces, not regarding closures), until we get more feedback from the community on the exact preferred resolution algorithms, and more thought is put to this.
For PHP 5.4 or 6:
-
Introduce file-level "use" statements with same syntax as now, but modified resolution rules based on further discussion and feedback. And if someone is about to say "we had plenty of discussion", well it's apparent we didn't have enough given all the problems facing namespaces right now, or maybe not enough of the constructive type of discussion.
-
Introduce ability to scope "use" and "namespace" statements with curly brackets, so that multiple files can be safely merged without changing intent (all file-level namespace can be converted with curly brackets, and the existing curly bracket ones don't need to be converted), example:
namespace X {
use Y as Z {
...
}
}
namespace Y {
use X as Z {
...
}
}
Waiting for your feedback...
Regards,
Stan Vassilev
Stan Vassilev | FM wrote:
Hi,
Multiple namespaces per file were introduced to allow certain
workflows in PEAR and frameworks like Symphony which can combine
multiple classes and namespaces in a single package.They work like this:
namespace X;
...
namespace Y;
...
The problem is, no one thought of scoping "use" statements, so now
those merged files share their "use" imports, thus breaking all the
code where collisions occur.
Hi,
Stan, did you actually try this out? According to my checkout of CVS,
you're wrong. Try this script:
<?php
namespace one;
class one {
static function hi(){echo "hi\n";}
}
one::hi();
namespace two;
use one::one;
one::hi();
namespace three;
one::hi();
?>
The output is:
hi
hi
Fatal error: Class 'three::one' not found in
/home/user/workspace/php5_func/test.php on line 11
Greg
Stan Vassilev | FM wrote:
Hi,
Multiple namespaces per file were introduced to allow certain
workflows in PEAR and frameworks like Symphony which can combine
multiple classes and namespaces in a single package.They work like this:
namespace X;
...
namespace Y;
...
The problem is, no one thought of scoping "use" statements, so now
those merged files share their "use" imports, thus breaking all the
code where collisions occur.Hi,
Stan, did you actually try this out? According to my checkout of CVS,
you're wrong. Try this script:
What's the logic behind namespace declaration affecting file-level import
statements. Looks like such a hack to me.
Stan Vassilev | FM wrote:
Stan Vassilev | FM wrote:
Hi,
Multiple namespaces per file were introduced to allow certain
workflows in PEAR and frameworks like Symphony which can combine
multiple classes and namespaces in a single package.They work like this:
namespace X;
...
namespace Y;
...
The problem is, no one thought of scoping "use" statements, so now
those merged files share their "use" imports, thus breaking all the
code where collisions occur.Hi,
Stan, did you actually try this out? According to my checkout of CVS,
you're wrong. Try this script:What's the logic behind namespace declaration affecting file-level
import statements. Looks like such a hack to me.
???
I'm confused. First you say that merged files share "use" imports,
which is not true, then complain that namespace declaration affects
file-level import statements. Which one is the problem?
Greg
Greg
Hi Stan,
I realized I missed 2 of your points, response below:
Stan Vassilev | FM wrote:
Hi,
Multiple namespaces per file were introduced to allow certain
workflows in PEAR and frameworks like Symphony which can combine
multiple classes and namespaces in a single package.They work like this:
namespace X;
...
namespace Y;
...
The problem is, no one thought of scoping "use" statements, so now
those merged files share their "use" imports, thus breaking all the
code where collisions occur.Also we have the problems with name resolution of internal vs user
classes and autoloaders, discussed here.
I just posted a patch that solves this problem, and a few minutes ago
forwarded two messages that further clarify how the patch works and why
it is a good solution to the problem.
And we also have the non-intuitive differentiation between resolving
functions/classes/constant which will most likely lead people to
believe functions/constants aren't supported in any way in namespaces
(if they try, and it doesn't work, they won't try second time).
The other 2 patches I have posted solve these issues decisively.
Since these would change namespace edge cases and introduce a new way to
import, I think an alpha3 is warranted.
The name resolution changes should not affect any existing working code
that utilizes namespaces, but should make it possible to do autoload
without having to "use" every single namespace class.
The patches do need review, and I am certain the patch introducing
function::blah::here() could be better written, and needs a Sara/Dmitry
type to take a quick look and say what could be done to improve it.
However, I don't think these facts warrant removal of the key feature of
namespaces, especially since they are relatively easy to solve - these
patches did not take many hours to whip up, and do not change very much.
Thanks,
Greg
Hi Stan,
I realized I missed 2 of your points, response below:
Hi,
Thanks for your work on resolving these issues. My comments about
use/namespace being a hack regards just the syntax, I was wrong about the
scoping of use, but also having "namespace" act as a scope without the scope
syntax {} will possibly be confusing. But, it'll work fine enough.
Regards,
Stan Vassilev
Stan Vassilev | FM wrote:
Hi,
Multiple namespaces per file were introduced to allow certain workflows in PEAR and frameworks like Symphony which can combine multiple classes and namespaces in a single package.
They work like this:
namespace X;
...
namespace Y;
...
The problem is, no one thought of scoping "use" statements, so now those merged files share their "use" imports, thus breaking all the code where collisions occur.
Also we have the problems with name resolution of internal vs user classes and autoloaders, discussed here.
And we also have the non-intuitive differentiation between resolving functions/classes/constant which will most likely lead people to believe functions/constants aren't supported in any way in namespaces (if they try, and it doesn't work, they won't try second time).
Which leads me to the following proposal:
For PHP 5.3 we introduce namespaces with a very limited "safe" set of barebones features, that we won't regret later for releasing and having to modify in a non-BC way. It'll let people start porting their code and be ready for the full featureset later on, which will be a proper superset of the 5.3 release:
We disable support for multiple namespaces per file as it is, as it can't be used without ability to scope "use" statements as well.
We remove the statement "use" (regarding namespaces, not regarding closures), until we get more feedback from the community on the exact preferred resolution algorithms, and more thought is put to this.
For PHP 5.4 or 6:
Introduce file-level "use" statements with same syntax as now, but modified resolution rules based on further discussion and feedback. And if someone is about to say "we had plenty of discussion", well it's apparent we didn't have enough given all the problems facing namespaces right now, or maybe not enough of the constructive type of discussion.
Introduce ability to scope "use" and "namespace" statements with curly brackets, so that multiple files can be safely merged without changing intent (all file-level namespace can be converted with curly brackets, and the existing curly bracket ones don't need to be converted), example:
namespace X {
use Y as Z {
...
}
}namespace Y {
use X as Z {
...
}
}Waiting for your feedback...
Regards,
Stan Vassilev
Again, some more 2 cents from me.
I'm not sure if this has already been decided but I agree with multiple
namespaces per file. Just seems like a good practice for large
frameworks. And I'm leaning towards +1 on NON-brackets for namespaces.
With multiple namespace declarations in one file the way it is now,
brackets seem un-needed.
As far as the scope of "use" in a multi-namespace file:
Considering that in a multi-namespace file, a namespace declaration ends
the previous namespace and begins the new one. Can the scope of the
"use" statement be whatever namespace declaration it is in? Ex:
<?php
namespace X;
use A::B as Z;
Z::func(); // Is really A::B::func()
namespace Y;
use C::D as Z;
Z::func(); // Is really C::D::func()
?>
There are a couple benefits with this way:
-
If multiple namespaces have the exact same use statements, they won't
conflict. Because the scope of use only applies the current namespace
declaration. -
Merging multiple files is easier. Before the files are merged, the
developer would probably be testing their framework. This means that the
separate files have use statements in each one. When merging them all
together, the use statements won't conflict.
I agree that if use does not have a scope, it would become confusing. If
there wasn't, what would happen when there are two exact same use
statements. Or, if use statements point to different namespaces but have
the same name.
Another question when merging multiple files, is it ok to declare the
same namespace multiple times? If I were to merge files, I would just
append them all to one file.