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> ;
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php