Dangit, I wasn't finished when that sent (apparently Ctrl-S sends a message - I was trying to Ctrl-V to paste)
Gregory Beaver wrote: > Hi again, > > I am not sure this will make it through the noise *sigh* but I'll give a > try :) > > Derick Rethans wrote: > >> Hei, >> >> now some patches by Greg and Dmitry made it into CVS, some of the things >> in my mail have been resolved, however, we still need to come up with a >> solution to the 1st and most important issue: >> >> On Tue, 4 Dec 2007, Derick Rethans wrote: >> >> >> >>> 1. As it is impossible to do "use XXX as NativeClass" we get to the >>> point where we'd have to namespace new internal native classes >>> otherwise we might introduce BC breaks. AFAIK, we've always said that >>> PHP reserves the globals space for it's own use (see also: >>> http://www.php.net/manual/en/userlandnaming.rules.php). In case we do >>> add new classes (an example could be DateTimeSpan), they should of >>> course follow the same format as already existing classes in the >>> extension (DateTime, DateTimeZone). However introducing the new class >>> DateTimeSpan might break people's code that do things like: >>> >>> <?php >>> use myNamespace::DateTimeZone as DateTimeZone; >>> ?> >>> >>> feature versions of people would then show: >>> >>> Fatal error: Cannot use myNamespace::DateTimeZone as DomDocument >>> because the name is already in use. >>> >>> It would be silly to require to have to do this: >>> >>> - Create a class PHP::Date::TimeSpan >>> - In your scripts: >>> use PHP::Date::TimeSpan >>> >>> But with the current implementation, this seems to be the only non-BC >>> breaking solution. If we chose *not* to require this silly namespacing >>> of internal classes, users instead have to do this: >>> >>> <?php >>> use myNamespace::DateTimeZone as myDateTimeZone; >>> ?> >>> >>> Basically prefixing the classnames... This you can already do just >>> fine without namespaces. >>> >>> >> I know Greg has some ideas with __php__ as recommendation, but I find it >> a bit clumsy still. Perhaps Greg can summarize how it will address the >> above issue? >> > I've been thinking quite a bit about several suggestions (surprise > surprise). First of all, Marcus Boerger suggested on IRC that "__php__" > was not the best name, and proposed "__user__" as a more logical choice > for the convention, which appeals to me more for the obvious reason that > it doesn't have the chance of confusing with "PHP" or "php" should > either of these be adopted by the core folks ever. > > I am going to use some shorthand. "internal class is used first" means > this code: > > <?php > namespace hithere; > $a = new Exception('hi'); > ?> > > would use ::Exception unles hithere::Exception already exists. > > In my inimitable style, for the larger suggestions I've been thinking > about I will list them: > > 1) having an implicit namespace for unnamespaced code > 2) never accessing internal classes inside a namespace (tough to > summarize I explain below) > 3) allowing override of internal classes with "use" in the global scope > 4) keep things the way they work now, and recommend using "namespace > __user__" for userspace code. > > 1) having an implicit namespace for unnamespaced code > ===================== > > > This is an interesting idea that will break autoloaders unless the > implicit namespace is automatically stripped on a call to autoload, > get_class() and reflection. > > Pros: > use myNamespace::DateTimeZone as DateTimeZone; will always work as intended > > Cons: > slight performance hit on every autoload caused by a strstr() check on > classname for "__auto__::" and same hit on get_class(), ReflectionClass > stuff > large number of potential "oops" spots for the implicit namespace to > slip into code and break everything horrendously. > the patch would be huge and very dangerous for the above reason until > kinks are worked out. > doesn't solve the "internal class is used first" issue. > > 2) never accessing internal classes inside a namespace > ===================== > > This basically means changing the autoloading rules to the following > (using the hithere namespace/Exception example from above): > > 1) does hithere::Exception exist? > 2) if not, autoload it > > Pros: > it is not necessary to "use hithere::classname" for every class you > might autoload. > 1 hash lookup reduced per autoloaded class (very minor performance gain, > hash lookup is O(1). profiling might not even detect a difference.) > > Cons: > to use internal classes, you would need to explicitly use ::Classname; > for each of them. > Code that does not use autoload would *also* have to explicitly use > ::Classname; > code that uses internal classes that wishes to become namespaced would > need to go through and figure out which internal classes are used and > add "use ::Classname" at the top of the file, making porting to > namespaces much more difficult. > > 3) allowing override of internal classes with "use" in the global scope > ===================== > > This would be surprisingly easy to implement, currently the only thing > preventing it from happening is a 5-10 line check in zend_do_use() to > see if the name requested would conflict with an internal class. Remove > that check and it becomes possible > > Pros: > Derick's main issue goes away, name conflicts with internal classes are > never possible when "use"ing them > it becomes possible to change which class is used in a file with 1 line > of code: > > <?php > use myNamespace::Exception as Exception; > ?> > > As opposed to two: > > <?php > namespace __user__; > use myNamespace::Exception as Exception; > ?> > > Cons: > It is then possible to accidentally override an internal classname used > in the code. > it encourages continuing to declare classes/functions in the global > namespace, resulting in potential name conflicts a la "Date" > > 4) keep things the way they work now, and recommend using "namespace __user__" for userspace code. Pros: explicit declaration of namespace can make code clearer Cons: users using global namespace and "use" will get burned. ========= As a reality check, in the entire lifetime of PHP, there has been only 1 name collision between new PHP classes and pre-existing major classnames. SplFileInfo was originally a conflict, but that was solved with a simple prefix to the classname of "Spl." This is an issue, but until PHP starts adding billions of classes to handle core elements, it is not a large one. However, it can be easily and simply solved, so I say why not :). After enumerating the pros/cons of each point, my personal opinion is that #1 and #2 are not feasible from either a user or a core developer standpoint, and would create more problems than they would solve. #3, however, looks much more appealing than I thought it would. I think this is a good idea as an addition. I might be inclined to ask for an E_STRICT warning that "use My::Exception;" is overriding an internal class, but that's up to what you all think. Implementing #3 would remove the con of #4. To answer Derick's call for clarification on #4, The convention of using the __user__ namespace for all code that uses namespaced code would force users to do two things: 1) explicitly "use" classnames they wish to shorten by importing them from another namespace 2) add "namespace __user__" to the top of their files. These two things would mean 1) autoload always works as intended 2) classes from external projects (dependencies not found in the current file) are always documented prominently at the top of the file, increasing maintainability if the project passes on to another developer. 3) the presence of "namespace __user__" would also immediately document the fact that this code is intended to be executed and is not library code (does not declare classes/functions and only uses them) Point #1 does not matter to people who don't use autoload, but #2 and #3 both increase the ease of understanding the purpose of code. I've often had trouble sifting through source code to find the main files that are executed. If I could have done a simple "grep -e namespace __user__" it would make things a lot easier that way. Thanks, Greg -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php