Any chance of sneeking this one in :) - patch attached
usage:
<?
class testclass2 extends testclass { }
class testclass {
function test() {
echo __CLASS__;
}
}
testclass2::test();
$t = new testclass2();
$t->test();
?>
prints
testclass2
testclass2
extremely usefull for building mulitiple extendable constructors.
regards
alan
diff -b -B -r -u php-4.2.0RC2/Zend/zend_compile.h ALAN_Zend/zend_compile.h
--- php-4.2.0RC2/Zend/zend_compile.h Sun Feb 10 20:52:45 2002
+++ ALAN_Zend/zend_compile.h Fri Apr 5 17:26:04 2002
@@ -81,7 +81,7 @@
zend_uchar *arg_types; /* MUST be the second element of this struct!
*/
char *function_name; /* MUST be the third element of this
struct! */
-
+ char *class_name; /* set at execute time to record the active class */
zend_uint *refcount;
zend_op *opcodes;
@@ -114,7 +114,7 @@
zend_uchar *arg_types; /* MUST be the second element of this struct */
char *function_name; /* MUST be the third element of this
struct */
-
+ char *class_name; /* set at execute time to record the active class */
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
} zend_internal_function;
@@ -124,7 +124,7 @@
zend_uchar *arg_types; /* MUST be the second element of this struct */
char *function_name; /* MUST be the third element of this struct */
-
+ char *class_name; /* set at execute time to record the active class */
zend_uint var;
} zend_overloaded_function;
@@ -135,6 +135,7 @@
zend_uchar type; /* never used */
zend_uchar *arg_types;
char *function_name;
+ char *class_name; /* set at execute time to record the active
+class */
} common;
zend_op_array op_array;
diff -b -B -r -u php-4.2.0RC2/Zend/zend_execute.c ALAN_Zend/zend_execute.c
--- php-4.2.0RC2/Zend/zend_execute.c Sun Jan 6 23:21:09 2002
+++ ALAN_Zend/zend_execute.c Fri Apr 5 17:26:04 2002
@@ -1485,6 +1485,7 @@
zend_function *function;
HashTable *active_function_table;
zval tmp;
+ char *class_name=NULL;
zend_ptr_stack_n_push(&EG(arg_types_stack), 2,
EX(fbc), EX(object).ptr);
if (EX(opline)->extended_value &
ZEND_CTOR_CALL) {
@@ -1521,6 +1522,7 @@
if
(zend_hash_find(EG(class_table), EX(opline)->op1.u.constant.value.str.val,
EX(opline)->op1.u.constant.value.str.len+1, (void **) &ce)==FAILURE) { /* class
doesn't exist */
zend_error(E_ERROR,
"Undefined class name '%s'", EX(opline)->op1.u.constant.value.str.val);
}
+ class_name = ce->name;
active_function_table =
&ce->function_table;
} else { /* used for member function
calls */
EX(object).ptr =
_get_object_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1) TSRMLS_CC);
@@ -1564,6 +1566,7 @@
zend_error(E_ERROR, "Call to undefined
function: %s()", function_name->value.str.val);
}
zval_dtor(&tmp);
+ function->common.class_name = class_name;
EX(fbc) = function;
overloaded_function_call_cont:
FREE_OP(EX(Ts), &EX(opline)->op2,
EG(free_op2));
@@ -1955,11 +1958,29 @@
NEXT_OPCODE();
case ZEND_FETCH_CONSTANT:
if
(!zend_get_constant(EX(opline)->op1.u.constant.value.str.val,
EX(opline)->op1.u.constant.value.str.len, &EX(Ts)[EX(opline)->result.u.var].tmp_var
TSRMLS_CC)) {
+ /*if
+(!strcmp(EX(opline)->op1.u.constant.value.str.val,"__FUNCTION__")) {
+ char *function_name =
+get_active_function_name(TSRMLS_C);
+ if (!function_name) function_name ="";
+
+EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.val = function_name;
+
+EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.len = strlen(function_name);
+
+EX(Ts)[EX(opline)->result.u.var].tmp_var.type = IS_STRING;
+
+zval_copy_ctor(&EX(Ts)[EX(opline)->result.u.var].tmp_var);
+ } else */
+ if
+(!strcmp(EX(opline)->op1.u.constant.value.str.val,"__CLASS__")) {
+ char *class_name =
+get_active_class_name(TSRMLS_C);
+ if (!class_name) class_name ="";
+
+EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.val = class_name;
+
+EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.len = strlen(class_name);
+
+EX(Ts)[EX(opline)->result.u.var].tmp_var.type = IS_STRING;
+
+zval_copy_ctor(&EX(Ts)[EX(opline)->result.u.var].tmp_var);
+ } else {
+
zend_error(E_NOTICE, "Use of undefined
constant %s - assumed '%s'",
EX(opline)->op1.u.constant.value.str.val,
EX(opline)->op1.u.constant.value.str.val);
EX(Ts)[EX(opline)->result.u.var].tmp_var =
EX(opline)->op1.u.constant;
zval_copy_ctor(&EX(Ts)[EX(opline)->result.u.var].tmp_var);
+ }
}
NEXT_OPCODE();
case ZEND_INIT_ARRAY:
diff -b -B -r -u php-4.2.0RC2/Zend/zend_execute.h ALAN_Zend/zend_execute.h
--- php-4.2.0RC2/Zend/zend_execute.h Sun Jan 6 23:21:09 2002
+++ ALAN_Zend/zend_execute.h Fri Apr 5 17:26:04 2002
@@ -133,6 +133,7 @@
/* services */
ZEND_API char *get_active_function_name(TSRMLS_D);
+ZEND_API char *get_active_class_name(TSRMLS_D);
ZEND_API char *zend_get_executed_filename(TSRMLS_D);
ZEND_API uint zend_get_executed_lineno(TSRMLS_D);
ZEND_API zend_bool zend_is_executing(TSRMLS_D);
diff -b -B -r -u php-4.2.0RC2/Zend/zend_execute_API.c ALAN_Zend/zend_execute_API.c
--- php-4.2.0RC2/Zend/zend_execute_API.c Sun Jan 6 23:21:09 2002
+++ ALAN_Zend/zend_execute_API.c Fri Apr 5 17:26:04 2002
@@ -218,6 +218,7 @@
ZEND_API char *get_active_function_name(TSRMLS_D)
{
+
switch(EG(function_state_ptr)->function->type) {
case ZEND_USER_FUNCTION: {
char *function_name = ((zend_op_array *)
EG(function_state_ptr)->function)->function_name;
@@ -237,6 +238,28 @@
}
}
+
+ZEND_API char *get_active_class_name(TSRMLS_D)
+{
+
+ switch(EG(function_state_ptr)->function->type) {
+ case ZEND_USER_FUNCTION: {
+ char *class_name = ((zend_op_array *)
+EG(function_state_ptr)->function)->class_name;
+
+ if (class_name) {
+ return class_name;
+ } else {
+ return "main";
+ }
+ }
+ break;
+ case ZEND_INTERNAL_FUNCTION:
+ return ((zend_internal_function *)
+EG(function_state_ptr)->function)->class_name;
+ break;
+ default:
+ return NULL;
+ }
+}
ZEND_API char *zend_get_executed_filename(TSRMLS_D)
{
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php