rfc:namespaces
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:namespaces [2008/09/15 00:45] – link to and deascribe patches (by greg), not completed jochem | rfc:namespaces [2008/09/16 00:07] – tweak jochem | ||
---|---|---|---|
Line 28: | Line 28: | ||
- via functional changes to the current implementation | - via functional changes to the current implementation | ||
- | - via the introduction of functional limitations (e.g. **E_WARNING** or **E_FATAL** errors) that alert php users to problems with there use of namespaces | + | - via the introduction of functional limitations (e.g. **E_WARNING**, **E_PARSE** or **E_FATAL** errors) that alert php users to problems with there use of namespaces |
- via user education, to this end a seperate document is being developed in order to define guidelines and 'best practices' | - via user education, to this end a seperate document is being developed in order to define guidelines and 'best practices' | ||
Line 35: | Line 35: | ||
The following issues have been put forwards by various members of the php developers group and php users at large, the issues are covered in the following sections: | The following issues have been put forwards by various members of the php developers group and php users at large, the issues are covered in the following sections: | ||
- | - 1. global & namespaced code in one file | + | - 1. **global & namespaced code in one file** |
- 2. define() & defined() | - 2. define() & defined() | ||
- 3. Autoload & functions | - 3. Autoload & functions | ||
- | - 4. You can **use** anything | + | - 4. You can use anything |
- 5. Importing NameSpace:: | - 5. Importing NameSpace:: | ||
- | - 6. Static methods/namespaced function ambiguities | + | - 6. **Static methods |
- | - 7. **use** and includes | + | - 7. **Class constants v. namespaced constants ambiguities** |
- | - 8. Importing functions | + | - 8. use and includes |
- | - 9. Name resolution order | + | - 9. **Importing functions** |
- | - 10. Keywords in namespace names | + | - 10. **Name resolution order** |
- | - 11. Namespace must be first declaration in file | + | - 11. Keywords in namespace names |
- | - 12. Namespaces aren't implemented like in ... | + | - 12. Namespace must be first declaration in file |
+ | - 13. Namespaces aren't implemented like in ... | ||
+ | |||
- | ** TODO: I'm currently scouring the web/ | ||
==== 1. global & namespaced code in one file ==== | ==== 1. global & namespaced code in one file ==== | ||
currently one can declare multiple namespaces per file, but it is not possible to have code in the global scope in a file that declares namespaces, this is seen by some as an artificial limitation that forces some developers to change their project structures and as such breaks system that make use of (automated) source file concatenation (for performance reasons & distrubition), | currently one can declare multiple namespaces per file, but it is not possible to have code in the global scope in a file that declares namespaces, this is seen by some as an artificial limitation that forces some developers to change their project structures and as such breaks system that make use of (automated) source file concatenation (for performance reasons & distrubition), | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
==== 2. define() & defined() ==== | ==== 2. define() & defined() ==== | ||
currently one can declare constants in namespaces (in the same way as can be done in classes) as well as using the **define()** function inside namespaced code, | currently one can declare constants in namespaces (in the same way as can be done in classes) as well as using the **define()** function inside namespaced code, | ||
Line 214: | Line 220: | ||
* which of the inconsistencies can be resolved through changes to the implementation? | * which of the inconsistencies can be resolved through changes to the implementation? | ||
* given the potential for confusion, and the potential difficulty of implementing a solution, is it worth keeping the ability to define constants (with **const**) directly in namespaces? | * given the potential for confusion, and the potential difficulty of implementing a solution, is it worth keeping the ability to define constants (with **const**) directly in namespaces? | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
==== 3. Autoload & functions ==== | ==== 3. Autoload & functions ==== | ||
Line 319: | Line 329: | ||
- | ==== 4. You can ' | ||
+ | ---- | ||
+ | |||
+ | ==== 4. You can ' | ||
When trying to use an undefined class or function the engine will respond with a fatal error (after an attempt to autoload in the case of | When trying to use an undefined class or function the engine will respond with a fatal error (after an attempt to autoload in the case of | ||
a class), this is not the case with the **use** statement < | a class), this is not the case with the **use** statement < | ||
Line 377: | Line 389: | ||
* is it viable to implement? | * is it viable to implement? | ||
* what effect would included files have? would they need to be considered when implementing this? | * what effect would included files have? would they need to be considered when implementing this? | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
==== 5. Importing NameSpace:: | ==== 5. Importing NameSpace:: | ||
Line 428: | Line 444: | ||
**The question is:** should we allow importing of everything in a namespace or accept that people will use the above mentioned work-around (which I believe | **The question is:** should we allow importing of everything in a namespace or accept that people will use the above mentioned work-around (which I believe | ||
probably will happen)? regardless one can consider this issue a philosophical one, rather than one caused by an unintentioned limitation in the namespace implementation. If importing of everything via a single **use** statement is added as engine functionality other issues are raised regarding what would occur with namespaced functions and constants. | probably will happen)? regardless one can consider this issue a philosophical one, rather than one caused by an unintentioned limitation in the namespace implementation. If importing of everything via a single **use** statement is added as engine functionality other issues are raised regarding what would occur with namespaced functions and constants. | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
==== 6. Static methods/ | ==== 6. Static methods/ | ||
+ | There is an abiguity, from the users point of view between static class method calls and namespaced function calls, essentially it is very difficult to determine (if at all) from the code, even given context, whether **TEST:: | ||
+ | |||
+ | class.inc: | ||
+ | <code php> | ||
+ | <?php | ||
+ | class TEST { | ||
+ | static function what() | ||
+ | static function where() { echo __FUNCTION__," | ||
+ | } | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | ns.inc: | ||
+ | <code php> | ||
+ | <?php | ||
+ | namespace TEST; | ||
+ | function what() { echo __FUNCTION__," | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | example1.php: | ||
+ | <code php> | ||
+ | <?php | ||
+ | include ' | ||
+ | include ' | ||
+ | TEST:: | ||
+ | TEST:: | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | output of example1.php (regardless of include order): | ||
+ | < | ||
+ | TEST::what in namespace | ||
+ | where in class | ||
+ | </ | ||
+ | |||
+ | There is no way to reference the static method **TEST:: | ||
+ | |||
+ | //There is a need to disambiguate these two calls, and to be able to call both regardless of the existence of the other.// | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== 7. Class constants v. constants ambiguities ==== | ||
+ | The same ambiguity that exists between static methods and namespaced functions also exists between class constants and namespaced constants. | ||
+ | From the users point of view it not possible to determine, with any easy or certainty, from the code whether **TEST:: | ||
+ | |||
+ | class.inc: | ||
+ | <code php> | ||
+ | <?php | ||
+ | class TEST { | ||
+ | const MY_CNST_ONE = 'TEST class CONSTANT ONE'; | ||
+ | const MY_CNST_TWO = 'TEST class CONSTANT TWO'; | ||
+ | } | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | ns.inc: | ||
+ | <code php> | ||
+ | <?php | ||
+ | namespace TEST; | ||
+ | const MY_CNST_ONE = 'TEST class CONSTANT ONE'; | ||
+ | ?> | ||
+ | |||
+ | example1.php: | ||
+ | <code php> | ||
+ | <?php | ||
+ | include ' | ||
+ | include ' | ||
+ | echo TEST:: | ||
+ | echo TEST:: | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | output of example1.php (regardless of include order): | ||
+ | < | ||
+ | TEST namespace CONSTANT ONE | ||
+ | TEST class CONSTANT TWO | ||
+ | </ | ||
+ | |||
+ | There is no way to reference the constant **MY_CNST_ONE** from class **TEST**, additionally because constant **MY_CNST_TWO** from class **TEST** is reachable one is left with the potential that the namespaced include will break current code if a constant **MY_CNST_TWO** is later defined in the TEST namespace, regardless it introduces confusion because one is it possible to retrieve constants from two different ' | ||
+ | |||
+ | //There is a need to disambiguate the constants, and to be able to reference both regardless of the existence of the other.// | ||
+ | |||
- | ==== 7. **use** and includes ==== | + | ---- |
+ | ==== 8. **use** and includes ==== | ||
Users are currently able and used to be able to include code, especially inside a loop, that makes use of the " | Users are currently able and used to be able to include code, especially inside a loop, that makes use of the " | ||
Line 447: | Line 551: | ||
Chances are this is not a good idea, nonetheless details examples and documentation will probably be required in order to stem developer confusion, if nothing else confusion will limit uptake (as a rule users generally don't make use of functionality they either don't understand or misunderstand) | Chances are this is not a good idea, nonetheless details examples and documentation will probably be required in order to stem developer confusion, if nothing else confusion will limit uptake (as a rule users generally don't make use of functionality they either don't understand or misunderstand) | ||
- | ==== 8. Importing functions ==== | ||
- | ==== 9. Name resolution order ==== | ||
- | ==== 10. Keywords in namespace names ==== | + | ---- |
- | ==== 11. Namespace must be first declaration in file ==== | + | ==== 9. Importing functions ==== |
+ | It is not currently possible to alias namespaced functions, making them inconsistent with namespaced classes, and forcing users that are working with namespaced functions to always prefix namespaced functions in order to use them. This seems like an artificial limitation that implies functions are a second-class after thought as far as namespaces are concerned, additionally php has never before dictated to users an **OO** over **procedural** style of coding, the current implementation of namespaces seems to imply that **OO** is inherently better. | ||
+ | |||
+ | It is therefore not possible to override built in functions with functions imported from a namespace, which some people has expressed a desire to do ... most notably in the context of template engines, which generally strive to hide as much of the php's syntax from template developers [who generally don't program php] even though the template engine actually uses php syntax/code to expose it's functionality) ... forcing template developers to learn the intricacies of prefixing functions they employ (and there by having to realise that these may clash with static methods!) creates an unnecessary burden. | ||
+ | |||
+ | Regardless, it should be possible to import a namespaced function into the current file and use it in the same way one has been accustomed to calling functions. | ||
+ | The following examples tries to demonstrate the issue: | ||
+ | |||
+ | ns_funcs.inc: | ||
+ | <code php> | ||
+ | <?php | ||
+ | namespace MY:: | ||
+ | function foo() { echo "Hello World!\n"; | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | example1.php: | ||
+ | <code php> | ||
+ | <?php | ||
+ | include ' | ||
+ | // use MY:: | ||
+ | use MY:: | ||
+ | NS:: | ||
+ | MY:: | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | output from example1.php: | ||
+ | < | ||
+ | Hello World! | ||
+ | Hello World! | ||
+ | </ | ||
+ | |||
+ | example2.php: | ||
+ | <code php> | ||
+ | <?php | ||
+ | include ' | ||
+ | use MY:: | ||
+ | foo(); | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | output from example2.php: | ||
+ | < | ||
+ | Fatal error: Call to undefined function foo() in < | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== 10. Name resolution order ==== | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== 11. Keywords in namespace names ==== | ||
+ | It is stated that namespace names serve simply as string replacements to unqualified [namespaced] class, function and constant names, which suggests that '::' | ||
+ | |||
+ | example1.php: | ||
+ | <code php> | ||
+ | <?php | ||
+ | namespace MY:: | ||
+ | class App {} | ||
+ | namespace MY:: | ||
+ | class DB {} | ||
+ | namespace MY:: | ||
+ | class Model {} | ||
+ | class View {} | ||
+ | class Controller {} | ||
+ | namespace MY:: | ||
+ | class Product {} | ||
+ | class Customer {} | ||
+ | class Order {} | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | the preceeding example offers, according to current documentation, | ||
+ | |||
+ | example2.php: | ||
+ | <code php> | ||
+ | <?php | ||
+ | namespace MY:: | ||
+ | // some code | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | output of example2.php: | ||
+ | < | ||
+ | Parse error: syntax error, unexpected T_STATIC, expecting T_STRING in < | ||
+ | </ | ||
+ | |||
+ | Essentially the engine is smarter about namespace names and aliases thereof than it is letting on, it's an almost certainty that the only issue here is lack of or somewhat misleading documentation (It's also fairly clear that this lends itself to a nested namespace implementation if that is ever seriously proposed). Below is a small example script demonstrating the engine' | ||
+ | |||
+ | example3.php: | ||
+ | <code php> | ||
+ | <?php | ||
+ | namespace MY:: | ||
+ | class hi {} | ||
+ | |||
+ | namespace MY__TEST__NS; | ||
+ | class hi {} | ||
+ | |||
+ | namespace THIRD; | ||
+ | use MY::TEST; | ||
+ | use MY:: | ||
+ | |||
+ | $a = new TEST:: | ||
+ | $b = new NS:: | ||
+ | $c = new MY__TEST__NS:: | ||
+ | var_dump($a, | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | output of example3.php: | ||
+ | < | ||
+ | object(MY:: | ||
+ | } | ||
+ | object(MY:: | ||
+ | } | ||
+ | object(MY__TEST__NS:: | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== 12. Namespace must be first declaration in file ==== | ||
Currently if you wish to declare one or more namespaces in a file nothing may preceed the initial namespace declaration, | Currently if you wish to declare one or more namespaces in a file nothing may preceed the initial namespace declaration, | ||
Line 500: | Line 731: | ||
</ | </ | ||
- | ==== 12. Namespaces aren't implemented like in ... ==== | + | |
+ | |||
+ | ---- | ||
+ | |||
+ | ==== 13. Namespaces aren't implemented like in ... ==== | ||
PHP is not <insert your favorite language here>. Granted this is not an issue, but some of you reading this probably need something to smile about after reading the items above! | PHP is not <insert your favorite language here>. Granted this is not an issue, but some of you reading this probably need something to smile about after reading the items above! | ||
+ | |||
+ | |||
+ | |||
===== Patches & Proposal ===== | ===== Patches & Proposal ===== | ||
Line 507: | Line 745: | ||
additionally a number of patches have already been made available, these are listed below: | additionally a number of patches have already been made available, these are listed below: | ||
+ | ==== Issue' | ||
* http:// | * http:// | ||
- | This patch addresses the issues regarding, as defined in issue ?? | + | This patch addresses the issues regarding |
To quote the author from his original post regarding this patch: | To quote the author from his original post regarding this patch: | ||
Line 567: | Line 806: | ||
</ | </ | ||
+ | ==== Issue 9 ==== | ||
* http:// | * http:// | ||
- | This patch addresses the issues regarding the inability to alias functions to simple names, as defined in issue ?? | + | This patch addresses the issues regarding the inability to alias functions to simple names, as defined in **issue 9. " |
+ | |||
+ | ==== Issue 12 ==== | ||
* http:// | * http:// | ||
- | This patch addresses the inability to include [html] output prior to the first **<? | + | This patch addresses the inability to include [html] output prior to the first **<? |
- | ===== Miscellaneous ===== | + | To quote the author from his original post regarding this patch: |
+ | > This is a simple patch that allows files like this to work without parse error.: | ||
+ | > | ||
+ | > main.php: | ||
+ | > <code php> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | < | ||
+ | <?php | ||
+ | namespace my:: | ||
+ | |||
+ | // stuff | ||
+ | |||
+ | ?> | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ===== Miscellaneous ===== | ||
+ | * [[http:// | ||
* An RFC discussing namespaces for internal classes exists (see: [[[rfc: | * An RFC discussing namespaces for internal classes exists (see: [[[rfc: | ||
* A scratchpad document is being worked on to gather namespace 'best practices' | * A scratchpad document is being worked on to gather namespace 'best practices' | ||
+ | |||
+ | |||
+ | |||
===== Discussions past & present ===== | ===== Discussions past & present ===== | ||
+ | Below is a list of links to internals@lists.php.net thread that discuss (amongst others things) namespaces, the list is in reverse chronological order (hopefully) based on the initial post to the given thread and only lists discussion that have occurred in 2008: | ||
+ | |||
+ | * [[php-internals@122125176711750|the namespace war]] | ||
+ | * [[php-internals@122124674902629|PATCH: | ||
+ | * [[php-internals@122118945204074|PATCH: | ||
+ | * [[php-internals@122118574632627|PATCH: | ||
+ | * [[php-internals@122126001625094|Please don't start 10 threads a day about the Namespace support]] | ||
+ | * [[php-internals@122114969907530|Scoping of " | ||
+ | * [[php-internals@122110981102381|PATCH: | ||
+ | * [[php-internals@122098797532195|namespace function/ | ||
+ | * [[php-internals@122018993030061|namespace RFC]] | ||
+ | * [[php-internals@121920359817682|Namespace Global User Function Calls]] | ||
+ | * [[php-internals@121776665630615|Inconsistencies in 5.3]] | ||
+ | * [[php-internals@121626223101585|questions about namespaces, functions vs. closures]] | ||
+ | * [[php-internals@121615179414749|Include/ | ||
+ | * [[php-internals@121614847408006|Namespace problem?]] | ||
+ | * [[php-internals@121502894019535|towards a 5.3 release]] | ||
+ | * [[php-internals@121447143022557|How bad would it be to say/enforce that namespacing can only apply to classes and not ...]] | ||
+ | * [[php-internals@121397701404954|simple solution to another namespace conundrum? | ||
+ | * [[php-internals@121233666301819|multiple use]] | ||
+ | * [[php-internals@121223589228439|Alternative to multiple namespaces per file]] | ||
+ | * [[php-internals@121199212705823|Name resolution rules]] | ||
+ | * [[php-internals@121079120018378|5.3 Namespace resolution rules suggestions]] | ||
+ | * [[php-internals@121071258907404|5.3 and reflection]] | ||
+ | * [[php-internals@120742574008363|namespace implementation (irritating warning and autoload)]] | ||
+ | * [[php-internals@120613563032212|RFC: | ||
+ | * [[php-internals@120429739728318|PHP 5.3 Autoload+Namespaces+Functions incorret (atleast wierd) behaviour.]] | ||
+ | * [[php-internals@120018255502021|Namespace & Type Hinting Summaries? | ||
+ | * [[php-internals@119992382220241|Set default namespace]] | ||
+ | * [[php-internals@119874502923978|Suggestion: | ||
+ | |||
+ | Nothing has been filtered on the basis of relevance BUT some threads may not be listed due to the ' | ||
+ | |||
+ | |||
- | **//I will list a set of links to archives of all namespace discussions (on internals mailing list) once descriptions and repro-code of the listed issues are inplace//** | ||
===== Additional Commentary ===== | ===== Additional Commentary ===== | ||
+ | the articles & blog posts listed here are (hopefully) in reverse chronological order, please note that older items may no longer be relevant as the implementation has changed since the time the item was published: | ||
+ | |||
+ | - [[http:// | ||
+ | - [[http:// | ||
+ | - [[http:// | ||
+ | - [[http:// | ||
+ | - [[http:// | ||
+ | - [[http:// | ||
+ | - [[http:// | ||
+ | - [[http:// | ||
+ | |||
+ | and way back when 5.0 was still in incubation: | ||
+ | |||
+ | - [[http:// | ||
+ | |||
+ | this particular assessment of the original php5.0 namespace implementation (which was scraped), might be of interest to compared issues raised then with those currently being raised: | ||
+ | |||
+ | - [[http:// | ||
+ | |||
+ | for the really keen ones amongst us, knock yourself out: | ||
- | **//I will list a set of links to [recent] articles/blog-entries/etc found elsewhere on the net//** | + | - [[http://search.yahoo.com/search? |
+ | |
rfc/namespaces.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1