In PHP, how can a function body reference variables in its dynamic parent?
In PHP, how can a function body reference variables in its dynamic parent?
In PHP, one can write
$a="$b$c";
This concatenates the assumed strings in $b and $c into $a elegantly (that is, using minimal yet clear syntax).
Now I want to move this statement into a function. The problem is that $b and $c are naturally interpreted as being local to this function, not its caller (which can be the global code or a function). Even if the caller defines $b and $c, this new function cannot see those definitions.
I want to do something clever that requires the statement to work the same (except for the location of $a) even though it has been moved into a function.
Furthermore, I want this to be efficient. No use of extract() or debug_backtrace(). Just want to use the caller's local scope. I don't mind if I use Zend to get the caller's symbol table, or any other hack, so long as it's efficient.
Don't worry, I'm not going to use this as general programming practice (ugh), just for one specific and wonderful purpose.
Generally, a function can access variables in its calling scope when the caller passes those variables in as arguments. :) To reference variables in the caller’s scope without passing them in brings many of the same problems with global variables.
– Ashton Wiersdorf
Jun 30 at 23:25
2 Answers
2
I know you don't want extract, but could this help?
<?php
function foo()
{
$b = 'Butter';
$c = 'Cup';
$v = get_defined_vars();
echo bar($v);
}
function bar($v)
{
extract($v);
return $b . $c;
}
foo();
Output:
ButterCup
There is no native PHP functionality for violating function scope in this way, other than backtraces included in debugging functions and exceptions.
I'd suggest looking at the C code for debug_backtrace() and seeing if you can write an extension that implements the bit of it you need (walking up the stack one step to find the parent symbol table) but which performs better than the existing function (I've no idea if that's possible, I don't know where the overhead comes from).
However, I would also recommend thinking really really hard about what problem you're actually trying to solve, and why it's led you to want to break function isolation in such an unusual way. Maybe there's a completely different solution.
For instance, if what you want is a kind of macro, rather than a function, you could write a pre-processor (or find one that's already been written) so that the code is literally pasted into place, and you don't need to hack the symbol table.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
What you're suggesting really violates scopes and is generally not a good idea. Also not sure if it's actually possible.
– apokryfos
Jun 30 at 21:46