I have locally made changes to support namespaces, with minimal impact to the Zend Engine (I based my changes on PHP 5.1.0b2). I have gone through the archives and read the previous discussions about namespaces and the outstanding issues, and to the best of my knowledge, I think my changes solve these.
I have only a few things to finish (as I'll explain below), but so far everything's working great (I have only enabled classes to be under namespaces, since that's all I care about, but functions and constants can be added in a similar manner)! Since I still have some things to finish, I won't post a patch yet, but I'll give a high-level description of what I did to see if my approach is acceptable or not. Basically, my approach involves the following concepts: - Classes may not contain colons (no change here), BUT class name references CAN contain colons (this is KEY!). - All imports are done at compile time. - Imports only affect the current file (yes, this has been done!) Here are some more details: Class Table Manipulation ------------------------ When the start of a namespace declaration is encountered, the namespace name is saved in a compile global variable. All classes inside the namespace block will get the namespace name and the colon prepended to the name (this is done in "zend_do_begin_class_declaration"). So, for the following code: <code> namespace my_namespace{ class my_class{ public $mem; } } </code> What will actually happen here is that the class will get added to the class table as "my_namespace:my_class". Referencing Classes ------------------- The following two examples are valid: <code> $a = new my_namespace:myclass(); </code> <code> import my_namespace:myclass; $a = new myclass(); </code> Imports ------- The syntax for the import statement will be: import <full-class-name> [as <alias-name>]; I have not yet added full namespace imports ("wildcard" imports), and am not yet sure if this is a good idea. Anyways, with the import statement, if no alias is specified, then the class is imported with the remaining string after the last colon in the name, and if an alias is specified, then that name is used (aliases cannot contain colons). For example: <code> import my_namespace:myclass; $a = new myclass(); </code> <code> import my_namespace:myclass as my_namespace_my_class; $a = new my_namespace_myclass(); </code> When an import is done, what happens is that the import is saved in an import hashtable, which holds the "aliases" which are active for the current file. The alias is also saved in class_table (an additional entry is added, the key being the alias name and the value being the zend_class_entry for the actual class). This means that a zend_class_entry can belong to more than one key in class_table at a time (this is done to emulate that a class by that name actually exists, and it also prevents classes in the global namespace to be named the same as import aliases). Now for the interesting part! How are imports done on a file scope only? The key to this is that file scopes can be emulated at compile time, but not at run time. As I said before, imports are saved in a compile global hashtable. When the end of the file is reached, this hashtable is cleared and the alias entries are removed from class_table. This is done simply by modifying the start rule: start: top_statement_list { zend_do_unimport_all(TSRMLS_C); } ; This triggers the "zend_do_unimport_all" function to be called at the end of the file. At this point (before the function is called), all references to imported names have been changed internally to full class names, which include the namespace and colon(s). Since include/require statements are executed at runtime, when the "zend_compile_file" function is executed for the included files, the import hashtable will be empty! I have not yet begun doing this, but I would like the import statement to actually include the file where the class is defined. A new php.ini variable called "class_path" will be used for this. When an "import my_ns:my_class;" statement is encountered, the file "<class-path>/my_ns/my_class.php" will be included (of course, multiple directories can be specified in the class_path, just like include_path). The above changes make a minimal impact to the Zend engine, and since all the namespace/import translation is done at compile time, execution speed is not affected. I would like to gather comments/suggestions/criticisms of the above approach, in order to see if I should continue making these changes or not. If there is enough demand, I will post the patches of what I have so far, even though it's not complete. Regards, Jessie Hernandez -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php