Hello.
Some time ago I have posted a patch that would make PHP call __autoload() for 
unknown functions too.
I didn't get any feedback regarding the patch so I send it to the mailing list 
once again. The patch
adds two constants AUTOLOAD_CLASS and AUTOLOAD_FUNCTION. The __autoload() 
definition is changed to :

function __autoload ($name, $type);

where $type is either AUTOLOAD_CLASS or AUTOLOAD_NAME, for backward 
compatibility thee definition

function __autoload ($name);

if allowed too. I have pasted a diff against the latest development snapshot of 
PHP-5.1. I'm sending the diff as an attachment too
in case the sending/receiving mail client mangles the diff. Any comments?

diff -ru php5-200411302330.orig/Zend/zend.c php5-200411302330/Zend/zend.c
--- php5-200411302330.orig/Zend/zend.c  2004-09-09 18:30:10.000000000 +0000
+++ php5-200411302330/Zend/zend.c       2004-12-01 04:09:24.000000000 +0000
@@ -477,7 +477,8 @@
        EG(user_error_handler) = NULL;
        EG(user_exception_handler) = NULL;
        EG(in_execution) = 0;
-       EG(in_autoload) = NULL;
+       EG(in_autoload_class) = NULL;
+       EG(in_autoload_function) = NULL;
        EG(current_execute_data) = NULL;
        EG(current_module) = NULL;
 }
diff -ru php5-200411302330.orig/Zend/zend_compile.c 
php5-200411302330/Zend/zend_compile.c
--- php5-200411302330.orig/Zend/zend_compile.c  2004-10-17 00:30:43.000000000 
+0000
+++ php5-200411302330/Zend/zend_compile.c       2004-12-01 04:12:08.000000000 
+0000
@@ -1177,8 +1177,8 @@
                name_len = strlen(CG(active_op_array)->function_name);
                zend_str_tolower_copy(lcname, 
CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1));
                lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't 
necessarily set the zero byte */
-               if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && 
!memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME,
sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1) {
-                       zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 
argument", ZEND_AUTOLOAD_FUNC_NAME);
+               if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && 
!memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME,
sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1 && 
CG(active_op_array)->num_args != 2) {
+                       zend_error(E_COMPILE_ERROR, "%s() must take 1 or 2 
arguments", ZEND_AUTOLOAD_FUNC_NAME);
                }               
        }
 
diff -ru php5-200411302330.orig/Zend/zend_constants.c 
php5-200411302330/Zend/zend_constants.c
--- php5-200411302330.orig/Zend/zend_constants.c        2004-07-13 
20:30:05.000000000 +0000
+++ php5-200411302330/Zend/zend_constants.c     2004-12-01 04:13:31.000000000 
+0000
@@ -108,6 +108,9 @@
 
        REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | 
CONST_CS);
 
+       REGISTER_MAIN_LONG_CONSTANT("AUTOLOAD_CLASS", AUTOLOAD_CLASS, 
CONST_PERSISTENT | CONST_CS);
+       REGISTER_MAIN_LONG_CONSTANT("AUTOLOAD_FUNCTION", AUTOLOAD_FUNCTION, 
CONST_PERSISTENT | CONST_CS);
+
        /* true/false constants */
        {
                zend_constant c;
diff -ru php5-200411302330.orig/Zend/zend_constants.h 
php5-200411302330/Zend/zend_constants.h
--- php5-200411302330.orig/Zend/zend_constants.h        2004-03-04 
11:08:13.000000000 +0000
+++ php5-200411302330/Zend/zend_constants.h     2004-12-01 04:14:22.000000000 
+0000
@@ -66,6 +66,9 @@
 
 #define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant
 
+#define AUTOLOAD_CLASS                 0
+#define AUTOLOAD_FUNCTION      1
+
 #endif
 
 /*
diff -ru php5-200411302330.orig/Zend/zend_execute.h 
php5-200411302330/Zend/zend_execute.h
--- php5-200411302330.orig/Zend/zend_execute.h  2004-09-23 22:30:50.000000000 
+0000
+++ php5-200411302330/Zend/zend_execute.h       2004-12-01 04:46:52.000000000 
+0000
@@ -65,6 +65,7 @@
        }
 }
 ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry 
***ce TSRMLS_DC);
+ZEND_API int zend_lookup_function(char *name, int name_length, zend_function 
**function TSRMLS_DC);
 ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name 
TSRMLS_DC);
 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char 
*string_name, int handle_exceptions TSRMLS_DC);
 
diff -ru php5-200411302330.orig/Zend/zend_execute_API.c 
php5-200411302330/Zend/zend_execute_API.c
--- php5-200411302330.orig/Zend/zend_execute_API.c      2004-11-23 
17:30:13.000000000 +0000
+++ php5-200411302330/Zend/zend_execute_API.c   2004-12-01 05:05:00.000000000 
+0000
@@ -137,7 +137,8 @@
        EG(class_table) = CG(class_table);
 
        EG(in_execution) = 0;
-       EG(in_autoload) = NULL;
+       EG(in_autoload_class) = NULL;
+       EG(in_autoload_function) = NULL;
        EG(autoload_func) = NULL;
 
        zend_ptr_stack_init(&EG(argument_stack));
@@ -293,10 +294,14 @@
                zend_ptr_stack_destroy(&EG(user_error_handlers));
                zend_ptr_stack_destroy(&EG(user_exception_handlers));
                zend_objects_store_destroy(&EG(objects_store));
-               if (EG(in_autoload)) {
-                       zend_hash_destroy(EG(in_autoload));
-                       FREE_HASHTABLE(EG(in_autoload));
-               }
+               if (EG(in_autoload_class)) {
+                       zend_hash_destroy(EG(in_autoload_class));
+                       FREE_HASHTABLE(EG(in_autoload_class));
+               }
+               if (EG(in_autoload_function)) {
+                       zend_hash_destroy(EG(in_autoload_function));
+                       FREE_HASHTABLE(EG(in_autoload_function));
+               }
        } zend_end_try();
 }
 
@@ -870,16 +875,18 @@
 }
 
 
-ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry 
***ce TSRMLS_DC)
+static int zend_lookup_autoloadable(char *name, int name_length, void **item, 
HashTable *lookup_table, HashTable
**autoload_table_ptr, long type TSRMLS_DC)
 {
-       zval **args[1];
+       char *lc_name;
+       HashTable *autoload_table;
+       char dummy = 1;
        zval autoload_function;
-       zval class_name, *class_name_ptr = &class_name;
+       zval **args[2];
+       zval autoload_name, *autoload_name_ptr = &autoload_name;
+       zval autoload_type, *autoload_type_ptr = &autoload_type;
+       zval *exception;
        zval *retval_ptr;
        int retval;
-       char *lc_name;
-       zval *exception;
-       char dummy = 1;
        zend_fcall_info fcall_info;
        zend_fcall_info_cache fcall_cache;
 
@@ -890,7 +897,7 @@
        lc_name = do_alloca(name_length + 1);
        zend_str_tolower_copy(lc_name, name, name_length);
 
-       if (zend_hash_find(EG(class_table), lc_name, name_length+1, (void **) 
ce) == SUCCESS) {
+       if (zend_hash_find(lookup_table, lc_name, name_length+1, item) == 
SUCCESS) {
                free_alloca(lc_name);
                return SUCCESS;
        }
@@ -903,29 +910,33 @@
                return FAILURE;
        }
 
-       if (EG(in_autoload) == NULL) {
-               ALLOC_HASHTABLE(EG(in_autoload));
-               zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0);      
+       if ((autoload_table = *autoload_table_ptr) == NULL) {
+               ALLOC_HASHTABLE(autoload_table);
+               zend_hash_init(autoload_table, 0, NULL, NULL, 0);       
+               *autoload_table_ptr = autoload_table;
        }
        
-       if (zend_hash_add(EG(in_autoload), lc_name, name_length+1, 
(void**)&dummy, sizeof(char), NULL) == FAILURE) {
+       if (zend_hash_add(autoload_table, lc_name, name_length+1, 
(void**)&dummy, sizeof(char), NULL) == FAILURE) {
                free_alloca(lc_name);
                return FAILURE;
        }
 
        ZVAL_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, 
sizeof(ZEND_AUTOLOAD_FUNC_NAME)-1,  0);
 
-       INIT_PZVAL(class_name_ptr);
-       ZVAL_STRINGL(class_name_ptr, name, name_length, 0);
-       
-       args[0] = &class_name_ptr;
+       INIT_PZVAL(autoload_name_ptr);
+       ZVAL_STRINGL(autoload_name_ptr, name, name_length, 0);
+       args[0] = &autoload_name_ptr;
+
+       INIT_PZVAL(autoload_type_ptr);
+       ZVAL_LONG(autoload_type_ptr, type);
+       args[1] = &autoload_type_ptr;
        
        fcall_info.size = sizeof(fcall_info);
        fcall_info.function_table = EG(function_table);
        fcall_info.function_name = &autoload_function;
        fcall_info.symbol_table = NULL;
        fcall_info.retval_ptr_ptr = &retval_ptr;
-       fcall_info.param_count = 1;
+       fcall_info.param_count = 2;
        fcall_info.params = args;
        fcall_info.object_pp = NULL;
        fcall_info.no_separation = 1;
@@ -940,7 +951,7 @@
        retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC);
        EG(autoload_func) = fcall_cache.function_handler;
 
-       zend_hash_del(EG(in_autoload), lc_name, name_length+1);
+       zend_hash_del(autoload_table, lc_name, name_length+1);
 
        if (retval == FAILURE) {
                EG(exception) = exception;
@@ -958,11 +969,21 @@
        /* If an exception is thrown retval_ptr will be NULL but we bailout 
before we reach this point */
        zval_ptr_dtor(&retval_ptr);
 
-       retval = zend_hash_find(EG(class_table), lc_name, name_length + 1, 
(void **) ce);
+       retval = zend_hash_find(lookup_table, lc_name, name_length + 1, item);
        free_alloca(lc_name);
        return retval;
 }
 
+ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry 
***ce TSRMLS_DC)
+{
+       return (zend_lookup_autoloadable (name, name_length, (void **)ce, 
EG(class_table), &EG(in_autoload_class), AUTOLOAD_CLASS
TSRMLS_CC));
+}
+
+ZEND_API int zend_lookup_function(char *name, int name_length, zend_function 
**function TSRMLS_DC)
+{
+       return (zend_lookup_autoloadable (name, name_length, (void **)function, 
EG(function_table), &EG(in_autoload_function),
AUTOLOAD_FUNCTION TSRMLS_CC));
+}
+
 ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name 
TSRMLS_DC)
 {
        zval pv;
diff -ru php5-200411302330.orig/Zend/zend_globals.h 
php5-200411302330/Zend/zend_globals.h
--- php5-200411302330.orig/Zend/zend_globals.h  2004-11-04 01:30:19.000000000 
+0000
+++ php5-200411302330/Zend/zend_globals.h       2004-12-01 05:05:49.000000000 
+0000
@@ -191,7 +191,8 @@
        int ticks_count;
 
        zend_bool in_execution;
-       HashTable *in_autoload;
+       HashTable *in_autoload_class;
+       HashTable *in_autoload_function;
        zend_function *autoload_func;
        zend_bool bailout_set;
        zend_bool full_tables_cleanup;
diff -ru php5-200411302330.orig/Zend/zend_vm_def.h 
php5-200411302330/Zend/zend_vm_def.h
--- php5-200411302330.orig/Zend/zend_vm_def.h   2004-11-03 09:30:10.000000000 
+0000
+++ php5-200411302330/Zend/zend_vm_def.h        2004-12-01 04:40:46.000000000 
+0000
@@ -1660,7 +1660,7 @@
        zend_op *opline = EX(opline);
        zval *function_name;
        zend_function *function;
-       char *function_name_strval, *lcname;
+       char *function_name_strval;
        int function_name_strlen;
        zend_free_op free_op2;
 
@@ -1682,13 +1682,10 @@
                function_name_strlen = function_name->value.str.len;
        }
 
-       lcname = zend_str_tolower_dup(function_name_strval, 
function_name_strlen);
-       if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, 
(void **) &function)==FAILURE) {
-               efree(lcname);
+       if (zend_lookup_function(function_name_strval, function_name_strlen, 
&function TSRMLS_CC)==FAILURE) {
                zend_error_noreturn(E_ERROR, "Call to undefined function %s()", 
function_name_strval);
        }
 
-       efree(lcname);
        FREE_OP2();
 
        EX(calling_scope) = function->common.scope;
diff -ru php5-200411302330.orig/Zend/zend_vm_execute.h 
php5-200411302330/Zend/zend_vm_execute.h
--- php5-200411302330.orig/Zend/zend_vm_execute.h       2004-11-03 
09:30:11.000000000 +0000
+++ php5-200411302330/Zend/zend_vm_execute.h    2004-12-01 04:45:38.000000000 
+0000
@@ -572,7 +572,7 @@
        zend_op *opline = EX(opline);
        zval *function_name;
        zend_function *function;
-       char *function_name_strval, *lcname;
+       char *function_name_strval;
        int function_name_strlen;
        zend_free_op free_op2;
 
@@ -594,13 +594,10 @@
                function_name_strlen = function_name->value.str.len;
        }
 
-       lcname = zend_str_tolower_dup(function_name_strval, 
function_name_strlen);
-       if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, 
(void **) &function)==FAILURE) {
-               efree(lcname);
+       if (zend_lookup_function(function_name_strval, function_name_strlen, 
&function TSRMLS_CC)==FAILURE) {
                zend_error_noreturn(E_ERROR, "Call to undefined function %s()", 
function_name_strval);
        }
 
-       efree(lcname);
        ;
 
        EX(calling_scope) = function->common.scope;
@@ -769,7 +766,7 @@
        zend_op *opline = EX(opline);
        zval *function_name;
        zend_function *function;
-       char *function_name_strval, *lcname;
+       char *function_name_strval;
        int function_name_strlen;
        zend_free_op free_op2;
 
@@ -791,13 +788,10 @@
                function_name_strlen = function_name->value.str.len;
        }
 
-       lcname = zend_str_tolower_dup(function_name_strval, 
function_name_strlen);
-       if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, 
(void **) &function)==FAILURE) {
-               efree(lcname);
+       if (zend_lookup_function(function_name_strval, function_name_strlen, 
&function TSRMLS_CC)==FAILURE) {
                zend_error_noreturn(E_ERROR, "Call to undefined function %s()", 
function_name_strval);
        }
 
-       efree(lcname);
        zval_dtor(free_op2.var);
 
        EX(calling_scope) = function->common.scope;
@@ -924,7 +918,7 @@
        zend_op *opline = EX(opline);
        zval *function_name;
        zend_function *function;
-       char *function_name_strval, *lcname;
+       char *function_name_strval;
        int function_name_strlen;
        zend_free_op free_op2;
 
@@ -946,13 +940,10 @@
                function_name_strlen = function_name->value.str.len;
        }
 
-       lcname = zend_str_tolower_dup(function_name_strval, 
function_name_strlen);
-       if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, 
(void **) &function)==FAILURE) {
-               efree(lcname);
+       if (zend_lookup_function(function_name_strval, function_name_strlen, 
&function TSRMLS_CC)==FAILURE) {
                zend_error_noreturn(E_ERROR, "Call to undefined function %s()", 
function_name_strval);
        }
 
-       efree(lcname);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
        EX(calling_scope) = function->common.scope;
@@ -1163,7 +1154,7 @@
        zend_op *opline = EX(opline);
        zval *function_name;
        zend_function *function;
-       char *function_name_strval, *lcname;
+       char *function_name_strval;
        int function_name_strlen;
        zend_free_op free_op2;
 
@@ -1185,13 +1176,10 @@
                function_name_strlen = function_name->value.str.len;
        }
 
-       lcname = zend_str_tolower_dup(function_name_strval, 
function_name_strlen);
-       if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, 
(void **) &function)==FAILURE) {
-               efree(lcname);
+       if (zend_lookup_function(function_name_strval, function_name_strlen, 
&function TSRMLS_CC)==FAILURE) {
                zend_error_noreturn(E_ERROR, "Call to undefined function %s()", 
function_name_strval);
        }
 
-       efree(lcname);
        ;
 
        EX(calling_scope) = function->common.scope;
@@ -29214,7 +29202,7 @@
        zend_op *opline = EX(opline);
        zval *function_name;
        zend_function *function;
-       char *function_name_strval, *lcname;
+       char *function_name_strval;
        int function_name_strlen;
        zend_free_op free_op2;
 
@@ -29236,13 +29224,10 @@
                function_name_strlen = function_name->value.str.len;
        }
 
-       lcname = zend_str_tolower_dup(function_name_strval, 
function_name_strlen);
-       if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, 
(void **) &function)==FAILURE) {
-               efree(lcname);
+       if (zend_lookup_function(function_name_strval, function_name_strlen, 
&function TSRMLS_CC)==FAILURE) {
                zend_error_noreturn(E_ERROR, "Call to undefined function %s()", 
function_name_strval);
        }
 
-       efree(lcname);
        FREE_OP(free_op2);
 
        EX(calling_scope) = function->common.scope; 

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

Reply via email to