Chuck Hagenbuch wrote: > Quoting Stanislav Malyshev <[EMAIL PROTECTED]>: > >> This is even better than requiring, and makes the intent very clear. I >> don't think it decreases intuitiveness, on the contrary - from the >> look of the code it is immediately clear which exception would be used. > > I went ahead and tried to apply this (explicit imports of classes in the > same namespace) to the library that I'm working on, and it doesn't work. > Here's the same example as before with 1.php and 2.php, but this time > we're trying to avoid ambiguity by importing Test::Exception in each file: > > 1.php: > ------ > <?php > > namespace Test; > import Test::Exception; > > throw new Exception(); > > > 2.php: > ------ > <?php > > namespace Test; > import Test::Exception; > > throw new Exception(); > > > (yes, they are identical; imagine that one defines, say, Test::Runner > and the other defines Test::Case, both of which can throw Test::Exception) > > Now I run parent.php, which looks like: > --------------------------------------- > > <?php > > function __autoload($class) { > include './test_exception.php'; > } > > try { > include '2.php'; > } catch (Exception $e) { > echo get_class($e) . "\n"; > } > > try { > include '1.php'; > } catch (Exception $e) { > echo get_class($e) . "\n"; > } > > > > And I get: > ---------- > $ php parent.php > Test::Exception > > Fatal error: Import name 'Exception' conflicts with defined class in > /Users/chuck/Desktop/php namespaces/1.php on line 4 > > This one I can't solve by removing the use of autoload, either - if I > include test_exception.php before doing anything, it just fails on the > first file that imports it: > > $ php parent.php > > Fatal error: Import name 'Exception' conflicts with defined class in > /Users/chuck/Desktop/php namespaces/2.php on line 4
Hi Chuck, Turns out you've found a bug in the fix for Bug #42859. I've attached a patch for PHP 5.3, and can do the same for PHP 6 later. Greg
Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.647.2.27.2.41.2.10 diff -u -r1.647.2.27.2.41.2.10 zend_compile.c --- Zend/zend_compile.c 17 Oct 2007 10:01:21 -0000 1.647.2.27.2.41.2.10 +++ Zend/zend_compile.c 21 Oct 2007 01:59:54 -0000 @@ -4596,7 +4596,7 @@ { char *lcname; zval *name, *ns, tmp; - zend_bool warn = 0; + zend_bool warn = 0, shorthand = 0; if (!CG(current_import)) { CG(current_import) = emalloc(sizeof(HashTable)); @@ -4611,11 +4611,12 @@ char *p; /* The form "import A::B" is eqivalent to "import A::B as B". - So we extract the last part of compound name ti use as a new_name */ + So we extract the last part of compound name to use as a new_name */ name = &tmp; p = zend_memrchr(Z_STRVAL_P(ns), ':', Z_STRLEN_P(ns)); if (p) { ZVAL_STRING(name, p+1, 1); + shorthand = 1; } else { *name = *ns; zval_copy_ctor(name); @@ -4640,7 +4641,8 @@ ns_name[Z_STRLEN_P(CG(current_namespace))] = ':'; ns_name[Z_STRLEN_P(CG(current_namespace))+1] = ':'; memcpy(ns_name+Z_STRLEN_P(CG(current_namespace))+2, lcname, Z_STRLEN_P(name)+1); - if (zend_hash_exists(CG(class_table), ns_name, Z_STRLEN_P(CG(current_namespace)) + 2 + Z_STRLEN_P(name)+1)) { + /* if our new import name is simply the shorthand, skip this check */ + if (!shorthand || !memcmp(ns_name, Z_STRVAL_P(ns), Z_STRLEN_P(ns) + 1) && zend_hash_exists(CG(class_table), ns_name, Z_STRLEN_P(CG(current_namespace)) + 2 + Z_STRLEN_P(name)+1)) { zend_error(E_COMPILE_ERROR, "Import name '%s' conflicts with defined class", Z_STRVAL_P(name)); } efree(ns_name); Index: Zend/tests/namespace_import1.inc =================================================================== RCS file: Zend/tests/namespace_import1.inc diff -N Zend/tests/namespace_import1.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/namespace_import1.inc 21 Oct 2007 01:59:55 -0000 @@ -0,0 +1,3 @@ +<?php +namespace Test; +class Exception extends ::Exception {} \ No newline at end of file Index: Zend/tests/namespace_import2.inc =================================================================== RCS file: Zend/tests/namespace_import2.inc diff -N Zend/tests/namespace_import2.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/namespace_import2.inc 21 Oct 2007 01:59:55 -0000 @@ -0,0 +1,4 @@ +<?php +namespace Test; +import Test::Exception; +throw new Exception; \ No newline at end of file Index: Zend/tests/ns_import.phpt =================================================================== RCS file: Zend/tests/ns_import.phpt diff -N Zend/tests/ns_import.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_import.phpt 21 Oct 2007 01:59:55 -0000 @@ -0,0 +1,13 @@ +--TEST-- +namespace import test - including external file with same import name +--FILE-- +<?php +include dirname(__FILE__) . '/namespace_import1.inc'; +try { + include dirname(__FILE__) . '/namespace_import2.inc'; +} catch (Test::Exception $e) { + echo 'caught'; +} +?> +--EXPECT-- +caught \ No newline at end of file
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php