Did you make sure to real all the past threads on the issue?
There are a variety of problems which arise with such a namespaces
implementation, including ambiguity, problems with multiple symbol table
lookups, dynamic variable creation, cross-file dependencies. I believe this
solution suffers from mostly the same problems.
Andi
At 08:44 PM 7/6/2005 -0400, Jessie Hernandez wrote:
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
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php