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