views:

34

answers:

2

I know that directly setting a variable in the scope of caller is probably not a good idea. However, the PHP extract() function does exactly that! I would like to write my over version of extract() but cannot figure out how to actually go about setting the variables in the caller. Any ideas? The closest I have come is modifying the caller's args using debug_backtrace(), but this is not exactly the same thing...

+3  A: 

You can't modify local variables in a parent scope - the method which extract() uses is not exposed by PHP.

Also, what you get back from debug_stacktrace() isn't magically linked to the real stack. You can't modify it and hope your modifications are live!

Paul Dixon
Thanks, that's what I suspected to be honest.
John J. Camilleri
+1  A: 

You could only do it in a PHP extension. If you call an internal PHP function, it will not run in a new PHP scope (i.e., no new symbol table will be created). Therefore, you can modify the "parent scope" by changing the global EG(active_symbol_table).

Basically, the core of the function would do something like extract does, the core of which is:

if (!EG(active_symbol_table)) {
    zend_rebuild_symbol_table(TSRMLS_C);
}
//loop through the given array
ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table),
    Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, data, 1, 0);

There are, however, a few nuances. See the implementation of extract, but keep in mind a function that did what you wanted wouldn't need to be as complex; most of the code in extract is there to deal with the several options it accepts.

Artefacto
+1 for the detail :)
Paul Dixon