Sam Barrow wrote:
> I agree with this 100%, is this something that could be changed? I don't
> see a reason behind it.
>
> On Sun, 2007-12-09 at 16:24 -0500, Jessie Hernandez wrote:
>   
>> internal class/function with the same name.
>>
>> Dmitry, what's the reason this lookup logic wasn't used in your patch?

Hi,

Actually, there several good reasons.  For one, every single unknown
class declaration inside a namespace would require a double check of
class existence, hitting performance.

Here's another example showing the "gotcha" that is inherent:

file1.php:
<?php
namespace Foo;
class IwantThis {}
?>

file2.php:
<?php
class IwantThis {}
?>

file3.php:
<?php
namespace Foo;
include 'file2.php';
function __autoload($class)
{
include 'file1.php'; // stupid but illustrates the point
}
$a = new IwantThis;
?>

Currently, executing file3.php would result in this logic chain:

1) does Foo::IwantThis exist? no => step 2
2) does internal class IwantThis exist? no => step 3
3) try autoloading Foo::IwantThis, loads file1.php, now Foo::IwantThis
exists

If this logic chain were changed to instead check for any globally
defined class of that name, the logic chain would be:

1) does Foo::IwantThis exist?  no => step 2
2) does ::IwantThis class exist? yes => use ::IwantThis

In other words, it would completely break autoloading for namespaced
classes.  Of course, this is the same problem as conflicting with
internal classnames, but the scope of the problem is far larger because
there are so few classes internal to PHP, and even fewer that are likely
to conflict with unqualified names.

So, it could be changed (patch attached for 5.3 to prove the concept,
it's not the best way to do this but shows the way it could be done),
but the price would be an absolute requirement that all classes be
explicitly "use"d in some manner inside a namespace.

Greg
Index: Zend/zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.331.2.20.2.24.2.14
diff -u -r1.331.2.20.2.24.2.14 zend_execute_API.c
--- Zend/zend_execute_API.c     7 Dec 2007 17:11:23 -0000       
1.331.2.20.2.24.2.14
+++ Zend/zend_execute_API.c     10 Dec 2007 04:31:42 -0000
@@ -1601,8 +1601,7 @@
                                php_name++;
                                php_name_len = class_name_len - (php_name - 
class_name);
                                php_name = zend_str_tolower_dup(php_name, 
php_name_len);
-                               if (zend_hash_find(EG(class_table), php_name, 
php_name_len + 1, (void **) &pce) == SUCCESS &&
-                                       (*pce)->type == ZEND_INTERNAL_CLASS
+                               if (zend_hash_find(EG(class_table), php_name, 
php_name_len + 1, (void **) &pce) == SUCCESS
                                ) {
                                        efree(php_name);
                                        return *pce;
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.647.2.27.2.41.2.29
diff -u -r1.647.2.27.2.41.2.29 zend_compile.c
--- Zend/zend_compile.c 7 Dec 2007 17:11:23 -0000       1.647.2.27.2.41.2.29
+++ Zend/zend_compile.c 10 Dec 2007 04:31:45 -0000
@@ -1599,6 +1599,7 @@
                               internal one. */
                                *fetch_type |= ZEND_FETCH_CLASS_RT_NS_CHECK;
                        }
+                       *fetch_type |= ZEND_FETCH_CLASS_RT_NS_CHECK;
                        tmp.op_type = IS_CONST;
                        tmp.u.constant = *CG(current_namespace);
                        zval_copy_ctor(&tmp.u.constant);

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to