Hi, These 2 scripts demonstrate the problem:
foo.php: <?php namespace foo; const one = 1; function what() { echo __FUNCTION__,"\n"; } ?> bar.php: <?php include 'foo.php'; class foo { const one = 1; static function what() { echo __FUNCTION__,"\n"; } } foo::what(); // is this static method ::foo::what() or namespace function ::foo::what()? var_dump(foo::one); // is this class constant ::foo::one or namespace constant ::foo::one? ?> The logical solution for functions would be to allow something to disambiguate. I would suggest allowing function:: to differentiate between a method and a function: bar_func.php: <?php include 'foo.php'; use function foo::what; // this should inform PHP to alias namespace function foo::what to "what" class foo { const one = 1; static function what() { echo __FUNCTION__,"\n"; } } foo::what(); // this is static method ::foo::what(); function::foo::what(); // this is namespace function ::foo::what(); what(); // this is namespace function ::foo::what(); ?> The solution for constants can be similar: bar_const.php: <?php include 'foo.php'; use const foo::one; // this should inform PHP to alias namespace constant foo::one to "one" class foo { const one = 1; static function what() { echo __FUNCTION__,"\n"; } } echo foo::one; // this is class constant ::foo::one; echo const::foo::one; // this is namespace constant ::foo::one; echo one; // this is namespace constant ::foo::one; ?> To implement this technically, we would need to create two new import hashes, one for functions, and one for constants. For this to be technically possible, we would need to ensure this is illegal: <?php use foo::name, function foo::name; // conflict between "name" and "name" even though context would differentiate use foo::name, const foo::name; // same conflict ?> Fortunately, it is easy to test, as zend_do_use() could simply check the other hashes for existence of the name in question. Then, the implementation of unqualified name resolution would consist of doing resolution like so: resolving name::foo(): 1) is there a use blah::name; or use something::else as name;? => resolve "name::foo()" as class blah::name/something::else, method foo 2) is there a class in the current namespace called "name"? => resolve "name::foo()" as class name method foo 3) is there a namespace in the current namespace called "name" and a function in it called "foo"? => resolve to namespace function "name::foo()" 4) resolve name::foo() at runtime using current resolution rules resolving foo(); 1) is there a use function name::foo; or use function something::else as foo;? => resolve "foo()" as namespace function "name::foo()/something::else()" 2) is there a foo() function in the current namespace? => resolve "foo()" as namespace function in the current namespace "foo()" if we are in a namespace: 3a) is there an internal function named foo()? => resolve "foo()" as internal function foo. and if we're in the top-level unnamespace: 3b) is there any global function named foo()? => resolve "foo()" as global function foo. resolving foo [in const context such as "$a = foo;"]: 1) is there a use const name::foo; or use const something::else as foo;? => resolve "foo" as namespace constant name::foo/something::else at compile time 2) is there a const in the current namespace "foo"? => resolve "foo" as namespace constant in current namespace at compile time 3) resolve "foo" as define()d at runtime It must be noted that because functions/constants cannot be autoloaded, we can safely assume that if a namespace function or constant does not exist at runtime, then we can error out immediately. This simplifies resolution slightly over class resolution. If this looks good, I may be able to try my hand at a patch, but I only have time today or tomorrow to do so. Greg -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php