getting the called name from a static method - extending zend_function ?

From: Date: Wed, 03 Apr 2002 09:59:14 +0000
Subject: getting the called name from a static method - extending zend_function ?
Groups: php.dev 
Request: Send a blank email to php-dev+get-82045@lists.php.net to get a copy of this message
This is what I was trying to do, class master { function static_test($var) {
       $class = get_class() <- this wont work obviously :)
       $ret = new $class();
       $ret->get($var);
       if (!$ret->N) return;
       return $ret;
} } class slave extends master {
    function get($var) {
      $this->N=1;
} } if ($obj = slave::static_test(123)) $obj->do_stuff(); ..... basically there is no way that I can see to get the called class out of the so that it would make a slave when called, not a master :) From a breif (well at least an hour or so :) look at the zend code - this was the solution i came up with - to extend the zend function to have an additional called_function_name pointer to store this in and have a extra magic define __CALLED_FUNCTION__ --- below are my notes how it might be done - is there any major objection/better ideas, before I waste some time playing with it :) zend_compile.h 132 <http://lxr.php.net/source/Zend/zend_compile.h#132> typedef union _zend_function <http://lxr.php.net/ident?i=_zend_function> {
133 <http://lxr.php.net/source/Zend/zend_compile.h#133>         zend_uchar <http://lxr.php.net/ident?i=zend_uchar> type <http://lxr.php.net/ident?i=type>;        *//* MUST be the first element of this struct! *//*
134 <http://lxr.php.net/source/Zend/zend_compile.h#134>         struct {
135 <http://lxr.php.net/source/Zend/zend_compile.h#135>                 zend_uchar <http://lxr.php.net/ident?i=zend_uchar> type <http://lxr.php.net/ident?i=type>;  *//* never used *//*
136 <http://lxr.php.net/source/Zend/zend_compile.h#136>                 zend_uchar <http://lxr.php.net/ident?i=zend_uchar> *arg_types;
137 <http://lxr.php.net/source/Zend/zend_compile.h#137>                 char *function_name;
char *called_function_name;
138 <http://lxr.php.net/source/Zend/zend_compile.h#138>         } common <http://lxr.php.net/ident?i=common>;
139 <http://lxr.php.net/source/Zend/zend_compile.h#139>         140 <http://lxr.php.net/source/Zend/zend_compile.h#140>         zend_op_array <http://lxr.php.net/ident?i=zend_op_array> op_array;
141 <http://lxr.php.net/source/Zend/zend_compile.h#141>         zend_internal_function <http://lxr.php.net/ident?i=zend_internal_function> internal_function;
142 <http://lxr.php.net/source/Zend/zend_compile.h#142>         zend_overloaded_function <http://lxr.php.net/ident?i=zend_overloaded_function> overloaded_function;
143 <http://lxr.php.net/source/Zend/zend_compile.h#143> } zend_function <http://lxr.php.net/ident?i=zend_function>; 144 <http://lxr.php.net/source/Zend/zend_compile.h#144> zend_execute.c ZEND_INIT_FCALL_BY_NAME <http://lxr.php.net/ident?i=ZEND_INIT_FCALL_BY_NAME>: {
1484 <http://lxr.php.net/source/Zend/zend_execute.c#1484>                                         zval <http://lxr.php.net/ident?i=zval> *function_name;
1485 <http://lxr.php.net/source/Zend/zend_execute.c#1485>                                         zend_function <http://lxr.php.net/ident?i=zend_function> *function <http://lxr.php.net/ident?i=function>;
1486 <http://lxr.php.net/source/Zend/zend_execute.c#1486>                                         HashTable <http://lxr.php.net/ident?i=HashTable> *active_function_table;
1487 <http://lxr.php.net/source/Zend/zend_execute.c#1487>                                         zval <http://lxr.php.net/ident?i=zval> tmp;
1488 <http://lxr.php.net/source/Zend/zend_execute.c#1488>                                         char *called_function_name=NULL;
                                                    if (zend_hash_find <http://lxr.php.net/ident?i=zend_hash_find>(EG <http://lxr.php.net/ident?i=EG>(class_table), EX <http://lxr.php.net/ident?i=EX>(opline)->op1.u.constant.value <http://lxr.php.net/ident?i=value>.str <http://lxr.php.net/ident?i=str>.val <http://lxr.php.net/ident?i=val>, EX <http://lxr.php.net/ident?i=EX>(opline)->op1.u.constant.value <http://lxr.php.net/ident?i=value>.str <http://lxr.php.net/ident?i=str>.len <http://lxr.php.net/ident?i=len>+1, (void **) &ce)==FAILURE <http://lxr.php.net/ident?i=FAILURE>) { *//* class doesn't exist *//*
1522 <http://lxr.php.net/source/Zend/zend_execute.c#1522>                                                                 zend_error <http://lxr.php.net/ident?i=zend_error>(E_ERROR <http://lxr.php.net/ident?i=E_ERROR>, /"Undefined class name '%s'"/, EX <http://lxr.php.net/ident?i=EX>(opline)->op1.u.constant.value <http://lxr.php.net/ident?i=value>.str <http://lxr.php.net/ident?i=str>.val <http://lxr.php.net/ident?i=val>);
1523 <http://lxr.php.net/source/Zend/zend_execute.c#1523>                                                         }
called_function_name = (char *) EX <http://lxr.php.net/ident?i=EX>(opline)->op1.u.constant.value <http://lxr.php.net/ident?i=value>.str <http://lxr.php.net/ident?i=str>.val <http://lxr.php.net/ident?i=val>;
1524 <http://lxr.php.net/source/Zend/zend_execute.c#1524>                                                         active_function_table = &ce->function_table <http://lxr.php.net/ident?i=function_table>;
1525 <http://lxr.php.net/source/Zend/zend_execute.c#1525>    
                              }
1566 <http://lxr.php.net/source/Zend/zend_execute.c#1566>                                         zval_dtor <http://lxr.php.net/ident?i=zval_dtor>(&tmp);
function.called_function_name = called_function_name;
1567 <http://lxr.php.net/source/Zend/zend_execute.c#1567>                                         EX <http://lxr.php.net/ident?i=EX>(fbc) = function <http://lxr.php.net/ident?i=function>;
1568 <http://lxr.php.net/source/Zend/zend_execute.c#1568> overloa...... zend_execute_API.c 219 <http://lxr.php.net/source/Zend/zend_execute_API.c#219> ZEND_API <http://lxr.php.net/ident?i=ZEND_API> char *get_active_function_name <http://lxr.php.net/ident?i=get_active_function_name>(TSRMLS_D <http://lxr.php.net/ident?i=TSRMLS_D>) 220 <http://lxr.php.net/source/Zend/zend_execute_API.c#220> {
221 <http://lxr.php.net/source/Zend/zend_execute_API.c#221>         switch(EG <http://lxr.php.net/ident?i=EG>(function_state_ptr)->function <http://lxr.php.net/ident?i=function>->type <http://lxr.php.net/ident?i=type>) {
222 <http://lxr.php.net/source/Zend/zend_execute_API.c#222>                 case ZEND_USER_FUNCTION <http://lxr.php.net/ident?i=ZEND_USER_FUNCTION>: {
223 <http://lxr.php.net/source/Zend/zend_execute_API.c#223>                                 char *function_name = ((zend_op_array <http://lxr.php.net/ident?i=zend_op_array> *) EG <http://lxr.php.net/ident?i=EG>(function_state_ptr)->function <http://lxr.php.net/ident?i=function>)->function_name;
224 <http://lxr.php.net/source/Zend/zend_execute_API.c#224>                         225 <http://lxr.php.net/source/Zend/zend_execute_API.c#225>                                 if (function_name) {
226 <http://lxr.php.net/source/Zend/zend_execute_API.c#226>                                         return function_name;
227 <http://lxr.php.net/source/Zend/zend_execute_API.c#227>                                 } else {
228 <http://lxr.php.net/source/Zend/zend_execute_API.c#228>                                         return /"main"/;
229 <http://lxr.php.net/source/Zend/zend_execute_API.c#229>                                 }
230 <http://lxr.php.net/source/Zend/zend_execute_API.c#230>                         }
231 <http://lxr.php.net/source/Zend/zend_execute_API.c#231>                         break;
232 <http://lxr.php.net/source/Zend/zend_execute_API.c#232>                 case ZEND_INTERNAL_FUNCTION <http://lxr.php.net/ident?i=ZEND_INTERNAL_FUNCTION>:
233 <http://lxr.php.net/source/Zend/zend_execute_API.c#233>                         return ((zend_internal_function <http://lxr.php.net/ident?i=zend_internal_function> *) EG <http://lxr.php.net/ident?i=EG>(function_state_ptr)->function <http://lxr.php.net/ident?i=function>)->function_name;
234 <http://lxr.php.net/source/Zend/zend_execute_API.c#234>                         break;
235 <http://lxr.php.net/source/Zend/zend_execute_API.c#235>                 default:
236 <http://lxr.php.net/source/Zend/zend_execute_API.c#236>                         return NULL <http://lxr.php.net/ident?i=NULL>;
237 <http://lxr.php.net/source/Zend/zend_execute_API.c#237>         }
238 <http://lxr.php.net/source/Zend/zend_execute_API.c#238> } 239 <http://lxr.php.net/source/Zend/zend_execute_API.c#239> 219 <http://lxr.php.net/source/Zend/zend_execute_API.c#219> ZEND_API <http://lxr.php.net/ident?i=ZEND_API> char *get_called_function_name <http://lxr.php.net/ident?i=get_active_function_name>(TSRMLS_D <http://lxr.php.net/ident?i=TSRMLS_D>) 220 <http://lxr.php.net/source/Zend/zend_execute_API.c#220> {
221 <http://lxr.php.net/source/Zend/zend_execute_API.c#221>         switch(EG <http://lxr.php.net/ident?i=EG>(function_state_ptr)->function <http://lxr.php.net/ident?i=function>->type <http://lxr.php.net/ident?i=type>) {
222 <http://lxr.php.net/source/Zend/zend_execute_API.c#222>                 case ZEND_USER_FUNCTION <http://lxr.php.net/ident?i=ZEND_USER_FUNCTION>: {
223 <http://lxr.php.net/source/Zend/zend_execute_API.c#223>                                 char *function_name = ((zend_op_array <http://lxr.php.net/ident?i=zend_op_array> *) EG <http://lxr.php.net/ident?i=EG>(function_state_ptr)->function <http://lxr.php.net/ident?i=function>)->called_function_name;
224 <http://lxr.php.net/source/Zend/zend_execute_API.c#224>                         225 <http://lxr.php.net/source/Zend/zend_execute_API.c#225>                                 if (function_name) {
226 <http://lxr.php.net/source/Zend/zend_execute_API.c#226>                                         return function_name;
227 <http://lxr.php.net/source/Zend/zend_execute_API.c#227>                                 } else {
228 <http://lxr.php.net/source/Zend/zend_execute_API.c#228>                                         return /"main"/;
229 <http://lxr.php.net/source/Zend/zend_execute_API.c#229>                                 }
230 <http://lxr.php.net/source/Zend/zend_execute_API.c#230>                         }
231 <http://lxr.php.net/source/Zend/zend_execute_API.c#231>                         break;
232 <http://lxr.php.net/source/Zend/zend_execute_API.c#232>                 case ZEND_INTERNAL_FUNCTION <http://lxr.php.net/ident?i=ZEND_INTERNAL_FUNCTION>:
233 <http://lxr.php.net/source/Zend/zend_execute_API.c#233>                         return ((zend_internal_function <http://lxr.php.net/ident?i=zend_internal_function> *) EG <http://lxr.php.net/ident?i=EG>(function_state_ptr)->function <http://lxr.php.net/ident?i=function>)->function_name;
234 <http://lxr.php.net/source/Zend/zend_execute_API.c#234>                         break;
235 <http://lxr.php.net/source/Zend/zend_execute_API.c#235>                 default:
236 <http://lxr.php.net/source/Zend/zend_execute_API.c#236>                         return NULL <http://lxr.php.net/ident?i=NULL>;
237 <http://lxr.php.net/source/Zend/zend_execute_API.c#237>         }
238 <http://lxr.php.net/source/Zend/zend_execute_API.c#238> } 239 <http://lxr.php.net/source/Zend/zend_execute_API.c#239> zend_language_parser.l <ST_IN_SCRIPTING>"__CALLED_FUNCTION__" {
904 <http://lxr.php.net/source/Zend/zend_language_scanner.l#904>         char *called_function =  get_called_function_name(TSRMLS_C);
905 <http://lxr.php.net/source/Zend/zend_language_scanner.l#905>         906 <http://lxr.php.net/source/Zend/zend_language_scanner.l#906>         if (!called_function) {
907 <http://lxr.php.net/source/Zend/zend_language_scanner.l#907>                 called_function= "";
908 <http://lxr.php.net/source/Zend/zend_language_scanner.l#908>         }
909 <http://lxr.php.net/source/Zend/zend_language_scanner.l#909>         zendlval->value.str.len = strlen(called_function);
910 <http://lxr.php.net/source/Zend/zend_language_scanner.l#910>         zendlval->value.str.val = estrndup(called_function, zendlval->value.str.len);
911 <http://lxr.php.net/source/Zend/zend_language_scanner.l#911>         zendlval->type = IS_STRING;
912 <http://lxr.php.net/source/Zend/zend_language_scanner.l#912>         return T_CFUNCTION;
913 <http://lxr.php.net/source/Zend/zend_language_scanner.l#913> } 126 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#126> %token T_FILE <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#127> %token T_CFUNCTION <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#127> zend_language_parser.y common_scalar:
597 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#597>                 T_LNUMBER                                       { $$ = $1; }
598 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#598>         |       T_DNUMBER                                       { $$ = $1; }
599 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#599>         |       T_CONSTANT_ENCAPSED_STRING      { $$ = $1; }
600 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#600>         |       T_LINE                                          { $$ = $1; }
601 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#601>         |       T_FILE                                          { $$ = $1; }
602 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#602>                 T_CFUNCTION                                        { $$ = $1; }
602 <http://lxr.php.net/source/ZendEngine2/zend_language_parser.y#602> ;

« previous php.dev (#82045) next »