Page 1 of 2
Variable scope
Posted: Wed May 19, 2010 12:57 pm
by larrygingras
How can I make a function that will share (or at least have access to) calling function's scope? I dig a lot of manuals and examples still I see nothing on this.
I think that should be possible. At least there is built-in function "extract" that is able to access and modify calling function's scope...
Re: Variable scope
Posted: Wed May 19, 2010 1:07 pm
by Eran
you can't share scope between functions. The closest you can get is sharing data through the $this scope for functions belonging to the same object. Perhaps if you explained why you need this we could offer alternative ways to go about it
Re: Variable scope
Posted: Wed May 19, 2010 1:17 pm
by larrygingras
1. So how it is possible for built-in functions like "extract" to access calling function's scope? Are built-in functions have wider possibilities?
2. I think about design of good and easy query escaping function. Now I can just put variables in query string (double-quoted) and they are expanded. This is very handy but not secure. What I want is to put variable names (it could be array members as well) to some sort of tags and I want function to parse such string and escape everything that is inside those tags. So this function's code should act as if it would be executed inside calling function.
In C, for example, I can write macro for such purpose...
Re: Variable scope
Posted: Wed May 19, 2010 1:23 pm
by larrygingras
I think I've not made myself very clear.
I mean in my way variables (inside tags) will NOT be expanded by means of PHP, but when function will parse these tags it will expand everything inside and after escape it.So this function should have access to same variables as in scope of calling function.
Re: Variable scope
Posted: Wed May 19, 2010 1:32 pm
by larrygingras
I think I could make like this:
Code: Select all
eval(safe_query("update table set var='%val%'"));
Function safe_query will return PHP code that will be executed in calling function's scope.
This way is closest approach to C macro way. But it looks not so good...
Re: Variable scope
Posted: Wed May 19, 2010 1:34 pm
by AbraCadaver
If you would show some code it would be easier to help you. What you are describing sounds a lot like prepared statements:
http://php.net/manual/en/pdo.prepared-statements.php
But to answer your question, extract() needs an array to extract. And for one function to access vars from another function they would either need to be passed in to the called function or they would need to be global. Consider this:
Code: Select all
function one() {
$a = 1;
$b = 2;
$GLOBALS['vars'] = get_defined_vars();
two();
}
function two() {
extract($GLOBALS['vars']);
echo $a;
echo $b;
}
However I would investigate using a class for this type of functionality.
Re: Variable scope
Posted: Wed May 19, 2010 1:52 pm
by larrygingras
AbraCadaver wrote:But to answer your question, extract() needs an array to extract
Yes, but it is extracting this array into the calling function's scope. But it looks it isn't possible within PHP language itself, right?
As for other things.
I cannot show code as right now it is just design concept.
Prepared statements is not what I want as I want to execute queries with just one call, simple and clear. I prefer code to be as laconic as possible.
I think, get_defined_vars (again - this function CAN read calling scope) is good idea, but I don't want to execute it every time I call query function.
Code: Select all
function safe_query($q,$vars=get_defined_vars())
{
...
}
Will something like this work?
Again, I could use eval but it will make code not so clean...
Re: Variable scope
Posted: Wed May 19, 2010 2:02 pm
by Eran
What is the problem with passing the variables in an array?
Re: Variable scope
Posted: Wed May 19, 2010 2:13 pm
by AbraCadaver
No, I was just illustrating how it works. You really need to do this by either using a class or by passing the vars in. This is just quick of the top of my head:
Code: Select all
function safe_query() {
$args = func_get_args();
$query = array_shift($args);
foreach($args as $key => $val) {
//whatever here
$query = str_replace("%$key%", mysql_real_escape_string($val), $query);
}
return mysql_query($query);
}
$var = $_POST['var'];
safe_query("update table set var='%0%'", $var);
Or you could write your function to take an array:
Code: Select all
$var = $_POST['var'];
safe_query("update table set var='%val%'", array('val'=>$var));
Re: Variable scope
Posted: Wed May 19, 2010 2:19 pm
by larrygingras
Well, imagine I make an insert with about 20 fields or more. That is big and complicated query. So I will put all variable names in my query string (inside my special tags), but I do not want to repeat these variables again in array or something.
This why I not want to use printf-like approach - I not want to count what argument stay in what position. I want it as simple as I write now:
Code: Select all
mysql_query("update `table` set `var`='$_GET[val]' where `id`='$_GET[id]'");
But I want it be secure as well...
Or you could write your function to take an array:
Code: Select all
$var = $_POST['var'];
safe_query("update table set var='%val%'", array('val'=>$var));
Well, this approach I like better than before as at least I don't need to count argument's position. But still this syntax is more complicated and you can imagine how more complicated will become queries with >20 arguments...
Re: Variable scope
Posted: Wed May 19, 2010 2:24 pm
by Eran
How about the following mock syntax:
Code: Select all
update('table',array('var1' => $var1));
insert('table',array('var1' => $var1));
Re: Variable scope
Posted: Wed May 19, 2010 2:42 pm
by larrygingras
Well, good idea. Not think about that before.
Not complete solution, for example complicated "select" with a lot of external arguments is still not covered, but for most common cases this can be good approach...
However, IDEALLY I want what I state before. And still, what about:
Code: Select all
function safe_query($q,$vars=get_defined_vars())
{
...
}
Will this work as I want - make $vars contain scope of calling function?
Well, I think I should just test this myself

Re: Variable scope
Posted: Wed May 19, 2010 2:44 pm
by AbraCadaver
Regardless of how you do it, you're going to have to pass the vars into the function. To simplify you might build an array from the start instead of using single vars. If vars come from get or post then you already have an array. If not, then something like:
Code: Select all
$vars['var'] = 1;
$vars['var2'] = 2;
Or:
Code: Select all
$var = 1;
$var2 = 2;
$vars = compact("var", "var2");
Re: Variable scope
Posted: Wed May 19, 2010 2:46 pm
by larrygingras
Unfortunately, no. It seems that it is not permitted to use function for default argument value: PHP Parse error: syntax error, unexpected '(', expecting ')' in /cd/home/admin/test.php on line 2
Re: Variable scope
Posted: Wed May 19, 2010 2:49 pm
by AbraCadaver
larrygingras wrote:Unfortunately, no. It seems that it is not permitted to use function for default argument value: PHP Parse error: syntax error, unexpected '(', expecting ')' in /cd/home/admin/test.php on line 2
You can do this, however I would recommend one of the other solutions:
Code: Select all
safe_query('query', get_defined_vars());
If the variables are global, then you can just use the $GLOBALS array in the safe_query() function.